Skip to content

fix: ensure container removal on teardown even if bash hangs or dies#2887

Merged
henryiii merged 1 commit into
pypa:mainfrom
henryiii:fix-oci-exit-cleanup
Jun 5, 2026
Merged

fix: ensure container removal on teardown even if bash hangs or dies#2887
henryiii merged 1 commit into
pypa:mainfrom
henryiii:fix-oci-exit-cleanup

Conversation

@henryiii
Copy link
Copy Markdown
Contributor

@henryiii henryiii commented Jun 2, 2026

This is a fix for item 4 in #2885. First pass tried to introduce a double nested try, I reduced it to a single try.

🤖 AI text below 🤖

OCIContainer.__enter__ was hardened in #2879 to always clean up on
failure, but __exit__ was left unguarded. If the container/bash had
already died, bash_stdin.write("exit 0") raises BrokenPipeError; if
bash refuses to exit, process.wait(timeout=30) raises TimeoutExpired.
Either propagated out of __exit__ before _remove_container() ran,
leaking the container (and, on timeout, the start process too).

Wrap the teardown so a broken pipe or timeout instead forces the process
down (kill + wait) and always falls through to container removal, while
still respecting CIBW_DEBUG_KEEP_CONTAINER. Pipe closes are now also
guarded so a flush-on-close against a dead pipe can't mask cleanup.

Add non-docker unit tests for the clean-exit, already-dead-bash, and
shutdown-timeout paths.

Assisted-by: ClaudeCode:claude-opus-4.8

`OCIContainer.__enter__` was hardened in pypa#2879 to always clean up on
failure, but `__exit__` was left unguarded. If the container/bash had
already died, `bash_stdin.write("exit 0")` raises `BrokenPipeError`; if
bash refuses to exit, `process.wait(timeout=30)` raises `TimeoutExpired`.
Either propagated out of `__exit__` before `_remove_container()` ran,
leaking the container (and, on timeout, the `start` process too).

Wrap the teardown so a broken pipe or timeout instead forces the process
down (kill + wait) and always falls through to container removal, while
still respecting CIBW_DEBUG_KEEP_CONTAINER. Pipe closes are now also
guarded so a flush-on-close against a dead pipe can't mask cleanup.

Add non-docker unit tests for the clean-exit, already-dead-bash, and
shutdown-timeout paths.

Assisted-by: ClaudeCode:claude-opus-4.8
Copy link
Copy Markdown
Member

@agriyakhetarpal agriyakhetarpal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel this change is narrowly scoped, and since it doesn't change any other behaviour on successes, I am +1 for this. I can't think of any problems with it. LGTM!

@henryiii henryiii merged commit 2988814 into pypa:main Jun 5, 2026
45 checks passed
@henryiii henryiii deleted the fix-oci-exit-cleanup branch June 5, 2026 02:36
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.

2 participants