handle ErrNotAnImage in RemoveImage for concurrent deletion idempotency#9803
Conversation
…potency When multiple concurrent RemoveImage calls race on the same image, the first call succeeds but subsequent calls fail with "identifier is not an image" (ErrNotAnImage). This happens because the image is already gone from storage by the time the other goroutines attempt deletion. The existing idempotency check only handled ErrImageUnknown but not ErrNotAnImage, which is the error returned by containers/storage when the image ID no longer resolves. Add ErrNotAnImage to the idempotency checks in both the ID-based and name-based deletion paths. Fixes cri-o#9796 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jindrich Novy <jnovy@redhat.com>
|
Hi @jnovy. Thanks for your PR. I'm waiting for a cri-o member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
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 (2)
📝 WalkthroughWalkthroughModified Changes
Possibly related issues
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)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9803 +/- ##
==========================================
+ Coverage 64.65% 67.53% +2.88%
==========================================
Files 212 212
Lines 29233 29235 +2
==========================================
+ Hits 18900 19745 +845
+ Misses 8643 7801 -842
+ Partials 1690 1689 -1 🚀 New features to boost your workflow:
|
|
/ok-to-test |
saschagrunert
left a comment
There was a problem hiding this comment.
Clean and well-targeted fix. The change is correct, tests cover both the ID-based and name-based deletion paths, and codecov confirms full coverage.
Minor observation: the statusErr check at line 119 is now functionally redundant since line 126 also returns nil unconditionally. It reads as documentation of intent, which is fine, but worth noting for a future cleanup.
LGTM.
| } | ||
|
|
||
| if !deleted && untagErr != nil { | ||
| if errors.Is(untagErr, storagetypes.ErrImageUnknown) || errors.Is(untagErr, storagetypes.ErrNotAnImage) { |
There was a problem hiding this comment.
Good catch adding ErrImageUnknown here as well. The existing code only had ErrImageUnknown handling in the ID-based path (line 49) and ErrNotAnImage handling via statusErr at line 119. This closes the gap where UntagImage could also return ErrImageUnknown during a concurrent deletion race.
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jnovy, saschagrunert The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/retest |
2 similar comments
|
/retest |
|
/retest |
When multiple concurrent RemoveImage calls race on the same image, the first call succeeds but subsequent calls fail with "identifier is not an image" (ErrNotAnImage). This happens because the image is already gone from storage by the time the other goroutines attempt deletion.
The existing idempotency check only handled ErrImageUnknown but not ErrNotAnImage, which is the error returned by containers/storage when the image ID no longer resolves. Add ErrNotAnImage to the idempotency checks in both the ID-based and name-based deletion paths.
Fixes #9796
What type of PR is this?
/kind bug
What this PR does / why we need it:
When multiple concurrent
RemoveImagecalls race on the same image, the first call succeeds but subsequent calls fail with "identifier is not an image" (ErrNotAnImage). This happens because the image is already gone from storage by the time the other goroutines attempt deletion.The existing idempotency check only handled
ErrImageUnknownbut notErrNotAnImage, which is the error returned bycontainers/storagewhen the image ID no longer resolves. This PR addsErrNotAnImageto the idempotency checks in both the ID-based and name-based deletion paths.Which issue(s) this PR fixes:
Fixes #9796
Special notes for your reviewer:
None
Does this PR introduce a user-facing change?
Summary by CodeRabbit
Release Notes