-
Notifications
You must be signed in to change notification settings - Fork 68
✨ (Valid for Boxcutter Runtime Only) switched to label-based revision lookups — faster, safer, and no orphans left behind. #2315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for olmv1 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors how previous revisions are discovered during ClusterExtensionRevision reconciliation. Instead of relying on a static Spec.Previous field, the controller now dynamically queries for previous revisions using the owner label, enabling more flexible revision management.
Key changes:
- Introduced
ListPreviousRevisions()method to dynamically discover sibling revisions - Updated
toBoxcutterRevision()to callListPreviousRevisions()and return errors - Enhanced test coverage with comprehensive test cases for the new listing logic
- Improved test names and added scenario comments for better readability
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| internal/operator-controller/controllers/clusterextensionrevision_controller.go | Added ListPreviousRevisions() method for dynamic revision discovery, refactored toBoxcutterRevision() signature to return errors, removed unused unstructured import |
| internal/operator-controller/controllers/clusterextensionrevision_controller_test.go | Added comprehensive tests for ListPreviousRevisions(), updated test names to be more descriptive, added scenario comments, updated mockTrackingCache to delegate Get/List to actual client, removed obsolete Spec.Previous test setup, added owner label to test revision helper |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2315 +/- ##
==========================================
+ Coverage 71.14% 74.11% +2.96%
==========================================
Files 91 91
Lines 7046 7101 +55
==========================================
+ Hits 5013 5263 +250
+ Misses 1618 1417 -201
- Partials 415 421 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
3a1c266 to
9c8f9af
Compare
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
9c8f9af to
6026ae8
Compare
c067348 to
6076304
Compare
6076304 to
5a89bed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
5a89bed to
fbf27d6
Compare
fbf27d6 to
c7ea251
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Outdated
Show resolved
Hide resolved
…it chains Instead of tracking revision history through Spec.Previous fields, we now find related revisions using labels and the controller-runtime cache. This is more efficient and works better with controller-runtime's caching layer. To support this change, the Helm-to-Boxcutter migration now sets ownerReferences on migrated revisions, ensuring they work identically to newly created revisions. Assisted-by: Cursor
c7ea251 to
ef2c006
Compare
| // Package name must be in labels for BoxcutterRevisionStatesGetter to find it | ||
| if pkg, ok := annotations[labels.PackageNameKey]; ok { | ||
| revisionLabels[labels.PackageNameKey] = pkg | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why:
- Main already reads
Packagefromrev.Labels["package-name"]in BoxcutterRevisionStatesGetter - But main doesn't set it during migration - Package field was always empty
- This fixes the bug by copying package name from annotations to labels
| } | ||
| // Only archive revisions with lower revision numbers (actual previous revisions) | ||
| if r.Spec.Revision >= rev.Spec.Revision { | ||
| continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still populate Spec.Previous even though we now use labels for discovery because:
-
- API Compatibility - It's a published field in the CRD and marked immutable. Removing it would be a breaking change.
-
- Garbage Collection -
setPreviousRevisions()uses it to enforce the 5 revision limit and delete older archived revisions.
- Garbage Collection -
-
- Audit Trail - Provides a historical record of the revision chain, useful for debugging and understanding upgrade history.
| if err := bc.Client.Get(ctx, client.ObjectKey{Name: currentRevision.Name}, updated); err != nil { | ||
| return false, "", fmt.Errorf("fetching updated revision: %w", err) | ||
| } | ||
| currentRevision = updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After in-place patch, currentRevision pointed to stale object with old annotations.
It is a bug fixes required to allow we move forward here and pass on the tests.
The scenario where it would fail is: v1.0.0 → v1.0.1 with identical bundle (only metadata changes)
| // - When a revision is archived or being deleted, exclude it from results | ||
| // - When a revision has a higher or equal revision number, exclude it (not a previous revision) | ||
| // - Otherwise include active and paused revisions with matching owner | ||
| func (c *ClusterExtensionRevisionReconciler) ListPreviousRevisions(ctx context.Context, rev *ocv1.ClusterExtensionRevision) ([]client.Object, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added ListPreviousRevisions(ctx, rev) that queries revisions by owner label and filters:
- Same ClusterExtension owner
- Revision number < current (only actual previous revisions)
- Active or paused (not archived)
Why the revision number filter matters:
Without it, Revision-1 completing would archive Revision-2, causing "revision is archived" errors.
| // This makes the migrated revision consistent with revisions created by normal Boxcutter flow. | ||
| if err := controllerutil.SetControllerReference(ext, rev, m.Scheme); err != nil { | ||
| return fmt.Errorf("set ownerref: %w", err) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tmshort That should address the JIRA you added: https://issues.redhat.com/browse/OPRUN-4038
Once this PR is merged, I plan to extend the test coverage to validate the orphan scenario, ensuring we’re not leaving any orphans behind. If we identify any, we’ll handle them properly in a follow-up PR.
Revisions are now discovered using a label-based cache instead of walking explicit
Spec.Previouschains.This makes lookups faster, safer, and ensures no orphan revisions are left behind when a ClusterExtension is deleted.
Migration automatically sets
ownerReferencesfor existing revisions.What Changed
Before:
Spec.PreviousownerReferencesNow:
olm.operatorframework.io/ownerownerReferencesWhy It's Better
Where it matters ( With Boxcutter runtime only )
ownerReferences