From b93d9ba1ffe08aba60e3b5654c822416e89562cd Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 25 Jul 2026 01:04:23 +0000 Subject: [PATCH] cmd/containerboot: return context error when canceled during tailscale up/set TestContainerBoot/kube_shutdown_during_state_write flaked with exit code 1 instead of 0 when SIGTERM arrived while "tailscale up" was still running. Two problems combined: tailscaleUp and tailscaleSet wrapped errors with %v, flattening the error chain, so main's errors.Is(err, context.Canceled) check could not recognize a graceful shutdown. Even with %w, cmd.Run under a canceled context usually reports the death of the killed subprocess ("signal: killed") rather than the context error that caused it, since Wait prefers the process error. Check ctx.Err() explicitly and return it (wrapped with %w) so that a shutdown-driven cancellation is recognized wherever it lands relative to the subprocess lifetime. Before: the exit-code failure reproduced 4 times in 808 stress runs under CPU starvation. After: 0 in 1195 runs. Fixes #19380 Change-Id: Ie15ca722d2d5ac2a3f79b2d0ab01fb71d4b9220d Signed-off-by: Brad Fitzpatrick --- cmd/containerboot/tailscaled.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/cmd/containerboot/tailscaled.go b/cmd/containerboot/tailscaled.go index 6f4ed77e7..379dd3eeb 100644 --- a/cmd/containerboot/tailscaled.go +++ b/cmd/containerboot/tailscaled.go @@ -150,7 +150,15 @@ func tailscaleUp(ctx context.Context, cfg *settings) error { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { - return fmt.Errorf("tailscale up failed: %v", err) + if ctxErr := ctx.Err(); ctxErr != nil { + // A canceled context kills the command, and cmd.Run can + // report the subprocess's death ("signal: killed") rather + // than the context error that caused it. Return the + // context error so that callers (and ultimately main) can + // recognize a graceful shutdown with errors.Is. + return fmt.Errorf("tailscale up failed: %w", ctxErr) + } + return fmt.Errorf("tailscale up failed: %w", err) } return nil } @@ -180,7 +188,11 @@ func tailscaleSet(ctx context.Context, cfg *settings) error { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { - return fmt.Errorf("tailscale set failed: %v", err) + if ctxErr := ctx.Err(); ctxErr != nil { + // See the equivalent check in tailscaleUp. + return fmt.Errorf("tailscale set failed: %w", ctxErr) + } + return fmt.Errorf("tailscale set failed: %w", err) } return nil }