Skip to content

⚠️ Refine ClusterExtentionRevision conditions - #2340

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

⚠️ Refine ClusterExtentionRevision conditions#2340
openshift-merge-bot[bot] merged 1 commit into
operator-framework:mainfrom
perdasilva:cer-conditions

Conversation

@perdasilva

@perdasilvaperdasilva commented Nov 18, 2025

Copy link
Copy Markdown
Contributor

Description

Summary

This PR refactors the ClusterExtensionRevision status conditions to provide clearer, more actionable feedback about revision lifecycle states. The changes introduce a new Progressing condition, simplify condition reasons, and ensure that revision-level errors (retrying states) are properly surfaced to the parent ClusterExtension.

This PR does introduce API breaking changes. But, only to experimental APIs. It should be ok to override.

Key Changes

  1. Refactored ClusterExtensionRevision Status Conditions

Simplified condition types:

  • Retained Available and Succeeded conditions
  • Added new Progressing condition for better visibility into rollout state
  • Removed obsolete condition reasons and consolidated error handling

Updated condition reasons to be more semantic and actionable:

  • Before: ReconcileFailure, RevisionValidationFailure, PhaseValidationError, ObjectCollisions, RolloutSuccess, Incomplete, Progressing
  • After: Retrying, Blocked, RollingOut, Archived, Migrated

API Changes:

  • Added Progressing column to kubectl get clusterextensionrevisions output
  1. Surfaced Revision Retrying Condition to ClusterExtension

Modified the Boxcutter applier to propagate retrying errors from ClusterExtensionRevision to the parent ClusterExtension. When a revision is in a Progressing=True state with Reason=Retrying, the error is now surfaced to the ClusterExtension, providing better visibility into failed reconciliation attempts. When the revision is Progressing=True/Succeeded the applier returns success.

  1. Added Comprehensive E2E Tests

Added end-to-end tests for ClusterExtensionRevision lifecycle scenarios to validate the new condition states and transitions.

  1. Added ClusterExtension documentation to the RolloutInProgress Progression reason

ClusterExtension Status Conditions

Progressing Condition (experimental only)

StatusReasonDescription
TrueRollingOutThe latest active revision is rolling out

ClusterExtensionRevision Status Conditions

Progressing Condition

Indicates whether the revision is progressing to its next state. It follows the same semantic as the ClusterExtension and Deployment Progressing condition.

StatusReasonDescription
TrueRetryingReconciliation failed due to validation errors, object collisions, or other recoverable errors; will retry
TrueRollingOutRevision is actively rolling out objects across phases
TrueSucceededRevision has completed its rollout successfully
FalseBlockedRevision reconciliation failed with unrecoverable error - manual intervention might be required
FalseArchivedRevision has been archived and is no longer progressing

Not a part of this PR yet, but Progressing can also be Blocked for non-retryable errors.

Available Condition

Indicates whether the revision's objects are available and passing the object status probes.

StatusReasonDescription
TrueProbesSuceededObjects are available and pass all probes
FalseProbeFailedOne or more objects are failing their availability probes
UnknownReconcilingProbes could not be observed / intermittent reconciliation error
UnknownArchivedRevision is archived
UnknownMigratedRevision was migrated from Helm release

Succeeded Condition

Indicates whether the revision has successfully completed its rollout.

StatusReasonDescription
TrueSucceededRevision succeeded rolling out all objects and passed all probes

Migration Notes

  • The Progressing condition replaces the previous pattern of setting Available=False with various failure reasons
  • All retrying scenarios (validation failures, collisions, reconcile errors) now consistently set Progressing=True, Reason=Retrying and Available=Unknown
  • The new condition structure provides clearer separation between "something is wrong" (Progressing=Retrying) vs "rollout is in progress" (Progressing=RollingOut)

Reviewer Checklist

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

@perdasilva
perdasilva requested a review from a team as a code ownerNovember 18, 2025 12:39
CopilotAI review requested due to automatic review settings November 18, 2025 12:39
@netlify

netlifyBot commented Nov 18, 2025

Copy link
Copy Markdown

Deploy Preview for olmv1 ready!

NameLink
🔨 Latest commit04de603
🔍 Latest deploy loghttps://app.netlify.com/projects/olmv1/deploys/692eb12b817d0b000844e6b8
😎 Deploy Previewhttps://deploy-preview-2340--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
perdasilva marked this pull request as draft November 18, 2025 12:40
@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 Nov 18, 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

This PR refactors the ClusterExtensionRevision conditions system to better distinguish between availability and progression states. The changes introduce a new "Progressing" condition type and update condition reasons to be more descriptive of the revision lifecycle states.

Key changes:

  • Introduces Progressing condition type alongside refactored Available and Succeeded conditions
  • Replaces generic condition reasons with specific lifecycle states (e.g., RollingOut, RolledOut, Retrying, ProbesSucceeded)
  • Adds comprehensive E2E tests for ClusterExtensionRevision condition behavior
  • Removes enum validation for CollisionProtection field in CRDs

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
api/v1/clusterextensionrevision_types.goRefactors condition type constants and adds Progressing type, updates condition reason constants to reflect specific lifecycle states
internal/operator-controller/controllers/clusterextensionrevision_controller.goImplements condition setting logic with new helper functions and updates reconciliation flow to properly set Progressing/Available conditions
internal/operator-controller/controllers/clusterextensionrevision_controller_test.goUpdates unit tests to validate new condition reasons and adds test coverage for error scenarios
internal/operator-controller/applier/boxcutter.goAdds handling for Retrying reason in progressing condition
test/e2e/cluster_extension_revision_test.goAdds comprehensive E2E test covering revision conditions, availability probes, and archiving
test/e2e/e2e_suite_test.goAdds Kubernetes clientset for pod exec operations in E2E tests
manifests/experimental.yaml, manifests/experimental-e2e.yaml, helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensionrevisions.yamlAdds Progressing column to kubectl output and removes CollisionProtection enum validation

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

@perdasilvaperdasilva changed the title :sparking: ClusterExtentionRevision conditions✨ ClusterExtentionRevision conditionsNov 18, 2025
@openshift-merge-robotopenshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 18, 2025
CopilotAI review requested due to automatic review settings November 18, 2025 18:24

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 9 out of 9 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 threadapi/v1/clusterextensionrevision_types.go
Comment threadtest/e2e/cluster_extension_revision_test.go
@openshift-merge-robotopenshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 18, 2025
@codecov

codecovBot commented Nov 18, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.54430% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.04%. Comparing base (b23e124) to head (04de603).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
internal/operator-controller/applier/boxcutter.go0.00%7 Missing ⚠️
...controllers/clusterextensionrevision_controller.go92.95%5 Missing ⚠️
...er/controllers/clusterextension_reconcile_steps.go0.00%1 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #2340 +/- ##
==========================================
+ Coverage 70.58% 71.04% +0.45% 
==========================================
Files 93 93 Lines 7333 7294 -39 ==========================================
+ Hits 5176 5182 +6 + Misses 1721 1680 -41 + Partials 436 432 -4 
FlagCoverage Δ
e2e44.84% <0.00%> (+0.36%)⬆️
experimental-e2e14.14% <0.00%> (?)
unit58.97% <83.54%> (+0.36%)⬆️

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.

@perdasilvaperdasilva changed the title ✨ ClusterExtentionRevision conditions⚠️ ClusterExtentionRevision conditionsNov 19, 2025
CopilotAI review requested due to automatic review settings November 19, 2025 15:01

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 9 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

internal/operator-controller/controllers/clusterextensionrevision_controller_test.go:915

  • Corrected spelling of 'InTransistion' to 'InTransition'.
func (m mockRevisionResult) InTransistion() bool {

internal/operator-controller/controllers/clusterextensionrevision_controller_test.go:953

  • Corrected spelling of 'InTransistion' to 'InTransition'.
func (m mockPhaseResult) InTransistion() bool {

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

CopilotAI review requested due to automatic review settings November 19, 2025 15:26

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 18 out of 18 changed files in this pull request and generated no new comments.


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

@openshift-merge-robotopenshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 25, 2025
@openshift-merge-robotopenshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 28, 2025
CopilotAI review requested due to automatic review settings November 28, 2025 09:48

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 15 out of 15 changed files in this pull request and generated no new comments.


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

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

please update/extend PR title to summarize what this PR is about.

Comment threadapi/v1/clusterextension_types.go
Comment threadapi/v1/clusterextensionrevision_types.go
Comment threadapi/v1/clusterextensionrevision_types.go Outdated
Comment threadinternal/operator-controller/applier/boxcutter.go
if err != nil {
if rres != nil {
l.Error(err, "revision reconcile failed")
l.V(1).Info("reconcile failure report", "report", rres.String())

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.

In case of error I think it would still very useful to log et error level, assuming that errors are happening occasionally.

Comment threadtest/e2e/cluster_extension_revision_test.go

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

Given that I am PR co-author, I would prefer that some else gives lgtm

//
// The Succeeded condition represents whether the revision has successfully completed its rollout:
// - When status is True and reason is RolloutSuccess, the revision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable.
// - When status is True and reason is RolloutSuccess, the ClusterExtensionRevision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable.

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.

I'm not seeing RolloutSuccess as a valid reason (it was removed)

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.

Good catch

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.

Fixed

// - When Progressing is not present, the revision is not currently in transition.
// - When status is True and reason is RollingOut, the ClusterExtensionRevision rollout is actively making progress and is in transition.
// - When status is True and reason is Retrying, the ClusterExtensionRevision has encountered an error that could be resolved on subsequent reconciliation attempts.
// - When status is True and reason is Succeeded, the ClusterExtensionRevision has reached the desired state.

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.

I don't see Succeeded as a reason (There's ProbesSucceeded, but it's not the same)

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.

// The Progressing condition represents whether the revision is actively rolling out:
// - When status is True and reason is Progressing, the revision rollout is actively making progress and is in transition.
// - When Progressing is not present, the revision is not currently in transition.
// - When status is True and reason is RollingOut, the ClusterExtensionRevision rollout is actively making progress and is in transition.

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.

I don't see RollingOut as a reason.

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.

//
// Reconcile
//
if err := c.ensureFinalizer(ctx, rev, clusterExtensionRevisionTeardownFinalizer); err != nil {

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.

Status update was removed here? Is that on purpose?

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.

We felt that it was unnecessary as the errors should be rare and short lived...

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.

We felt that it was unnecessary as the errors should be rare and short lived...

Yes, if there is an error at adding finalizer (sending API request), there is very high chance that updating the status is also going to fail. Hoping that the issue is short-lived/transient, we just retry without bugging user about it.

func markAsArchived(cer *ocv1.ClusterExtensionRevision) bool {
const msg = "revision is archived"
updated := markAsNotProgressing(cer, ocv1.ClusterExtensionRevisionReasonArchived, msg)
return markAsAvailableUnknown(cer, ocv1.ClusterExtensionRevisionReasonArchived, msg) || updated

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.

This feels like it ought to be "Unavailable" rather than "Unknown"? Is there a reason for the distinction here?

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.

I'm wondering if we'll remove it all together in a follow-up. The reason for it being unknown is that there are situation in which it could be considered to be available. If rev-2 is rev-1 + some random resource, its possible that rev-1 could be available.

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 15 out of 15 changed files in this pull request and generated 7 comments.


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

Comment threadmanifests/experimental.yaml Outdated
Comment threadapi/v1/clusterextensionrevision_types.go Outdated
Comment threadmanifests/experimental-e2e.yaml Outdated
Co-authored-by: Per Goncalves da Silva <pegoncal@redhat.com>
Co-authored-by: Predrag Knezevic <pknezevi@redhat.com
Signed-off-by: Per Goncalves da Silva <pegoncal@redhat.com>
@dtfranz

Copy link
Copy Markdown
Contributor

/lgtm

@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

@pedjak

Copy link
Copy Markdown
Contributor

/approve

@openshift-ci

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: pedjak, 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

@perdasilva

Copy link
Copy Markdown
ContributorAuthor

/override go-apidiff/go-apidiff

@openshift-ci

Copy link
Copy Markdown

@perdasilva: /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
  • experimental-e2e
  • extension-developer-e2e
  • go-apidiff
  • go-verdiff
  • goreleaser
  • lint
  • netlify/olmv1/deploy-preview
  • st2ex-e2e
  • tide
  • unit-test-basic
  • upgrade-st2st-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.

Details

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.

@perdasilva

Copy link
Copy Markdown
ContributorAuthor

/override go-apidiff

@openshift-ci

Copy link
Copy Markdown

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

Details

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.

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.

9 participants

@perdasilva@dtfranz@pedjak@anik120@rashmigottipati@camilamacedo86@tmshort@openshift-merge-robot