Fix Docker volume leak on SIGTERM, SIGHUP, and concurrent cleanup#1787
Merged
firecow merged 4 commits intofirecow:masterfrom Mar 2, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
1 issue found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/index.ts">
<violation number="1" location="src/index.ts:21">
P2: cleanupAndExit caches a rejected promise and never calls process.exit when cleanupJobResources fails, so a failed cleanup can leave the process running and future signals become no-ops.</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Add one-off context when rerunning by tagging
@cubic-dev-aiwith guidance or docs links (includingllms.txt) - Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
If cleanupJobResources throws, .then() never fires, the rejected promise gets cached, and all future signals become no-ops — leaving the process hanging. Using .finally() ensures process.exit() always runs regardless of whether cleanup succeeds or fails. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
firecow
reviewed
Mar 2, 2026
Owner
firecow
left a comment
There was a problem hiding this comment.
Nice fix — the core change is solid and well-scoped. A few minor suggestions below.
(Correction from earlier: point 3 about clearTimeout only running on the first call was wrong — it's before the re-entry guard and runs every time. Point 5 about a cleanup timeout is out of scope for this PR.)
- Remove space before ( in cleanupAndExit declaration - Add comment explaining first-caller-wins exit code behavior - Guard SIGUSR2 handler to skip cleanup if termination cleanup is in flight
The @stylistic/space-before-function-paren rule requires it.
firecow
approved these changes
Mar 2, 2026
Owner
firecow
left a comment
There was a problem hiding this comment.
Tested locally — all CI checks pass, both manual signal tests (SIGINT and SIGHUP) confirmed no orphaned Docker volumes.
tmeijn
pushed a commit
to tmeijn/dotfiles
that referenced
this pull request
Mar 24, 2026
This MR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---|---|---| | [npm:gitlab-ci-local](https://github.com/firecow/gitlab-ci-local) | `4.67.2` → `4.70.0` |  |  |  |  | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>firecow/gitlab-ci-local (npm:gitlab-ci-local)</summary> ### [`v4.70.0`](https://github.com/firecow/gitlab-ci-local/releases/tag/4.70.0) [Compare Source](firecow/gitlab-ci-local@4.69.0...4.70.0) #### What's Changed - Add `GCL_VARIABLE_<name>` env var support, replace `yargs .env("GCL")` by [@​firecow](https://github.com/firecow) in [#​1805](firecow/gitlab-ci-local#1805) - fix: prefix rsync paths with ./ by [@​ednxzu](https://github.com/ednxzu) in [#​1801](firecow/gitlab-ci-local#1801) - chore(deps): update all non-major by [@​renovate](https://github.com/renovate)\[bot] in [#​1802](firecow/gitlab-ci-local#1802) - chore(deps): lock file maintenance by [@​renovate](https://github.com/renovate)\[bot] in [#​1798](firecow/gitlab-ci-local#1798) #### New Contributors - [@​ednxzu](https://github.com/ednxzu) made their first contribution in [#​1801](firecow/gitlab-ci-local#1801) **Full Changelog**: <firecow/gitlab-ci-local@4.69.0...4.70.0> ### [`v4.69.0`](https://github.com/firecow/gitlab-ci-local/releases/tag/4.69.0) [Compare Source](firecow/gitlab-ci-local@4.68.1...4.69.0) #### What's Changed - fix: disable .env autoload in compiled binaries by [@​firecow](https://github.com/firecow) in [#​1799](firecow/gitlab-ci-local#1799) - Add `--wait-for-services-timeout` option to CLI by [@​dernilz](https://github.com/dernilz) in [#​1796](firecow/gitlab-ci-local#1796) - ci: add Node.js and Bun version matrix to smoke test by [@​firecow](https://github.com/firecow) in [#​1797](firecow/gitlab-ci-local#1797) - chore(deps): update github/codeql-action action to v4.32.6 by [@​renovate](https://github.com/renovate)\[bot] in [#​1793](firecow/gitlab-ci-local#1793) **Full Changelog**: <firecow/gitlab-ci-local@4.68.1...4.68.2> ### [`v4.68.1`](https://github.com/firecow/gitlab-ci-local/releases/tag/4.68.1) [Compare Source](firecow/gitlab-ci-local@4.68.0...4.68.1) #### What's Changed - chore(deps): update all non-major by [@​renovate](https://github.com/renovate)\[bot] in [#​1792](firecow/gitlab-ci-local#1792) - fix: disable Bun automatic .env loading by [@​firecow](https://github.com/firecow) in [#​1794](firecow/gitlab-ci-local#1794) **Full Changelog**: <firecow/gitlab-ci-local@4.68.0...4.68.1> ### [`v4.68.0`](https://github.com/firecow/gitlab-ci-local/releases/tag/4.68.0) [Compare Source](firecow/gitlab-ci-local@4.67.2...4.68.0) #### What's Changed - chore(deps): lock file maintenance by [@​renovate](https://github.com/renovate)\[bot] in [#​1785](firecow/gitlab-ci-local#1785) - fix: docker cp fails on read-only directories by [@​firecow](https://github.com/firecow) in [#​1773](firecow/gitlab-ci-local#1773) - make services run as container user instead of root by [@​peterbbeu](https://github.com/peterbbeu) in [#​1781](firecow/gitlab-ci-local#1781) - chore(deps): update github/codeql-action action to v4.32.5 by [@​renovate](https://github.com/renovate)\[bot] in [#​1786](firecow/gitlab-ci-local#1786) - Migrate test runner from bun:test to vitest by [@​firecow](https://github.com/firecow) in [#​1784](firecow/gitlab-ci-local#1784) - Route parser warnings through WriteStreams instead of console.log by [@​firecow](https://github.com/firecow) in [#​1788](firecow/gitlab-ci-local#1788) - Use test.concurrent for independent integration tests by [@​firecow](https://github.com/firecow) in [#​1769](firecow/gitlab-ci-local#1769) - Fix Docker volume leak on SIGTERM, SIGHUP, and concurrent cleanup by [@​cegofrhs](https://github.com/cegofrhs) in [#​1787](firecow/gitlab-ci-local#1787) - Add TypeScript type checking to CI by [@​firecow](https://github.com/firecow) in [#​1789](firecow/gitlab-ci-local#1789) - Convert remaining tests to concurrent and tune vitest by [@​firecow](https://github.com/firecow) in [#​1790](firecow/gitlab-ci-local#1790) - fix: flaky log-padding test assertions by [@​firecow](https://github.com/firecow) in [#​1791](firecow/gitlab-ci-local#1791) #### New Contributors - [@​cegofrhs](https://github.com/cegofrhs) made their first contribution in [#​1787](firecow/gitlab-ci-local#1787) **Full Changelog**: <firecow/gitlab-ci-local@4.67.2...4.68.0> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My42MS43IiwidXBkYXRlZEluVmVyIjoiNDMuODYuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6Om1pbm9yIl19-->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
kill <pid>(SIGTERM) previously terminated the process without running cleanup, leaving orphanedgcl-*-buildandgcl-*-tmpDocker volumescleanupAndExit()— eliminates the race condition where Ctrl+C triggered cleanup from both the SIGINT handler and the error catch block concurrently, withprocess.exit()from the winner killing the loser mid-flight beforedocker volume rmJob.cleanupResources()— concurrent callers now share the same cleanup promise instead of racing ondocker rmvsdocker volume rmorderingTest plan
tsc --noEmitpasses (no new errors insrc/)bun run lintpassesbun run buildpassesbun test tests/test-cases/artifacts-docker/passes (exercises Docker volume creation/cleanup)bun test tests/test-cases/list-case/passesbun test tests/test-cases/preview/passesgcl-*volumes remaingcl-*volumes remainSummary by cubic
Stops leaking Docker volumes by running a single, guarded cleanup on SIGINT, SIGTERM, SIGHUP, and error exits. Prevents orphaned gcl-* volumes and avoids hangs from concurrent cleanup or cleanup failures.
Written for commit b4a527f. Summary will update on new commits.