Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/draft/concepts/clusterobjectsets.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Indicates whether the revision is actively rolling out.
| False | `Blocked` | Error requiring manual intervention |
| False | `Archived` | No longer actively reconciled |

### Available
### Ready
Comment thread
perdasilva marked this conversation as resolved.

Indicates whether all objects have been successfully rolled out and pass readiness probes.

Expand Down Expand Up @@ -387,7 +387,7 @@ kubectl get clusterobjectset <name> -o yaml
Example output:

```
NAME AVAILABLE PROGRESSING AGE
my-extension-abc12 Unknown False 2d
my-extension-def34 True True 1h
NAME READY AGE
my-extension-abc12 Unknown 2d
my-extension-def34 True 1h
```
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl
// Blocked takes precedence over ProgressDeadlineExceeded: it is more actionable for the user.
if err := c.verifyReferencedSecretsImmutable(ctx, cos); err != nil {
l.Error(err, "referenced Secret verification failed, blocking reconciliation")
markAsUnavailable(cos, ocv1.ClusterObjectSetReasonBlocked, err.Error())
markAsNotReady(cos, ocv1.ClusterObjectSetReasonBlocked, err.Error())
return ctrl.Result{}, nil
}

Expand All @@ -148,7 +148,7 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl
cos.Status.ObservedPhases = currentPhases
} else if err := verifyObservedPhases(cos.Status.ObservedPhases, currentPhases); err != nil {
l.Error(err, "resolved phases content changed, blocking reconciliation")
markAsUnavailable(cos, ocv1.ClusterObjectSetReasonBlocked, err.Error())
markAsNotReady(cos, ocv1.ClusterObjectSetReasonBlocked, err.Error())
return ctrl.Result{}, nil
}

Expand All @@ -168,7 +168,7 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl

if cos.Spec.LifecycleState == ocv1.ClusterObjectSetLifecycleStateArchived {
if err := c.TrackingCache.Free(ctx, cos); err != nil {
markAsUnavailable(cos, ocv1.ClusterObjectSetReasonReconciling, err.Error())
markAsNotReady(cos, ocv1.ClusterObjectSetReasonReconciling, err.Error())
return ctrl.Result{}, fmt.Errorf("error stopping informers: %v", err)
}
return c.archive(ctx, revisionEngine, cos, revision)
Expand Down Expand Up @@ -225,7 +225,7 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl

revisionNumber := cos.Spec.Revision
if rres.InTransition() {
setAvailableWithDeadline(cos, metav1.ConditionFalse, ocv1.ReasonRollingOut, fmt.Sprintf("Revision %d is rolling out.", revisionNumber), isDeadlineExceeded)
setReadyWithDeadline(cos, metav1.ConditionFalse, ocv1.ReasonRollingOut, fmt.Sprintf("Revision %d is rolling out.", revisionNumber), isDeadlineExceeded)
}

//nolint:nestif
Expand All @@ -245,7 +245,7 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl
}
}

markAsAvailable(cos, ocv1.ClusterObjectSetReasonProbesSucceeded, "Objects are available and pass all probes.")
markAsReady(cos, ocv1.ClusterObjectSetReasonProbesSucceeded, "Objects are available and pass all probes.")

// Record the timestamp of the first time the revision was observed to be
// ready. This is set once and never changes for subsequent reconciliations.
Expand Down Expand Up @@ -291,11 +291,11 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl
// the "last status", not the per-object probe detail, so the reconstructed
// ClusterExtension Progressing/ProgressDeadlineExceeded message matches the
// message the removed COS Progressing condition historically carried.
setAvailableWithDeadline(cos, metav1.ConditionFalse, ocv1.ReasonRollingOut, rollingOutMsg, true)
setReadyWithDeadline(cos, metav1.ConditionFalse, ocv1.ReasonRollingOut, rollingOutMsg, true)
case len(probeFailureMsgs) > 0:
setAvailableWithDeadline(cos, metav1.ConditionFalse, ocv1.ClusterObjectSetReasonProbeFailure, strings.Join(probeFailureMsgs, "\n"), false)
setReadyWithDeadline(cos, metav1.ConditionFalse, ocv1.ClusterObjectSetReasonProbeFailure, strings.Join(probeFailureMsgs, "\n"), false)
default:
setAvailableWithDeadline(cos, metav1.ConditionFalse, ocv1.ReasonRollingOut, rollingOutMsg, false)
setReadyWithDeadline(cos, metav1.ConditionFalse, ocv1.ReasonRollingOut, rollingOutMsg, false)
}
if hasDeadline && !isDeadlineExceeded {
return ctrl.Result{RequeueAfter: remaining}, nil
Expand All @@ -307,7 +307,7 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl

func (c *ClusterObjectSetReconciler) delete(ctx context.Context, cos *ocv1.ClusterObjectSet) (ctrl.Result, error) {
if err := c.TrackingCache.Free(ctx, cos); err != nil {
markAsUnavailable(cos, ocv1.ClusterObjectSetReasonReconciling, err.Error())
markAsNotReady(cos, ocv1.ClusterObjectSetReasonReconciling, err.Error())
return ctrl.Result{}, fmt.Errorf("error stopping informers: %v", err)
}
if err := c.removeFinalizer(ctx, cos, clusterObjectSetTeardownFinalizer); err != nil {
Expand Down Expand Up @@ -655,13 +655,13 @@ func buildProgressionProbes(progressionProbes []ocv1.ProgressionProbe) (probing.
return userProbes, nil
}

// setAvailableWithDeadline sets the Available condition to the supplied status/reason/message,
// setReadyWithDeadline sets the Ready condition to the supplied status/reason/message,
// unless the progress deadline has been exceeded — in which case it reports
// Available=False/ProgressDeadlineExceeded instead. This centralises the deadline
// Ready=False/ProgressDeadlineExceeded instead. This centralises the deadline
// enforcement that previously lived in markAsProgressing.
func setAvailableWithDeadline(cos *ocv1.ClusterObjectSet, status metav1.ConditionStatus, reason, message string, isDeadlineExceeded bool) { // nolint:unparam
func setReadyWithDeadline(cos *ocv1.ClusterObjectSet, status metav1.ConditionStatus, reason, message string, isDeadlineExceeded bool) { // nolint:unparam
if isDeadlineExceeded {
markAsUnavailable(cos, ocv1.ReasonProgressDeadlineExceeded,
markAsNotReady(cos, ocv1.ReasonProgressDeadlineExceeded,
fmt.Sprintf("Revision has not rolled out for %d minute(s). Last status: %s", cos.Spec.ProgressDeadlineMinutes, message))
return
}
Expand All @@ -675,10 +675,10 @@ func setAvailableWithDeadline(cos *ocv1.ClusterObjectSet, status metav1.Conditio
}

func setRetryingConditions(cos *ocv1.ClusterObjectSet, message string, isDeadlineExceeded bool) {
setAvailableWithDeadline(cos, metav1.ConditionFalse, ocv1.ClusterObjectSetReasonReconciling, message, isDeadlineExceeded)
setReadyWithDeadline(cos, metav1.ConditionFalse, ocv1.ClusterObjectSetReasonReconciling, message, isDeadlineExceeded)
}

func markAsAvailable(cos *ocv1.ClusterObjectSet, reason, message string) bool {
func markAsReady(cos *ocv1.ClusterObjectSet, reason, message string) bool {
return meta.SetStatusCondition(&cos.Status.Conditions, metav1.Condition{
Type: ocv1.ClusterObjectSetTypeReady,
Status: metav1.ConditionTrue,
Expand All @@ -688,7 +688,7 @@ func markAsAvailable(cos *ocv1.ClusterObjectSet, reason, message string) bool {
})
}

func markAsUnavailable(cos *ocv1.ClusterObjectSet, reason, message string) bool {
func markAsNotReady(cos *ocv1.ClusterObjectSet, reason, message string) bool {
return meta.SetStatusCondition(&cos.Status.Conditions, metav1.Condition{
Type: ocv1.ClusterObjectSetTypeReady,
Status: metav1.ConditionFalse,
Expand All @@ -700,7 +700,7 @@ func markAsUnavailable(cos *ocv1.ClusterObjectSet, reason, message string) bool

func markAsArchived(cos *ocv1.ClusterObjectSet) bool {
const msg = "revision is archived"
return markAsUnavailable(cos, ocv1.ClusterObjectSetReasonArchived, msg)
return markAsNotReady(cos, ocv1.ClusterObjectSetReasonArchived, msg)
}

// computePhaseDigest computes a deterministic SHA-256 digest of a phase's
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
},
},
{
name: "Available condition is set to False/Reconciling on error when not previously set",
name: "Ready condition is set to False/Reconciling on error when not previously set",
reconcilingRevisionName: clusterObjectSetName,
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{}),
revisionReconcileErr: errors.New("some error"),
Expand All @@ -92,7 +92,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
},
},
{
name: "Available condition is set to False/Reconciling on error when previously set",
name: "Ready condition is set to False/Reconciling on error when previously set",
reconcilingRevisionName: clusterObjectSetName,
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{}),
revisionReconcileErr: errors.New("some error"),
Expand Down Expand Up @@ -124,8 +124,8 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
},
{
// A revision whose FIRST reconcile fails at engine creation (factory error)
// must set Available=False/Reconciling even though Available did not previously exist.
name: "Available condition is set to False/Reconciling on factory error when not previously set",
// must set Ready=False/Reconciling even though Ready did not previously exist.
name: "Ready condition is set to False/Reconciling on factory error when not previously set",
reconcilingRevisionName: clusterObjectSetName,
factoryErr: errors.New("failed to create revision engine"),
existingObjs: func() []client.Object {
Expand All @@ -147,7 +147,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
},
},
{
name: "set Available:False:RollingOut status condition during rollout when no probe failures are detected",
name: "set Ready:False:RollingOut status condition during rollout when no probe failures are detected",
reconcilingRevisionName: clusterObjectSetName,
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{}),
existingObjs: func() []client.Object {
Expand All @@ -170,7 +170,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
},
},
{
name: "set Available:False:ProbeFailure condition when probe failures are detected and revision is in transition",
name: "set Ready:False:ProbeFailure condition when probe failures are detected and revision is in transition",
reconcilingRevisionName: clusterObjectSetName,
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{
inTransition: true,
Expand Down Expand Up @@ -258,7 +258,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
},
},
{
name: "set Available:False:ProbeFailure condition when probe failures are detected and revision is not in transition",
name: "set Ready:False:ProbeFailure condition when probe failures are detected and revision is not in transition",
reconcilingRevisionName: clusterObjectSetName,
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{
inTransition: false,
Expand Down Expand Up @@ -346,7 +346,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
},
},
{
name: "set Available:False:RollingOut condition while revision is transitioning",
name: "set Ready:False:RollingOut condition while revision is transitioning",
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{
inTransition: true,
}),
Expand All @@ -371,7 +371,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_RevisionReconciliation(t *testing
},
},
{
name: "set Available:True:ProbesSucceeded condition and completedAt on successful revision rollout",
name: "set Ready:True:ProbesSucceeded condition and completedAt on successful revision rollout",
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{
isComplete: true,
}),
Expand Down Expand Up @@ -729,7 +729,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_ArchivalAndDeletion(t *testing.T)
},
},
{
name: "set Available:False:Reconciling when tracking cache free fails during deletion",
name: "set Ready:False:Reconciling when tracking cache free fails during deletion",
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{}),
existingObjs: func() []client.Object {
ext := newTestClusterExtension()
Expand Down Expand Up @@ -761,7 +761,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_ArchivalAndDeletion(t *testing.T)
},
},
{
name: "set Available:False:Archived condition when a revision is archived",
name: "set Ready:False:Archived condition when a revision is archived",
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{}),
existingObjs: func() []client.Object {
ext := newTestClusterExtension()
Expand Down Expand Up @@ -794,7 +794,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_ArchivalAndDeletion(t *testing.T)
},
},
{
name: "set Available:False:Reconciling and requeue when archived revision archival is incomplete",
name: "set Ready:False:Reconciling and requeue when archived revision archival is incomplete",
revisionResult: newMockRevisionResult(mockCtrl, revisionResultConfig{}),
existingObjs: func() []client.Object {
ext := newTestClusterExtension()
Expand Down Expand Up @@ -993,7 +993,7 @@ func Test_ClusterObjectSetReconciler_Reconcile_ProgressDeadline(t *testing.T) {
clock clock.Clock
}{
{
name: "available set to false/ProgressDeadlineExceeded when progress deadline is exceeded",
name: "Ready set to false/ProgressDeadlineExceeded when progress deadline is exceeded",
existingObjs: func() []client.Object {
ext := newTestClusterExtension()
rev1 := newTestClusterObjectSet(t, clusterObjectSetName, ext, testScheme)
Expand All @@ -1019,8 +1019,8 @@ func Test_ClusterObjectSetReconciler_Reconcile_ProgressDeadline(t *testing.T) {
},
{
// A rolling revision with failing probes AND an exceeded progress deadline must
// set Available=False/ProgressDeadlineExceeded (deadline wins over ProbeFailure).
name: "available set to false/ProgressDeadlineExceeded when deadline is exceeded during probe failure (deadline wins over ProbeFailure)",
// set Ready=False/ProgressDeadlineExceeded (deadline wins over ProbeFailure).
name: "Ready set to false/ProgressDeadlineExceeded when deadline is exceeded during probe failure (deadline wins over ProbeFailure)",
existingObjs: func() []client.Object {
ext := newTestClusterExtension()
rev1 := newTestClusterObjectSet(t, clusterObjectSetName, ext, testScheme)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func TestApplyBundleWithBoxcutter(t *testing.T) {
},
},
{
name: "rolling revision without Available resets stale Progressing to RollingOut default",
name: "rolling revision without Ready resets stale Progressing to RollingOut default",
args: args{
activeRevisions: []ocv1.RevisionStatus{
{Name: "ce-1"},
Expand All @@ -128,7 +128,7 @@ func TestApplyBundleWithBoxcutter(t *testing.T) {
revisionStates: &RevisionStates{
RollingOut: []*RevisionMetadata{
// Freshly created revision that has not reconciled yet:
// it has no Available condition.
// it has no Ready condition.
{RevisionName: "ce-1"},
},
},
Expand Down
Loading
Loading