fix: isolate bind_workdir workspace per task to prevent concurrent job conflicts

When multiple jobs from the same repo run concurrently with bind_workdir
enabled, they shared the same host directory. Cleanup of one job would
delete the workspace of another, causing container breakout errors.

Use per-task workspace directories (/workspace/<task_id>/<owner>/<repo>)
to isolate concurrent jobs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
silverwind 2026-03-02 12:47:52 +01:00
parent 1b31155930
commit 97508ed1a8
No known key found for this signature in database
GPG Key ID: 2E62B41C93869443
1 changed files with 12 additions and 3 deletions

View File

@ -197,10 +197,17 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
maxLifetime = time.Until(deadline)
}
workdirParent := strings.TrimLeft(r.cfg.Container.WorkdirParent, "/")
if r.cfg.Container.BindWorkdir {
// Prepend the task ID to isolate concurrent jobs from the same repo.
workdirParent = fmt.Sprintf("%s/%d", workdirParent, task.Id)
}
workdir := filepath.FromSlash(fmt.Sprintf("/%s/%s", workdirParent, preset.Repository))
runnerConfig := &runner.Config{
// On Linux, Workdir will be like "/<parent_directory>/<owner>/<repo>"
// On Windows, Workdir will be like "\<parent_directory>\<owner>\<repo>"
Workdir: filepath.FromSlash(fmt.Sprintf("/%s/%s", strings.TrimLeft(r.cfg.Container.WorkdirParent, "/"), preset.Repository)),
Workdir: workdir,
BindWorkdir: r.cfg.Container.BindWorkdir,
ActionCacheDir: filepath.FromSlash(r.cfg.Host.WorkdirParent),
@ -248,8 +255,10 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
reporter.SetOutputs(job.Outputs)
if r.cfg.Container.BindWorkdir {
if err := os.RemoveAll(runnerConfig.Workdir); err != nil {
log.Warnf("failed to clean up workspace %s: %v", runnerConfig.Workdir, err)
// Remove the entire task-specific directory (e.g. /workspace/<task_id>).
taskDir := filepath.FromSlash("/" + workdirParent)
if err := os.RemoveAll(taskDir); err != nil {
log.Warnf("failed to clean up workspace %s: %v", taskDir, err)
}
}