From f59df227d838470b8e587b8fd69e0f5da249c7f5 Mon Sep 17 00:00:00 2001 From: Mateusz Morusiewicz <11313015+Ruteri@users.noreply.github.com> Date: Tue, 10 Feb 2026 04:37:02 +0000 Subject: [PATCH 1/2] Adjusts force shutdown --- playground/local_runner.go | 41 +++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/playground/local_runner.go b/playground/local_runner.go index da7300f3..187ce0e6 100644 --- a/playground/local_runner.go +++ b/playground/local_runner.go @@ -283,18 +283,6 @@ func (d *LocalRunner) sendExitError(err error) { } func (d *LocalRunner) Stop(keepResources bool) error { - forceKillCtx, cancel := context.WithCancel(context.Background()) - defer cancel() - // Keep an eye on the force kill requests. - go func(ctx context.Context) { - select { - case <-ctx.Done(): - return - case <-mainctx.GetForceKillCtx().Done(): - d.stopAllProcessesWithSignal(os.Kill) - ForceKillSession(d.manifest.ID, keepResources) - } - }(forceKillCtx) // Kill all the processes ran by playground on the host. // Possible to make a more graceful exit with os.Interrupt here // but preferring a quick exit for now. @@ -341,7 +329,7 @@ func StopSession(id string, keepResources bool) error { } else { args = append(args, "down", "-v") // removes containers and volumes } - cmd := exec.CommandContext(context.Background(), "docker", args...) + cmd := exec.Command("docker", args...) // Isolate terminal signals from the child process and avoid weird force-kill cases // and leftovers. cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} @@ -356,11 +344,16 @@ func StopSession(id string, keepResources bool) error { return nil } -// ForceKillSession stops all containers for a session with a short grace period (SIGTERM, wait, SIGKILL) +// ForceKillSession immediately stops all containers for a session using SIGKILL with a grace period timeout func ForceKillSession(id string, keepResources bool) { cmd := exec.Command("sh", "-c", - fmt.Sprintf("docker ps -q --filter label=playground.session=%s | xargs -r docker stop -s SIGKILL", id)) - _ = cmd.Run() + fmt.Sprintf("docker ps -q --filter label=playground.session=%s | xargs -r docker stop -t %d -s SIGKILL", id, stopGracePeriodSecs)) + var outBuf bytes.Buffer + cmd.Stdout = &outBuf + cmd.Stderr = &outBuf + if err := cmd.Run(); err != nil { + slog.Warn("Failed to force kill containers", "session", id, "error", err, "output", outBuf.String()) + } } func GetLocalSessions() ([]string, error) { @@ -1176,6 +1169,22 @@ func (d *LocalRunner) pullNotAvailableImages(ctx context.Context) error { } func (d *LocalRunner) Run(ctx context.Context) error { + // Start a force kill handler that runs throughout the entire lifecycle + go func() { + <-mainctx.GetForceKillCtx().Done() + slog.Warn("Force kill triggered, terminating all processes and containers immediately") + + // Kill all host processes + d.stopAllProcessesWithSignal(os.Kill) + + // Force kill all containers directly + ForceKillSession(d.manifest.ID, false) + + // Give a moment for cleanup to complete, then force exit + time.Sleep(2 * time.Second) + os.Exit(130) + }() + go d.trackContainerStatusAndLogs() yamlData, err := d.generateDockerCompose() From 0048cada5d203fd0561c0ee58607f33d40b2fcdc Mon Sep 17 00:00:00 2001 From: Mateusz Morusiewicz <11313015+Ruteri@users.noreply.github.com> Date: Tue, 24 Feb 2026 13:59:14 +0000 Subject: [PATCH 2/2] Fix comment --- playground/local_runner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playground/local_runner.go b/playground/local_runner.go index 187ce0e6..b8272faf 100644 --- a/playground/local_runner.go +++ b/playground/local_runner.go @@ -344,7 +344,7 @@ func StopSession(id string, keepResources bool) error { return nil } -// ForceKillSession immediately stops all containers for a session using SIGKILL with a grace period timeout +// ForceKillSession stops all containers for a session using SIGKILL with a grace period timeout func ForceKillSession(id string, keepResources bool) { cmd := exec.Command("sh", "-c", fmt.Sprintf("docker ps -q --filter label=playground.session=%s | xargs -r docker stop -t %d -s SIGKILL", id, stopGracePeriodSecs))