fix: resolve stale predecessor misidentification during self-update - #1713
Conversation
- Add IsOldNamedContainer helper to identify predecessor containers by name prefix - Fix hostname-based detection to prefer non-old-named Watchtower over lingering predecessor - Resolve old-named current container to same-scope successor in excess cleanup and chain logic - Skip redundant rename when source container already has the target old name
- Fix `getChainedContainers` to clear `effectiveCurrent` when no non-renamed successor container is found, preventing stale references from being used - Set `renamed = true` in `restartStaleContainer` when skipping rename of an already-renamed container, ensuring correct tracking of rename state - Update test expectation to reflect that the container is correctly identified as renamed
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughDetects Watchtower "old-named" containers (prefix ChangesOld-Named Container Handling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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 |
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Complexity | 1 medium |
🟢 Metrics 35 complexity · 39 duplication
Metric Results Complexity 35 Duplication 39
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Codecov Report❌ Patch coverage is
@@ Coverage Diff @@
## main #1713 +/- ##
==========================================
- Coverage 74.59% 74.41% -0.18%
==========================================
Files 60 61 +1
Lines 10052 10199 +147
==========================================
+ Hits 7498 7590 +92
- Misses 2286 2330 +44
- Partials 268 279 +11
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
internal/actions/update.go (1)
1676-1719: ⚡ Quick winCentralize the old-name prefix contract.
"watchtower-old-"is now a cross-file protocol between rename generation here and detection inpkg/container/container_id.go. Keeping it duplicated makes future drift easy and would silently break successor detection again. Please move the prefix into a shared constant/helper and buildtargetOldNamefrom that single source of truth.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/actions/update.go` around lines 1676 - 1719, The hard-coded prefix "watchtower-old-" must be centralized: introduce a shared constant (e.g., OldWatchtowerOldPrefix or WatchtowerOldPrefix) in the common package used by container ID logic, update the detection function IsOldNamedContainer to reference that constant, and replace the inline string here when building targetOldName (symbol targetOldName) so targetOldName is constructed from the new constant before calling client.RenameContainer; ensure both rename generation and IsOldNamedContainer use the single source-of-truth constant/helper so the cross-file protocol cannot drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/actions/cleanup.go`:
- Around line 188-199: When currentContainer is old-named, do not pick the first
non-old-named container; instead resolve the true successor by matching lineage:
iterate filteredContainers and prefer a container whose chain/lineage label
(e.g., the Watchtower chain label accessed via c.Labels()[<chainLabelKey>] or
similar) contains currentContainer.ID() (or exact predecessor identifier) and
use that container's ID as currentID; only if no explicit lineage match is found
fall back to the existing scope-only selection. Apply this same lineage-first
logic to the other similar block handling (the section around the 234-268
range).
---
Nitpick comments:
In `@internal/actions/update.go`:
- Around line 1676-1719: The hard-coded prefix "watchtower-old-" must be
centralized: introduce a shared constant (e.g., OldWatchtowerOldPrefix or
WatchtowerOldPrefix) in the common package used by container ID logic, update
the detection function IsOldNamedContainer to reference that constant, and
replace the inline string here when building targetOldName (symbol
targetOldName) so targetOldName is constructed from the new constant before
calling client.RenameContainer; ensure both rename generation and
IsOldNamedContainer use the single source-of-truth constant/helper so the
cross-file protocol cannot drift.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 24c1d184-6a8f-4b52-8f76-5edc130a6121
📒 Files selected for processing (6)
internal/actions/actions_internal_test.gointernal/actions/cleanup.gointernal/actions/cleanup_test.gointernal/actions/update.gopkg/container/container_id.gopkg/container/container_id_test.go
- Replace naive non-old-named fallback in `getFilteredContainers` with chain-label matching: prefer a successor whose container chain contains the old container's ID, falling back to scope-only match - Update `getChainedContainers` to use explicit lineage link via chain label before accepting scope-only match, and reset `effectiveCurrent` when no valid successor exists - Extract `WatchtowerOldPrefix` constant in `pkg/container/container_id.go` and use it in `restartStaleContainer` to eliminate hardcoded string literal
This PR addresses issues that intermittently materialize during self-updates.
Problem
When Watchtower updates itself, the old instance is renamed to
watchtower-old-<id>and continues running with the expectation of the new container performing the cleanup of excess Watchtower containers. Multiple code paths failed to distinguish this stale predecessor from the running successor, causing intermittent failures. This manifests at several points:watchtower-old-prefix, causing a same-name error.Solution
Added
IsOldNamedContainer(name)to detect thewatchtower-old-prefix convention, then resolved to the successor at each affected decision point:Changes
pkg/container/container_id.go— addedIsOldNamedContainer; hostname fallback prefers non-predecessor matchesinternal/actions/cleanup.go—getFilteredContainersandgetChainedContainersresolve successors when current is a predecessor;getChainedContainersreturns empty when no successor foundinternal/actions/update.go—restartStaleContainerskips redundant renameSummary by CodeRabbit