-
Notifications
You must be signed in to change notification settings - Fork 68
✨ Propagate ClusterExtensionRevision conditions to ClusterExtension status #2281
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
✨ Propagate ClusterExtensionRevision conditions to ClusterExtension status #2281
Conversation
✅ Deploy Preview for olmv1 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
/hold wip |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2281 +/- ##
==========================================
- Coverage 74.88% 74.81% -0.08%
==========================================
Files 95 95
Lines 7323 7377 +54
==========================================
+ Hits 5484 5519 +35
- Misses 1407 1421 +14
- Partials 432 437 +5
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:
|
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Outdated
Show resolved
Hide resolved
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Outdated
Show resolved
Hide resolved
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Outdated
Show resolved
Hide resolved
8a1a5d4 to
496d418
Compare
496d418 to
8c97bd7
Compare
16c6ada to
6f1271c
Compare
6f1271c to
16c6ada
Compare
16c6ada to
ef00449
Compare
ef00449 to
370f203
Compare
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Outdated
Show resolved
Hide resolved
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Outdated
Show resolved
Hide resolved
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Outdated
Show resolved
Hide resolved
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Outdated
Show resolved
Hide resolved
db396e5 to
370f203
Compare
370f203 to
1622df1
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
This PR refactors the ClusterExtension reconciliation process to use a step-based architecture and updates condition handling to use Available and Progressing conditions instead of the legacy Installed condition. The changes support better status reporting from ClusterExtensionRevision objects and introduce an ActiveRevisions status field.
Key changes:
- Introduces a step-based reconciliation pattern using
ReconcileStepFuncto break down the reconcile logic into composable steps - Updates CRD printer columns and status types to use
Availableinstead ofInstalledcondition - Adds
Progressingcondition to ClusterExtensionRevision with new reasons likeRollingOut,RolloutError, andRolledOut - Introduces
ActiveRevisionsstatus field to track active revisions in ClusterExtension status - Adds new test data for v1.0.2 test-operator bundle with httpd-based container setup
Reviewed Changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
internal/operator-controller/controllers/clusterextension_reconcile_steps.go |
New file implementing generic reconcile steps for finalizers, revision states, metadata retrieval, bundle unpacking, and application |
internal/operator-controller/controllers/boxcutter_reconcile_steps.go |
New file with boxcutter-specific reconcile steps including storage migration and condition mirroring |
internal/operator-controller/controllers/clusterextension_controller.go |
Refactored to remove inline reconcile logic, moved to step-based architecture with ReconcileSteps |
internal/operator-controller/controllers/clusterextensionrevision_controller.go |
Updated condition handling to use new helper methods and improved status messages with version information |
api/v1/clusterextensionrevision_types.go |
Added helper methods for marking revision status and new condition constants |
api/v1/clusterextension_types.go |
Added RevisionStatus type and ActiveRevisions field to status |
| CRD manifests | Updated printer columns from Installed to Available and added ActiveRevisions schema |
| Test files | Updated to use new reconciler setup pattern with options, updated expected conditions |
| Test data | Added v1.0.2 bundle with httpd container setup and updated v1.0.0/v1.2.0 bundles |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
internal/operator-controller/controllers/boxcutter_reconcile_steps.go
Outdated
Show resolved
Hide resolved
internal/operator-controller/controllers/clusterextensionrevision_controller.go
Show resolved
Hide resolved
7e9a601 to
877dfec
Compare
|
/unhold ready for review |
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 20 out of 20 changed files in this pull request and generated 9 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
internal/operator-controller/controllers/boxcutter_reconcile_steps.go
Outdated
Show resolved
Hide resolved
internal/operator-controller/controllers/boxcutter_reconcile_steps.go
Outdated
Show resolved
Hide resolved
internal/operator-controller/controllers/boxcutter_reconcile_steps.go
Outdated
Show resolved
Hide resolved
88ed002 to
12e578b
Compare
internal/operator-controller/controllers/boxcutter_reconcile_steps.go
Outdated
Show resolved
Hide resolved
| // is fairly decoupled from this code where we get the annotations back out. We may want to co-locate | ||
| // the set/get logic a bit better to make it more maintainable and less likely to get out of sync. | ||
| rm := &RevisionMetadata{ | ||
| Package: rev.Annotations[labels.PackageNameKey], |
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.
From yesterday's discussion, should we stick to annotations?
| if i := state.revisionStates.Installed; i != nil { | ||
| for _, cndType := range []string{ocv1.ClusterExtensionRevisionTypeAvailable, ocv1.ClusterExtensionRevisionTypeProgressing} { | ||
| if cnd := apimeta.FindStatusCondition(i.Conditions, cndType); cnd != nil { | ||
| cnd.ObservedGeneration = ext.GetGeneration() |
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.
Not for this PR, but I wonder if we should carry the CE generation as an annotation on the CER...
| Version: "1.0.1", | ||
| PackageName: "test", | ||
| Version: "1.0.1", | ||
| UpgradeConstraintPolicy: ocv1.UpgradeConstraintPolicySelfCertified, |
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.
How come we need this?
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.
Because there's no upgrade edge between 1.0.1 and 1.0.2? should we call it out in a comment?
|
LGTM |
|
/approve |
322a717 to
e762c77
Compare
e762c77 to
c90c978
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 17 out of 17 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| cnd.ObservedGeneration = ext.GetGeneration() | ||
| apimeta.SetStatusCondition(&ext.Status.Conditions, *cnd) |
Copilot
AI
Dec 10, 2025
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.
The condition retrieved from i.Conditions is being modified directly (line 122) before being passed to SetStatusCondition. According to the repository convention, conditions from ClusterExtensionRevision should be deep-copied before modification when propagating to ClusterExtension status.
Suggested fix:
if cnd := apimeta.FindStatusCondition(i.Conditions, cndType); cnd != nil {
cndCopy := cnd.DeepCopy()
cndCopy.ObservedGeneration = ext.GetGeneration()
apimeta.SetStatusCondition(&ext.Status.Conditions, *cndCopy)
}| cnd.ObservedGeneration = ext.GetGeneration() | |
| apimeta.SetStatusCondition(&ext.Status.Conditions, *cnd) | |
| cndCopy := cnd.DeepCopy() | |
| cndCopy.ObservedGeneration = ext.GetGeneration() | |
| apimeta.SetStatusCondition(&ext.Status.Conditions, *cndCopy) |
| if cnd := apimeta.FindStatusCondition(rs.Conditions, cndType); cnd != nil { | ||
| cnd.ObservedGeneration = ext.GetGeneration() | ||
| apimeta.SetStatusCondition(&rs.Conditions, *cnd) |
Copilot
AI
Dec 10, 2025
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.
This code attempts to find a condition in rs.Conditions, but rs was just created on line 132 with only the Name field set and an empty Conditions slice. This means apimeta.FindStatusCondition(rs.Conditions, cndType) will always return nil, making lines 134-137 ineffective.
The intended logic appears to be finding the condition from r.Conditions (the source RevisionMetadata), not rs.Conditions (the destination RevisionStatus).
Suggested fix:
if cnd := apimeta.FindStatusCondition(r.Conditions, cndType); cnd != nil {
cndCopy := cnd.DeepCopy()
cndCopy.ObservedGeneration = ext.GetGeneration()
apimeta.SetStatusCondition(&rs.Conditions, *cndCopy)
}| if cnd := apimeta.FindStatusCondition(rs.Conditions, cndType); cnd != nil { | |
| cnd.ObservedGeneration = ext.GetGeneration() | |
| apimeta.SetStatusCondition(&rs.Conditions, *cnd) | |
| if cnd := apimeta.FindStatusCondition(r.Conditions, cndType); cnd != nil { | |
| cndCopy := cnd.DeepCopy() | |
| cndCopy.ObservedGeneration = ext.GetGeneration() | |
| apimeta.SetStatusCondition(&rs.Conditions, *cndCopy) |
| | Field | Description | Default | Validation | | ||
| | --- | --- | --- | --- | | ||
| | `name` _string_ | name is the revision name that can be used to retrieve it. | | | | ||
| | `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions is a set of conditions associated with the revision. | | | |
Copilot
AI
Dec 10, 2025
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.
The field description in the generated documentation is incomplete compared to the API type definition. The API type has a more detailed description explaining:
- "conditions optionally expose Progressing and Available condition of the revision"
- "in case when it is not yet marked as successfully installed (condition Succeeded is not set to True)"
- "Given that a ClusterExtension should remain available during upgrades, an observer may use these conditions to get more insights about reasons for its current state"
However, the generated documentation only shows "Conditions is a set of conditions associated with the revision."
This suggests the documentation generation tool may not be picking up the full comment from the API type (lines 479-482 in api/v1/clusterextension_types.go). Please verify that the documentation generation correctly extracts the full field description.
| | `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions is a set of conditions associated with the revision. | | | | |
| | `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions optionally expose Progressing and Available condition of the revision. In case when it is not yet marked as successfully installed (condition Succeeded is not set to True), these conditions provide additional insight. Given that a ClusterExtension should remain available during upgrades, an observer may use these conditions to get more insights about reasons for its current state. | | | |
… status * `ClusterExtension`'s `Available` and `Progressing` conditions are equal to the counterparts on the latest installed active revision * When a new revision is rolling out, mirror its `Progressing` condition to its counterpart on `ClusterExtension` to improve visibility and to signal that a transition is in progress * Adds `.status.activeRevisions` field to the `ClusterExtension` to track the active revisions and mirrors `Available` and `Progressing` conditions for those not marked yet as installed This changes opens up a possibility for an observer to get insights on `ClusterExtension` update process: * When Reason on `Progressing` condition flips to `RollingOut`, an update is in progress * More then one revision could be listed under `.status.activeRevisions` during upgrade (installed + those in progress) * `Available` and `Progressing` conditions of an active, but not yet available revision, are listed under `.status.activeRevisions.conditions` so that can be easier to understand update issues The new behavior is marked as experimental behind Boxcutter feature gate.
c90c978 to
3816d20
Compare
|
/lgtm |
rashmigottipati
left a comment
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.
/lgtm
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: perdasilva, rashmigottipati 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 |
e4a633e
into
operator-framework:main
Description
ClusterExtension'sAvailableandProgressingconditions are equal to the counterparts on the latest installed active revisionProgressingcondition to its counterpart onClusterExtensionto improve visibility and to signal that a transition is in progress.status.activeRevisionsfield to theClusterExtensionto track the active revisions and mirrorsAvailableandProgressingconditions for those not marked yet as installedThis changes opens up a possibility for an observer to get insights on
ClusterExtensionupdate process:Progressingcondition flips toRollingOut, an update is in progress.status.activeRevisionsduring upgrade (installed + those in progress)AvailableandProgressingconditions of an active, but not yet available revision, are listed under.status.activeRevisions.conditionsso that can be easier to understand update issuesThe new behavior is marked as experimental behind Boxcutter feature gate.
Reviewer Checklist