Skip to content

fix(render): cancel on SIGINT/SIGTERM so deferred cleanup runs - #406

Open
jcogilvie wants to merge 2 commits into
crossplane:mainfrom
jcogilvie:jco/render-interrupt-cleanup
Open

jcogilvie wants to merge 2 commits into
crossplane:mainfrom
jcogilvie:jco/render-interrupt-cleanup

Conversation

@jcogilvie

@jcogilvie jcogilvie commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Description of your changes

Ctrl+C/SIGTERM mid-render leaked the Function containers, the render container and the network: nothing turned signals into context cancellation, and the spinner's handler called os.Exit, skipping defers.

  • main binds a signal.NotifyContext context into kong; render xr/op use it, so an interrupt cancels work and deferred cleanup runs. Exit code is 130.
  • The spinner no longer handles signals; SpinnerPrinter's wrappers already stop it when the wrapped func returns.
  • A second signal exits immediately (130). If stderr is a TTY it first restores the cursor and bracketed-paste mode, which a killed spinner otherwise leaves broken.
  • docker.RunContainer closes the attach stream on ctx cancellation. Without this, cleanup waited for the render container to exit: ~115s with a hung Function, now ~0.3s.

Verified manually with a hanging Function: exit 130, no containers or network left behind. No automated test for the signal wiring (it needs a subprocess harness).

Note: other commands don't use the bound context yet, so a first Ctrl+C lets them finish before exiting 130 (previously immediate). Wiring them up can be a follow-up.

Fixes #400

I have:

  • Read and followed Crossplane's contribution process.
  • Run ./nix.sh flake check to ensure this PR is ready for review.
  • Added or updated unit tests. I only updated existing tests for the signature change (see above).
  • Linked a PR or a docs tracking issue to document this change.
  • Added backport release-x.y labels to auto-backport this PR.

Need help with this checklist? See the cheat sheet.

🤖 Generated with Claude Code

jcogilvie and others added 2 commits October 13, 2026 14:05
Interrupting `crossplane render` leaked every Function container, the
render engine container and the temporary network. All of that cleanup
is defer-based, but nothing turned SIGINT/SIGTERM into context
cancellation, and the spinner's signal handler called os.Exit(130),
which skips defers.

Derive a signal-aware context in main with signal.NotifyContext and
bind it into kong; render xr and render op now base their timeout
context on it. The spinner no longer handles signals; the SpinnerPrinter
wrappers stop it when the wrapped func returns. An interrupted run exits
130.

A second signal exits 130 immediately without waiting for cleanup. A
spinner may still be running then, and being killed by the default
handler left the cursor hidden and bracketed paste enabled, so main
first restores both when stderr is a terminal.

Fixes crossplane#400

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com>
RunContainer blocked in stdcopy.StdCopy, which doesn't observe ctx, so
an interrupted render waited until the render container exited by
itself (~115s with a hung Function) before cleanup could run. Close the
attach connection when ctx is done, and report ctx.Err() rather than
the resulting read error.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com>
@jcogilvie
jcogilvie force-pushed the jco/render-interrupt-cleanup branch from 818e267 to e83f8cf Compare October 13, 2026 18:25
@jcogilvie
jcogilvie marked this pull request as ready for review October 13, 2026 18:33
@jcogilvie
jcogilvie requested review from a team and tampakrap as code owners October 13, 2026 18:33
@jcogilvie
jcogilvie requested review from negz and removed request for a team October 13, 2026 18:33
@coderabbitai

coderabbitai Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 32 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: crossplane/cli/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9e501db5-41a0-4081-815a-f3a834a39003
📥 Commits

Reviewing files that changed from the base of the PR and between 833d6e0 and e83f8cf.

⛔ Files ignored due to path filters (1)
  • go.mod is excluded by none and included by none
📒 Files selected for processing (7)
  • cmd/crossplane/main.go
  • cmd/crossplane/render/op/cmd.go
  • cmd/crossplane/render/op/cmd_test.go
  • cmd/crossplane/render/xr/cmd.go
  • cmd/crossplane/render/xr/cmd_test.go
  • internal/docker/docker.go
  • internal/terminal/spinner.go
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

render: interrupting with Ctrl+C (SIGINT/SIGTERM) leaks Function containers, the render container, and the network

1 participant