Repository navigation
fix(postgres): garbage-collect init-job after completion (#3055) - #3069
Conversation
The post-install/post-upgrade init Job is a one-shot reconciler of users/databases/roles. Its hook-delete-policy was `before-hook-creation` only, which never fires on uninstall, so the completed Job and its Pod lingered in the tenant namespace forever after the Postgres CR was deleted (#3055). Add `ttlSecondsAfterFinished: 120` so the Kubernetes TTL controller GCs the Job and its Pod ~2 minutes after completion, regardless of the Helm hook lifecycle. This deliberately avoids touching the hook-timeout semantics that the bootstrap.recovery path depends on. Add a helm-unittest suite locking in the TTL and the bootstrap-skip behaviour to prevent regression. Fixes #3055 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: Алексей Артамонов <[email protected]>
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a resource leak where completed init Jobs and Pods remained in the tenant namespace indefinitely after a Postgres app CR was deleted. By implementing a TTL on the Job, the system now automatically garbage-collects these resources after a short duration, improving cluster hygiene without disrupting existing Helm hook lifecycle requirements. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe Postgres init Job now sets a 3600-second completion TTL. A new test suite renders the template, checks the TTL value, and verifies that enabling bootstrap skips the Job entirely. ChangesPostgres init-job cleanup
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Code Review
This pull request adds a 'ttlSecondsAfterFinished' configuration set to 120 seconds for the Postgres 'init-job' template to ensure it is garbage-collected after completion, and introduces a unit test suite to verify this behavior. The reviewer recommends increasing this TTL to 3600 seconds (1 hour) to allow sufficient time for troubleshooting failed jobs before they are cleaned up, which requires corresponding updates to the test assertions and comments.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| # One-shot reconciler Job: once it has applied users/databases/roles it is no | ||
| # longer needed. Let the Kubernetes TTL controller garbage-collect the Job and | ||
| # its Pod ~2 minutes after completion so it does not linger after the release | ||
| # is deleted (cozystack/cozystack#3055). This does not touch the Helm hook | ||
| # lifecycle the bootstrap.recovery path relies on. | ||
| ttlSecondsAfterFinished: 120 |
There was a problem hiding this comment.
While setting a TTL for the completed init Job is a great way to prevent resource leaks, a 120-second (2-minute) TTL might be too short for troubleshooting if the Job fails. Since ttlSecondsAfterFinished cleans up both successful and failed Jobs, a failure during database initialization would leave operators with a very narrow window to inspect the logs of the failed Pod. Increasing this to 3600 seconds (1 hour) provides a much safer buffer for production troubleshooting while still ensuring the resources are eventually garbage-collected.
# One-shot reconciler Job: once it has applied users/databases/roles it is no
# longer needed. Let the Kubernetes TTL controller garbage-collect the Job and
# its Pod ~1 hour after completion so it does not linger after the release
# is deleted (cozystack/cozystack#3055). This does not touch the Helm hook
# lifecycle the bootstrap.recovery path relies on.
ttlSecondsAfterFinished: 3600| # Locks in cozystack/cozystack#3055: the post-install/post-upgrade init Job | ||
| # is a one-shot reconciler of users/databases/roles. Without a TTL it lingers | ||
| # in the namespace forever after the Postgres CR is deleted (its hook-delete-policy | ||
| # is `before-hook-creation` only, which never fires on uninstall). A native | ||
| # ttlSecondsAfterFinished lets the Kubernetes TTL controller GC the Job and its | ||
| # Pod ~2 minutes after it completes, regardless of Helm hook lifecycle — without | ||
| # touching the hook-timeout semantics the recovery flow depends on. |
There was a problem hiding this comment.
Update the comment in the test file to reflect the increased TTL of 1 hour instead of 2 minutes.
# Locks in cozystack/cozystack#3055: the post-install/post-upgrade init Job
# is a one-shot reconciler of users/databases/roles. Without a TTL it lingers
# in the namespace forever after the Postgres CR is deleted (its hook-delete-policy
# is 'before-hook-creation' only, which never fires on uninstall). A native
# ttlSecondsAfterFinished lets the Kubernetes TTL controller GC the Job and its
# Pod ~1 hour after it completes, regardless of Helm hook lifecycle — without
# touching the hook-timeout semantics the recovery flow depends on.| - equal: | ||
| path: spec.ttlSecondsAfterFinished | ||
| value: 120 |
Drop the explanatory comment added alongside ttlSecondsAfterFinished; the rationale lives in the PR/commit history. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: Алексей Артамонов <[email protected]>
Address review feedback on #3069: - ttlSecondsAfterFinished 120 -> 3600 so a failed init Job leaves a 1h debugging window before the TTL controller collects it (the TTL also reaps failed Jobs, not just successful ones). - Load templates/init-script.yaml in the unittest suite: the Job's checksum/config annotation includes that template, so rendering init-job.yaml in isolation failed in CI. Select the Job via documentSelector and assert the 3600 TTL. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: Алексей Артамонов <[email protected]>
Signed-off-by: Алексей Артамонов <[email protected]>
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
LGTM — adds ttlSecondsAfterFinished: 3600 so the Kubernetes TTL-after-finished controller garbage-collects the one-shot init Job (and its Pod) after completion, independent of the Helm hook lifecycle that never fired on uninstall.
Business context: the post-install/post-upgrade init Job lingered in the namespace forever after the Postgres instance was deleted — its only hook-delete-policy (before-hook-creation) never triggers on uninstall (#3055).
Verified: native ttlSecondsAfterFinished is honored by the TTL controller regardless of Helm, and it doesn't touch the hook-timeout semantics the bootstrap-recovery flow depends on. The test pins ttl=3600 and that the init Job is skipped (count: 0) under bootstrap.enabled. No blockers.
Problem
After deleting a
Postgresapp CR, the chart-managed init Job<release>-init-joband its completed Pod remain in the tenant namespace indefinitely (reported in #3055).The init Job is a Helm hook (
post-install,post-upgrade) whose only delete policy isbefore-hook-creation. That policy deletes the previous hook only right before a new one is created (next upgrade) — it never fires onhelm uninstall. With nohook-succeededand no TTL, the completed Job and Pod leak.Root cause
packages/apps/postgres/templates/init-job.yaml— the Job has no garbage-collection mechanism for its completed state.Fix
Add
ttlSecondsAfterFinished: 120to the Job spec. The native Kubernetes TTL controller then GCs the Job and its Pod ~2 minutes after completion, regardless of the Helm hook lifecycle.The init Job is a one-shot, idempotent reconciler of users/databases/roles (
init-script.yaml) — once it has run it is not needed until the next upgrade (when Helm recreates it), so GC-ing the finished Job is safe.This approach deliberately does not touch the hook-delete-policy / hook-timeout semantics, which the
bootstrap.recoverypath depends on (see the header comment ininit-job.yaml). Underbootstrap.enabledthe Job is skipped entirely, so the change is inert there.Tests
Added a
helm-unittestsuitepackages/apps/postgres/tests/init_job_cleanup_test.yaml:spec.ttlSecondsAfterFinished: 120bootstrap.enabled: trueVerified locally with
helm template(TTL present on default render; Job absent under bootstrap recovery).Test plan
helm templaterendersttlSecondsAfterFinished: 120on the init Jobhelm unittest packages/apps/postgresgreen in CItest-apps-postgresgreenFixes #3055
Summary by CodeRabbit
New Features
Tests