Skip to content

Commit 3a90769

Browse files
Per G. da Silvaclaude
andcommitted
✨ rename ClusterObjectSet Ready reason to AllObjectsReady; decouple ClusterExtension Available
Rename the ClusterObjectSet Ready condition's success reason from ProbesSucceeded to AllObjectsReady, with an updated message ("All objects are at the desired state"). The reason now describes the observed outcome rather than the probing mechanism. Decouple the ClusterExtension Available condition from the revision-level Ready condition: availableFromReady() re-emits the ready (True) state with a ClusterExtension-owned reason (ReasonProbesSucceeded) and a stable message, so rewording the ClusterObjectSet Ready condition no longer alters the ClusterExtension API surface. Update CRD docs, apply configurations, manifests, and tests accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent cf15063 commit 3a90769

16 files changed

Lines changed: 63 additions & 44 deletions

File tree

‎api/v1/clusterobjectset_types.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ const (
3232
ClusterObjectSetReasonArchived = "Archived"
3333
ClusterObjectSetReasonBlocked = "Blocked"
3434
ClusterObjectSetReasonProbeFailure = "ProbeFailure"
35-
ClusterObjectSetReasonProbesSucceeded = "ProbesSucceeded"
3635
ClusterObjectSetReasonRetryableError = "RetryableError"
36+
ClusterObjectSetReasonAllObjectsReady = "AllObjectsReady"
3737
)
3838

3939
// ClusterObjectSetSpec defines the desired state of ClusterObjectSet.
@@ -497,7 +497,7 @@ type ClusterObjectSetStatus struct {
497497
// True means all objects are at the desired state; False means one or more
498498
// objects are not at the desired state; Unknown is the initial state, before
499499
// the first reconciliation has evaluated the revision.
500-
// - True with reason ProbesSucceeded: the revision has rolled out and all objects pass their readiness probes.
500+
// - True with reason AllObjectsReady: the revision has rolled out and all objects are at the desired state.
501501
// - False with reason ProbeFailure: one or more objects are failing their readiness probes during rollout.
502502
// - False with reason RollingOut: the revision is actively rolling out and has not yet become ready.
503503
// - False with reason Blocked: the revision has encountered an error that requires manual intervention for recovery.

‎api/v1/common_types.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ const (
2727
// Installed reasons
2828
ReasonAbsent = "Absent"
2929

30+
// Available reasons
31+
ReasonProbesSucceeded = "ProbesSucceeded"
32+
3033
// Progressing reasons
3134
ReasonRollingOut = "RollingOut"
3235
ReasonRetrying = "Retrying"

‎applyconfigurations/api/v1/clusterobjectsetstatus.go‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎cmd/object-controller/main_test.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ func TestStandaloneController(t *testing.T) {
127127
return
128128
}
129129
assert.False(collect, cos.Status.CompletedAt.IsZero(), "completedAt should be set after rollout; conditions: %v", cos.Status.Conditions)
130-
available := meta.FindStatusCondition(cos.Status.Conditions, ocv1.ClusterObjectSetTypeReady)
131-
if assert.NotNil(collect, available) {
132-
assert.Equal(collect, metav1.ConditionTrue, available.Status)
133-
assert.Equal(collect, ocv1.ClusterObjectSetReasonProbesSucceeded, available.Reason)
130+
ready := meta.FindStatusCondition(cos.Status.Conditions, ocv1.ClusterObjectSetTypeReady)
131+
if assert.NotNil(collect, ready) {
132+
assert.Equal(collect, metav1.ConditionTrue, ready.Status)
133+
assert.Equal(collect, ocv1.ClusterObjectSetReasonAllObjectsReady, ready.Reason)
134134
}
135135
}, time.Minute, 100*time.Millisecond)
136136
cm := &corev1.ConfigMap{}

‎docs/draft/concepts/clusterobjectsets.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,11 @@ Indicates whether the revision is actively rolling out.
169169

170170
### Ready
171171

172-
Indicates whether all objects have been successfully rolled out and pass readiness probes.
172+
Indicates whether all objects in the revision have been successfully rolled out and reached their desired state.
173173

174174
| Status | Reason | Meaning |
175175
| --- | --- | --- |
176-
| True | `ProbesSucceeded` | All objects pass readiness probes |
176+
| True | `AllObjectsReady` | All objects are at the desired state |
177177
| False | `ProbeFailure` | One or more probes failing |
178178
| Unknown | `RetryableError` | Error prevented probe observation |
179179
| Unknown | `Archived` | Objects torn down after archival |

‎helm/olmv1/base/object-controller/crd/experimental/olm.operatorframework.io_clusterobjectsets.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ spec:
558558
True means all objects are at the desired state; False means one or more
559559
objects are not at the desired state; Unknown is the initial state, before
560560
the first reconciliation has evaluated the revision.
561-
- True with reason ProbesSucceeded: the revision has rolled out and all objects pass their readiness probes.
561+
- True with reason AllObjectsReady: the revision has rolled out and all objects are at the desired state.
562562
- False with reason ProbeFailure: one or more objects are failing their readiness probes during rollout.
563563
- False with reason RollingOut: the revision is actively rolling out and has not yet become ready.
564564
- False with reason Blocked: the revision has encountered an error that requires manual intervention for recovery.

‎internal/object-controller/controllers/clusterobjectset_controller.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl
245245
}
246246
}
247247

248-
markAsReady(cos, ocv1.ClusterObjectSetReasonProbesSucceeded, "Objects are available and pass all probes.")
248+
markAsReady(cos, ocv1.ClusterObjectSetReasonAllObjectsReady, "All objects are at the desired state")
249249

250250
// Record the timestamp of the first time the revision was observed to be
251251
// ready. This is set once and never changes for subsequent reconciliations.

‎internal/object-controller/controllers/clusterobjectset_controller_test.go‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
102102
meta.SetStatusCondition(&rev1.Status.Conditions, metav1.Condition{
103103
Type: ocv1.ClusterObjectSetTypeReady,
104104
Status: metav1.ConditionTrue,
105-
Reason: ocv1.ClusterObjectSetReasonProbesSucceeded,
105+
Reason: ocv1.ClusterObjectSetReasonAllObjectsReady,
106106
Message: "Revision 1 is rolled out.",
107107
ObservedGeneration: 1,
108108
})
@@ -371,7 +371,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
371371
},
372372
},
373373
{
374-
name: "set Ready:True:ProbesSucceeded condition and completedAt on successful revision rollout",
374+
name: "set Ready:True:AllObjectsReady condition and completedAt on successful revision rollout",
375375
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{
376376
isComplete: true,
377377
}),
@@ -390,8 +390,8 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
390390
cond := meta.FindStatusCondition(rev.Status.Conditions, ocv1.ClusterObjectSetTypeReady)
391391
require.NotNil(t, cond)
392392
require.Equal(t, metav1.ConditionTrue, cond.Status)
393-
require.Equal(t, ocv1.ClusterObjectSetReasonProbesSucceeded, cond.Reason)
394-
require.Equal(t, "Objects are available and pass all probes.", cond.Message)
393+
require.Equal(t, ocv1.ClusterObjectSetReasonAllObjectsReady, cond.Reason)
394+
require.Equal(t, "All objects are at the desired state", cond.Message)
395395
require.Equal(t, int64(1), cond.ObservedGeneration)
396396

397397
require.False(t, rev.Status.CompletedAt.IsZero(), "completedAt should be set on successful rollout")
@@ -1102,7 +1102,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_ProgressDeadline(t *testing.T) {
11021102
},
11031103
},
11041104
{
1105-
name: "recovery from ProgressDeadlineExceeded to ProbesSucceeded when revision completes",
1105+
name: "recovery from ProgressDeadlineExceeded to AllObjectsReady when revision completes",
11061106
existingObjs: func() []client.Object {
11071107
ext := newTestClusterExtension()
11081108
rev1 := newTestClusterObjectSet(t, clusterObjectSetName, ext, testScheme)
@@ -1130,8 +1130,8 @@ func Test_ClusterObjectSetReconciler_Reconcile_ProgressDeadline(t *testing.T) {
11301130
cnd := meta.FindStatusCondition(rev.Status.Conditions, ocv1.ClusterObjectSetTypeReady)
11311131
require.NotNil(t, cnd)
11321132
require.Equal(t, metav1.ConditionTrue, cnd.Status)
1133-
require.Equal(t, ocv1.ClusterObjectSetReasonProbesSucceeded, cnd.Reason)
1134-
require.Equal(t, "Objects are available and pass all probes.", cnd.Message)
1133+
require.Equal(t, ocv1.ClusterObjectSetReasonAllObjectsReady, cnd.Reason)
1134+
require.Equal(t, "All objects are at the desired state", cnd.Message)
11351135
},
11361136
},
11371137
{
@@ -1144,7 +1144,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_ProgressDeadline(t *testing.T) {
11441144
meta.SetStatusCondition(&rev1.Status.Conditions, metav1.Condition{
11451145
Type: ocv1.ClusterObjectSetTypeReady,
11461146
Status: metav1.ConditionTrue,
1147-
Reason: ocv1.ClusterObjectSetReasonProbesSucceeded,
1147+
Reason: ocv1.ClusterObjectSetReasonAllObjectsReady,
11481148
ObservedGeneration: rev1.Generation,
11491149
})
11501150
rev1.Status.CompletedAt = metav1.Now()

‎internal/operator-controller/conditionsets/conditionsets.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ var ConditionReasons = []string{
4646
ocv1.ReasonAbsent,
4747
ocv1.ReasonRollingOut,
4848
ocv1.ReasonProgressDeadlineExceeded,
49+
ocv1.ReasonProbesSucceeded,
4950
}

‎internal/operator-controller/controllers/common_controller.go‎

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,25 @@ func setInstalledStatusFromRevisionStates(ext *ocv1.ClusterExtension, revisionSt
6969
setInstalledStatusConditionSuccess(ext, fmt.Sprintf("Installed bundle %s successfully", revisionStates.Installed.Image))
7070
}
7171

72+
// availableTrueMessage is the message surfaced on the ClusterExtension Available condition when the
73+
// active revision is Ready. It is intentionally decoupled from the ClusterObjectSet Ready condition's
74+
// own message.
75+
const availableTrueMessage = "Objects are available and pass all probes."
76+
77+
// availableFromReady maps a ClusterObjectSet Ready condition onto a ClusterExtension Available condition.
78+
// Non-ready states are surfaced as-is (only the Type is rewritten to Available). The ready (True) state is
79+
// re-emitted with a ClusterExtension-owned reason and message.
80+
func availableFromReady(ready metav1.Condition, generation int64) metav1.Condition {
81+
a := ready
82+
a.Type = ocv1.TypeAvailable
83+
a.ObservedGeneration = generation
84+
if a.Status == metav1.ConditionTrue {
85+
a.Reason = ocv1.ReasonProbesSucceeded
86+
a.Message = availableTrueMessage
87+
}
88+
return a
89+
}
90+
7291
// setActiveRevisionsFromRevisionStates derives the active revisions for the ClusterExtension status
7392
func setActiveRevisionsFromRevisionStates(ext *ocv1.ClusterExtension, revisionStates *RevisionStates) {
7493
ext.Status.ActiveRevisions = make([]ocv1.RevisionStatus, 0, 1+len(revisionStates.RollingOut))
@@ -79,10 +98,7 @@ func setActiveRevisionsFromRevisionStates(ext *ocv1.ClusterExtension, revisionSt
7998
rs := ocv1.RevisionStatus{Name: r.RevisionName}
8099
ready := apimeta.FindStatusCondition(r.Conditions, ocv1.ClusterObjectSetTypeReady)
81100
if ready != nil {
82-
a := *ready
83-
a.Type = ocv1.TypeAvailable
84-
a.ObservedGeneration = ext.GetGeneration()
85-
apimeta.SetStatusCondition(&rs.Conditions, a)
101+
apimeta.SetStatusCondition(&rs.Conditions, availableFromReady(*ready, ext.GetGeneration()))
86102
}
87103
ext.Status.ActiveRevisions = append(ext.Status.ActiveRevisions, rs)
88104
}
@@ -93,10 +109,7 @@ func setAvailableFromRevisionStates(ext *ocv1.ClusterExtension, revisionStates *
93109
if i := revisionStates.Installed; i != nil {
94110
ready := apimeta.FindStatusCondition(i.Conditions, ocv1.ClusterObjectSetTypeReady)
95111
if ready != nil {
96-
a := *ready
97-
a.Type = ocv1.TypeAvailable
98-
a.ObservedGeneration = ext.GetGeneration()
99-
apimeta.SetStatusCondition(&ext.Status.Conditions, a)
112+
apimeta.SetStatusCondition(&ext.Status.Conditions, availableFromReady(*ready, ext.GetGeneration()))
100113
}
101114
}
102115
}
@@ -261,7 +274,7 @@ func progressingFromReady(ready *metav1.Condition, completed bool) metav1.Condit
261274
case ocv1.ClusterObjectSetReasonRetryableError:
262275
cond.Reason = ocv1.ReasonRetrying
263276
default:
264-
// ProbeFailure, RollingOut, or ProbesSucceeded-but-not-yet-complete.
277+
// ProbeFailure, RollingOut, or AllObjectsReady-but-not-yet-complete.
265278
cond.Reason = ocv1.ReasonRollingOut
266279
}
267280
return cond

0 commit comments

Comments
 (0)