mirror of
https://gitea.com/gitea/act_runner
synced 2026-11-14 13:29:16 +01:00
A job running as root leaves root-owned files in the bind-mounted workspace. A non-root runner on Linux cannot remove them, so workspaces pile up with only a warning. Such a runner now empties the workspace as root from inside the job container, right before removing the container. Root runners and Docker Desktop already remove these files themselves and skip this. The workspace is only emptied when it is exactly the runner's own mountpoint with no mount below it. Otherwise, or when the command fails, the existing removal and warning apply. Jobs of a reusable workflow share the workspace, so they are not covered and still end in the existing warning. Fixes: https://gitea.com/gitea/runner/issues/879 Co-authored-by: silverwind <2021+silverwind@noreply.gitea.com> Co-authored-by: silverwind <me@silverwind.io> Reviewed-on: https://gitea.com/gitea/runner/pulls/1399 Reviewed-by: silverwind <2021+silverwind@noreply.gitea.com> Co-authored-by: bircni <bircni@icloud.com>
100 lines
3.1 KiB
Go
100 lines
3.1 KiB
Go
// Copyright 2022 The Gitea Authors. All rights reserved.
|
|
// Copyright 2022 The nektos/act Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package runner
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
"gitea.com/gitea/runner/act/common"
|
|
"gitea.com/gitea/runner/act/container"
|
|
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
var noopExecutor = func(context.Context) error { return nil }
|
|
|
|
type linuxEnvironment struct {
|
|
container.LinuxContainerEnvironmentExtensions
|
|
}
|
|
|
|
func (linuxEnvironment) GetRunnerContext(context.Context) map[string]any {
|
|
return map[string]any{"os": "Linux", "arch": "X64", "temp": "/tmp", "tool_cache": container.DefaultToolCache}
|
|
}
|
|
|
|
type containerMock struct {
|
|
mock.Mock
|
|
container.Container
|
|
linuxEnvironment
|
|
}
|
|
|
|
func (cm *containerMock) Create(capAdd, capDrop []string) common.Executor {
|
|
return cm.Called(capAdd, capDrop).Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) Pull(forcePull bool) common.Executor {
|
|
return cm.Called(forcePull).Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) Start(attach bool) common.Executor {
|
|
return cm.Called(attach).Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) Remove() common.Executor {
|
|
return cm.Called().Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) Close() common.Executor {
|
|
return cm.Called().Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) UpdateFromEnv(srcPath string, env *map[string]string) common.Executor {
|
|
return cm.Called(srcPath, env).Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) Copy(destPath string, files ...*container.FileEntry) common.Executor {
|
|
return cm.Called(destPath, files).Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) CopyDir(destPath, srcPath string, useGitIgnore, skipGitDir bool) common.Executor {
|
|
return cm.Called(destPath, srcPath, useGitIgnore, skipGitDir).Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) Exec(command []string, env map[string]string, user, workdir string) common.Executor {
|
|
return cm.Called(command, env, user, workdir).Get(0).(func(context.Context) error)
|
|
}
|
|
|
|
func (cm *containerMock) ExecOutput(ctx context.Context, command []string) (io.ReadCloser, error) {
|
|
args := cm.Called(ctx, command)
|
|
output, _ := args.Get(0).(io.ReadCloser)
|
|
return output, args.Error(1)
|
|
}
|
|
|
|
func (cm *containerMock) GetContainerArchive(ctx context.Context, srcPath string) (io.ReadCloser, error) {
|
|
args := cm.Called(ctx, srcPath)
|
|
err, _ := args.Get(1).(error)
|
|
return args.Get(0).(io.ReadCloser), err
|
|
}
|
|
|
|
func (cm *containerMock) DumpLogs(ctx context.Context) error {
|
|
return cm.Called(ctx).Error(0)
|
|
}
|
|
|
|
func (cm *containerMock) Inspect(ctx context.Context) (*container.Info, error) {
|
|
args := cm.Called(ctx)
|
|
info, _ := args.Get(0).(*container.Info)
|
|
err, _ := args.Get(1).(error)
|
|
return info, err
|
|
}
|
|
|
|
func (cm *containerMock) CopyTarStream(ctx context.Context, destPath string, write func(*container.TarWriter) error) error {
|
|
return cm.Called(ctx, destPath, write).Error(0)
|
|
}
|
|
|
|
func (cm *containerMock) ReplaceLogWriter(stdout, stderr io.Writer) (io.Writer, io.Writer) {
|
|
args := cm.Called(stdout, stderr)
|
|
return args.Get(0).(io.Writer), args.Get(1).(io.Writer)
|
|
}
|