Skip to content

Conversation

@camilamacedo86
Copy link
Contributor

@camilamacedo86 camilamacedo86 commented Nov 9, 2025

Revisions are now discovered using label-based cache lookups instead of explicit Spec.Previous chains.

This makes lookups faster and ensures proper cleanup when a ClusterExtension is deleted.

What Changed

API (Breaking - OK in experimental mode):

  • Removed Spec.Previous field from ClusterExtensionRevision
  • Removed ClusterExtensionRevisionPrevious type

Discovery:

  • Revisions queried by label olm.operatorframework.io/owner via TrackingCache
  • Filtered in-memory (skip current, archived, deleting, higher revision numbers)

Migration:

  • Sets ownerReferences so revisions are garbage collected with their ClusterExtension
  • Uses natural reconciliation: sets Available=Unknown, lets revision controller verify cluster state
  • Re-fetches after Create() to get accurate Generation for ObservedGeneration

Garbage Collection:

  • Renamed function and constant for clarity (garbageCollectOldRevisions, ClusterExtensionRevisionRetentionLimit)
  • Still enforces 5 revision limit for archived revisions

Why It's Better

Performance:

  • Uses TrackingCache for label-based lookups instead of API calls
  • Single query replaces chain walking

Reliability:

  • Deleting ClusterExtension auto-deletes all its revisions via ownerReferences
  • No orphaned revisions left behind

Simplicity:

  • Removed explicit chain tracking from API
  • Revision numbers provide self-evident ordering

Migration Behavior

When upgrading from Helm storage:

  1. Migration creates revision with Available=Unknown status
  2. ClusterExtension briefly shows as not installed
  3. Revision controller reconciles, verifies cluster state via probes
  4. Once healthy, sets Available=True and Succeeded=True
  5. ClusterExtension converges to installed state

Demo

asciicast

Copilot AI review requested due to automatic review settings November 9, 2025 00:17
@camilamacedo86 camilamacedo86 requested a review from a team as a code owner November 9, 2025 00:17
@netlify
Copy link

netlify bot commented Nov 9, 2025

Deploy Preview for olmv1 ready!

Name Link
🔨 Latest commit 056baee
🔍 Latest deploy log https://app.netlify.com/projects/olmv1/deploys/691c6f0962ede300089b3ca4
😎 Deploy Preview https://deploy-preview-2315--olmv1.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

Copilot AI left a 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 call ListPreviousRevisions() 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.

@camilamacedo86 camilamacedo86 changed the title ✨ (chore): (Boxcutter): Use label selector for listing previous revisions WIP ✨ (chore): (Boxcutter): Use label selector for listing previous revisions Nov 9, 2025
@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 9, 2025
@codecov
Copy link

codecov bot commented Nov 9, 2025

Codecov Report

❌ Patch coverage is 62.29508% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.18%. Comparing base (cbdb84c) to head (008d77e).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...controllers/clusterextensionrevision_controller.go 63.15% 11 Missing and 3 partials ⚠️
internal/operator-controller/applier/boxcutter.go 57.14% 5 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2315      +/-   ##
==========================================
- Coverage   74.32%   74.18%   -0.15%     
==========================================
  Files          92       92              
  Lines        7226     7256      +30     
==========================================
+ Hits         5371     5383      +12     
- Misses       1428     1437       +9     
- Partials      427      436       +9     
Flag Coverage Δ
e2e 44.55% <0.00%> (-0.13%) ⬇️
experimental-e2e 48.50% <44.26%> (-0.17%) ⬇️
unit 58.24% <59.01%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch 2 times, most recently from 9c8f9af to 6026ae8 Compare November 9, 2025 11:35
@camilamacedo86 camilamacedo86 changed the title WIP ✨ (chore): (Boxcutter): Use label selector for listing previous revisions WIP ✨ (chore): (Boxcutter): se label-based cache for revision lookups instead of explicit chains; Nov 9, 2025
@camilamacedo86 camilamacedo86 changed the title WIP ✨ (chore): (Boxcutter): se label-based cache for revision lookups instead of explicit chains; ✨ (Valid for Boxcutter Runtime Only) switched to label-based revision lookups — faster, safer, and no orphans left behind. Nov 9, 2025
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 9, 2025
@camilamacedo86 camilamacedo86 changed the title ✨ (Valid for Boxcutter Runtime Only) switched to label-based revision lookups — faster, safer, and no orphans left behind. WIP ✨ (Valid for Boxcutter Runtime Only) switched to label-based revision lookups — faster, safer, and no orphans left behind. Nov 9, 2025
@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 9, 2025
@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch 4 times, most recently from c067348 to 6076304 Compare November 9, 2025 12:57
Copilot AI review requested due to automatic review settings November 9, 2025 13:10
@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch from 6076304 to 5a89bed Compare November 9, 2025 13:10

This comment was marked as outdated.

@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch from 5a89bed to fbf27d6 Compare November 9, 2025 13:50
Copilot AI review requested due to automatic review settings November 9, 2025 18:24
@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch from fbf27d6 to c7ea251 Compare November 9, 2025 18:24

This comment was marked as outdated.

@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch from c7ea251 to ef2c006 Compare November 9, 2025 19:01
}
// Only archive revisions with lower revision numbers (actual previous revisions)
if r.Spec.Revision >= rev.Spec.Revision {
continue
Copy link
Contributor Author

@camilamacedo86 camilamacedo86 Nov 9, 2025

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:

    1. API Compatibility - It's a published field in the CRD and marked immutable. Removing it would be a breaking change.
    1. Garbage Collection - setPreviousRevisions() uses it to enforce the 5 revision limit and delete older archived revisions.
    1. Audit Trail - Provides a historical record of the revision chain, useful for debugging and understanding upgrade history.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this one. I think we can violate i since we're still in experimental mode and breaking changes are allowed, we should probably update ii to use the List function anyway, and lastly, revisions are numbered, so the chain should be self-evident, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are 100% right and we can keep things simple here by removing it.

@camilamacedo86
Copy link
Contributor Author

Hi @pedjak,

We are changing the public API:
https://github.com/operator-framework/operator-controller/pull/2315/files#diff-35832abf0db7539022428aa7858395b2f994892cb14e0f2a41c3d05137af599d

If this had already been promoted to GA, we wouldn’t be able to do that. It currently fails the go-apidiff check, which confirms it’s a user-facing change. Anything that affects what users see or experience is considered a user-facing change. In contrast, changes that only modify how we do things internally—without altering how information is presented, stored, or accessed on the cluster—are not user-facing.

So it should actually have a ⚠️ in case someone is still using it.
I’ve updated the title to make that clearer.

Additionally, this change resolves a user-facing issue by ensuring that orphaned revisions are no longer left behind on the cluster.

Thank you 🙏

Copy link
Contributor

@pedjak pedjak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm a few questions left author to decide if they should be addressed in this PR or follow-ups.

}

revList := &ocv1.ClusterExtensionRevisionList{}
if err := c.TrackingCache.List(ctx, revList, client.MatchingLabels{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the advantage of using c.TrackingCache.List() vs. c.Client.List()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. TrackingCache.List() comes from Boxcutter’s managedcache (https://pkg.go.dev/pkg.package-operator.run/[email protected]/managedcache
). It tracks object-to-revision relationships, which the standard c.Client doesn’t. This is mostly experimental — we could use the default controller-runtime client instead.

Since this is in tech preview, I’m was looking for us to use it for now, but we should keep an eye on the usual trade-offs: double caching, some memory overhead, possible some maintenance complexity. If the tracking features don’t end up paying off, we can switch to c.Client.List() later.

My idea was try out it now, and see if we found bugs, allow we epxlore more in follow-ups and add some E2E coverage around it. Let me know if this makes sense.

@thetechnick have you any reason for we do not use it?

previous = append(previous, prev)
// listPreviousRevisions returns active revisions belonging to the same ClusterExtension with lower revision numbers.
// Filters out the current revision, archived revisions, deleting revisions, and revisions with equal or higher numbers.
func (c *ClusterExtensionRevisionReconciler) listPreviousRevisions(ctx context.Context, rev *ocv1.ClusterExtensionRevision) ([]client.Object, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason why we do not return []*ocv1.ClusterExtensionRevision?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed ! I think is better your proposal

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Nov 18, 2025
@openshift-ci
Copy link

openshift-ci bot commented Nov 18, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: pedjak, perdasilva

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch from 5161d30 to 3d11630 Compare November 18, 2025 12:14
@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Nov 18, 2025
Copilot AI review requested due to automatic review settings November 18, 2025 12:23
@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch from 3d11630 to b0f47d1 Compare November 18, 2025 12:23
Copilot finished reviewing on behalf of camilamacedo86 November 18, 2025 12:26
Copy link

Copilot AI left a 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 13 out of 13 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…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
@camilamacedo86 camilamacedo86 force-pushed the boxcutter-use-labels-cache branch from b0f47d1 to 056baee Compare November 18, 2025 13:05
@camilamacedo86
Copy link
Contributor Author

/hold

Doing some tests locally

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 18, 2025
@camilamacedo86
Copy link
Contributor Author

/hold cancel

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 18, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

@pedjak pedjak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Nov 18, 2025
@tmshort
Copy link
Contributor

tmshort commented Nov 18, 2025

/override go-apidiff/go-apidiff

@openshift-ci
Copy link

openshift-ci bot commented Nov 18, 2025

@tmshort: /override requires failed status contexts, check run or a prowjob name to operate on.
The following unknown contexts/checkruns were given:

  • go-apidiff/go-apidiff

Only the following failed contexts/checkruns were expected:

  • Verify PR title
  • crd-diff
  • e2e-kind
  • extension-developer-e2e
  • go-apidiff
  • go-verdiff
  • goreleaser
  • lint
  • netlify/olmv1/deploy-preview
  • tide
  • unit-test-basic
  • upgrade-e2e
  • verify

If you are trying to override a checkrun that has a space in it, you must put a double quote on the context.

In response to this:

/override go-apidiff/go-apidiff

Instructions 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.

@tmshort
Copy link
Contributor

tmshort commented Nov 18, 2025

/override go-apidiff

@openshift-ci
Copy link

openshift-ci bot commented Nov 18, 2025

@tmshort: Overrode contexts on behalf of tmshort: go-apidiff

In response to this:

/override go-apidiff

Instructions 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.

@tmshort
Copy link
Contributor

tmshort commented Nov 18, 2025

/override go-apidiff

@openshift-ci
Copy link

openshift-ci bot commented Nov 18, 2025

@tmshort: Overrode contexts on behalf of tmshort: go-apidiff

In response to this:

/override go-apidiff

Instructions 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.

@openshift-merge-bot openshift-merge-bot bot merged commit 472e8a2 into operator-framework:main Nov 18, 2025
31 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants