Skip to content

✨ Propagate ClusterExtensionRevision conditions to ClusterExtension status - #2281

Merged
openshift-merge-bot[bot] merged 1 commit into
operator-framework:mainfrom
perdasilva:revision-conditions
Dec 10, 2025
Merged

✨ Propagate ClusterExtensionRevision conditions to ClusterExtension status#2281
openshift-merge-bot[bot] merged 1 commit into
operator-framework:mainfrom
perdasilva:revision-conditions

Conversation

@perdasilva

@perdasilvaperdasilva commented Oct 21, 2025

Copy link
Copy Markdown
Contributor

Description

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

Reviewer Checklist

  • API Go Documentation
  • Tests: Unit Tests (and E2E Tests, if appropriate)
  • Comprehensive Commit Messages
  • Links to related GitHub Issue(s)

@openshift-ciopenshift-ciBot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Oct 21, 2025
@netlify

netlifyBot commented Oct 21, 2025

Copy link
Copy Markdown

Deploy Preview for olmv1 ready!

NameLink
🔨 Latest commit3816d20
🔍 Latest deploy loghttps://app.netlify.com/projects/olmv1/deploys/6939679e3497bd0008b2cf3f
😎 Deploy Previewhttps://deploy-preview-2281--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.

@perdasilva

Copy link
Copy Markdown
ContributorAuthor

/hold wip

@openshift-ciopenshift-ciBot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 21, 2025
@codecov

codecovBot commented Oct 21, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.83051% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.81%. Comparing base (ff7d3c2) to head (3816d20).
⚠️ Report is 1 commits behind head on main.

Files with missing linesPatch %Lines
api/v1/zz_generated.deepcopy.go66.66%6 Missing ⚠️
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 
FlagCoverage Δ
e2e44.65% <0.00%> (-0.29%)⬇️
experimental-e2e49.23% <89.83%> (-0.12%)⬇️
unit58.39% <0.00%> (-0.44%)⬇️

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.

Comment threadapi/v1/clusterextensionrevision_types.go Outdated
@pedjak
pedjakforce-pushed the revision-conditions branch from 496d418 to 8c97bd7CompareOctober 24, 2025 16:33
@openshift-merge-robotopenshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 24, 2025
@openshift-merge-robotopenshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 27, 2025
@openshift-merge-robotopenshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 27, 2025
@openshift-merge-robotopenshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 27, 2025
@pedjak
pedjakforce-pushed the revision-conditions branch from 370f203 to 1622df1CompareOctober 28, 2025 13:54
CopilotAI review requested due to automatic review settings November 5, 2025 17:42

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 ReconcileStepFunc to break down the reconcile logic into composable steps
  • Updates CRD printer columns and status types to use Available instead of Installed condition
  • Adds Progressing condition to ClusterExtensionRevision with new reasons like RollingOut, RolloutError, and RolledOut
  • Introduces ActiveRevisions status 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
FileDescription
internal/operator-controller/controllers/clusterextension_reconcile_steps.goNew file implementing generic reconcile steps for finalizers, revision states, metadata retrieval, bundle unpacking, and application
internal/operator-controller/controllers/boxcutter_reconcile_steps.goNew file with boxcutter-specific reconcile steps including storage migration and condition mirroring
internal/operator-controller/controllers/clusterextension_controller.goRefactored to remove inline reconcile logic, moved to step-based architecture with ReconcileSteps
internal/operator-controller/controllers/clusterextensionrevision_controller.goUpdated condition handling to use new helper methods and improved status messages with version information
api/v1/clusterextensionrevision_types.goAdded helper methods for marking revision status and new condition constants
api/v1/clusterextension_types.goAdded RevisionStatus type and ActiveRevisions field to status
CRD manifestsUpdated printer columns from Installed to Available and added ActiveRevisions schema
Test filesUpdated to use new reconciler setup pattern with options, updated expected conditions
Test dataAdded 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.

Comment threadinternal/operator-controller/controllers/boxcutter_reconcile_steps.go Outdated
CopilotAI review requested due to automatic review settings November 10, 2025 17:08
@openshift-merge-robotopenshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 10, 2025
@pedjak

Copy link
Copy Markdown
Contributor

/unhold ready for review

@openshift-ciopenshift-ciBot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Dec 8, 2025

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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.

Comment threadtest/e2e/cluster_extension_revision_test.go Outdated
Comment threadtest/e2e/cluster_extension_revision_test.go Outdated
Comment threadinternal/operator-controller/controllers/boxcutter_reconcile_steps.go Outdated
Comment threadapi/v1/clusterextension_types.go Outdated
Comment threadapi/v1/clusterextension_types.go
Comment threadinternal/operator-controller/controllers/boxcutter_reconcile_steps.go Outdated
Comment threadinternal/operator-controller/controllers/boxcutter_reconcile_steps.go Outdated
@pedjak
pedjakforce-pushed the revision-conditions branch from 88ed002 to 12e578bCompareDecember 8, 2025 17:03
Comment threadinternal/operator-controller/controllers/boxcutter_reconcile_steps.go Outdated
// 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],

Copy link
Copy Markdown
ContributorAuthor

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()

Copy link
Copy Markdown
ContributorAuthor

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

Comment threadapi/v1/clusterextension_types.go Outdated
Version: "1.0.1",
PackageName: "test",
Version: "1.0.1",
UpgradeConstraintPolicy: ocv1.UpgradeConstraintPolicySelfCertified,

Copy link
Copy Markdown
ContributorAuthor

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?

Copy link
Copy Markdown
ContributorAuthor

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?

CopilotAI review requested due to automatic review settings December 9, 2025 12:11
@michaelryanpeter

Copy link
Copy Markdown
Contributor

LGTM

@perdasilva

Copy link
Copy Markdown
ContributorAuthor

/approve

@openshift-ciopenshift-ciBot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Dec 10, 2025
CopilotAI review requested due to automatic review settings December 10, 2025 11:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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.

Comment on lines +122 to +123
cnd.ObservedGeneration = ext.GetGeneration()
apimeta.SetStatusCondition(&ext.Status.Conditions, *cnd)

CopilotAIDec 10, 2025

Copy link

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:

ifcnd:=apimeta.FindStatusCondition(i.Conditions, cndType); cnd!=nil {
cndCopy:=cnd.DeepCopy()
cndCopy.ObservedGeneration=ext.GetGeneration()
apimeta.SetStatusCondition(&ext.Status.Conditions, *cndCopy)
}
Suggested change
cnd.ObservedGeneration=ext.GetGeneration()
apimeta.SetStatusCondition(&ext.Status.Conditions, *cnd)
cndCopy:=cnd.DeepCopy()
cndCopy.ObservedGeneration=ext.GetGeneration()
apimeta.SetStatusCondition(&ext.Status.Conditions, *cndCopy)

Copilot uses AI. Check for mistakes.
Comment on lines +134 to +136
if cnd := apimeta.FindStatusCondition(rs.Conditions, cndType); cnd != nil {
cnd.ObservedGeneration = ext.GetGeneration()
apimeta.SetStatusCondition(&rs.Conditions, *cnd)

CopilotAIDec 10, 2025

Copy link

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:

ifcnd:=apimeta.FindStatusCondition(r.Conditions, cndType); cnd!=nil {
cndCopy:=cnd.DeepCopy()
cndCopy.ObservedGeneration=ext.GetGeneration()
apimeta.SetStatusCondition(&rs.Conditions, *cndCopy)
}
Suggested change
ifcnd:=apimeta.FindStatusCondition(rs.Conditions, cndType); cnd!=nil {
cnd.ObservedGeneration=ext.GetGeneration()
apimeta.SetStatusCondition(&rs.Conditions, *cnd)
ifcnd:=apimeta.FindStatusCondition(r.Conditions, cndType); cnd!=nil {
cndCopy:=cnd.DeepCopy()
cndCopy.ObservedGeneration=ext.GetGeneration()
apimeta.SetStatusCondition(&rs.Conditions, *cndCopy)

Copilot uses AI. Check for mistakes.
| 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. | | |

CopilotAIDec 10, 2025

Copy link

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.

Suggested change
|`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. |||

Copilot uses AI. Check for mistakes.
… 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.
@dtfranz

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ciopenshift-ciBot added the lgtm Indicates that a PR is ready to be merged. label Dec 10, 2025

@rashmigottipatirashmigottipati left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci

Copy link
Copy Markdown

[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

Details 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

@openshift-merge-bot
openshift-merge-botBot merged commit e4a633e into operator-framework:mainDec 10, 2025
28 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@perdasilva@pedjak@michaelryanpeter@dtfranz@rashmigottipati@tmshort@openshift-merge-robot