Skip to content

Commit 679e4ab

Browse files
authored
✨ add progressing condition (#1302)
* add progressing condition Signed-off-by: everettraven <[email protected]> * cleanup lingering healthy condition reason Signed-off-by: everettraven <[email protected]> --------- Signed-off-by: everettraven <[email protected]>
1 parent 10510d9 commit 679e4ab

7 files changed

+305
-217
lines changed

api/v1alpha1/clusterextension_types.go

+13-10
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ import (
2222
"github.com/operator-framework/operator-controller/internal/conditionsets"
2323
)
2424

25-
var (
26-
ClusterExtensionKind = "ClusterExtension"
27-
)
25+
var ClusterExtensionKind = "ClusterExtension"
2826

29-
type UpgradeConstraintPolicy string
30-
type CRDUpgradeSafetyPolicy string
27+
type (
28+
UpgradeConstraintPolicy string
29+
CRDUpgradeSafetyPolicy string
30+
)
3131

3232
const (
3333
// The extension will only upgrade if the new version satisfies
@@ -412,8 +412,9 @@ type CRDUpgradeSafetyPreflightConfig struct {
412412

413413
const (
414414
// TODO(user): add more Types, here and into init()
415-
TypeInstalled = "Installed"
416-
TypeResolved = "Resolved"
415+
TypeInstalled = "Installed"
416+
TypeResolved = "Resolved"
417+
TypeProgressing = "Progressing"
417418

418419
// TypeDeprecated is a rollup condition that is present when
419420
// any of the deprecated conditions are present.
@@ -426,12 +427,12 @@ const (
426427
ReasonSuccess = "Succeeded"
427428
ReasonDeprecated = "Deprecated"
428429
ReasonFailed = "Failed"
430+
ReasonBlocked = "Blocked"
431+
ReasonRetrying = "Retrying"
429432

430433
ReasonErrorGettingClient = "ErrorGettingClient"
431434
ReasonErrorGettingReleaseState = "ErrorGettingReleaseState"
432435

433-
ReasonUnverifiable = "Unverifiable"
434-
435436
CRDUpgradeSafetyPolicyEnabled CRDUpgradeSafetyPolicy = "Enabled"
436437
CRDUpgradeSafetyPolicyDisabled CRDUpgradeSafetyPolicy = "Disabled"
437438
)
@@ -446,6 +447,7 @@ func init() {
446447
TypeChannelDeprecated,
447448
TypeBundleDeprecated,
448449
TypeUnpacked,
450+
TypeProgressing,
449451
)
450452
// TODO(user): add Reasons from above
451453
conditionsets.ConditionReasons = append(conditionsets.ConditionReasons,
@@ -454,7 +456,8 @@ func init() {
454456
ReasonFailed,
455457
ReasonErrorGettingClient,
456458
ReasonErrorGettingReleaseState,
457-
ReasonUnverifiable,
459+
ReasonBlocked,
460+
ReasonRetrying,
458461
)
459462
}
460463

internal/controllers/clusterextension_controller.go

+26-9
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
201201
setInstallStatus(ext, nil)
202202
setResolutionStatus(ext, nil)
203203
setResolvedStatusConditionFailed(ext, err.Error())
204+
setStatusProgressing(ext, err)
204205
ensureAllConditionsWithReason(ext, ocv1alpha1.ReasonFailed, err.Error())
205206
return ctrl.Result{}, err
206207
}
@@ -216,6 +217,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
216217
setInstallStatus(ext, nil)
217218
// TODO: use Installed=Unknown
218219
setInstalledStatusConditionFailed(ext, err.Error())
220+
setStatusProgressing(ext, err)
219221
return ctrl.Result{}, err
220222
}
221223

@@ -227,6 +229,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
227229
setInstallStatus(ext, nil)
228230
setResolutionStatus(ext, nil)
229231
setResolvedStatusConditionFailed(ext, err.Error())
232+
setStatusProgressing(ext, err)
230233
ensureAllConditionsWithReason(ext, ocv1alpha1.ReasonFailed, err.Error())
231234
return ctrl.Result{}, err
232235
}
@@ -247,8 +250,9 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
247250
// all catalogs?
248251
SetDeprecationStatus(ext, resolvedBundle.Name, resolvedDeprecation)
249252

253+
resolvedBundleMetadata := bundleutil.MetadataFor(resolvedBundle.Name, *resolvedBundleVersion)
250254
resStatus := &ocv1alpha1.ClusterExtensionResolutionStatus{
251-
Bundle: bundleutil.MetadataFor(resolvedBundle.Name, *resolvedBundleVersion),
255+
Bundle: resolvedBundleMetadata,
252256
}
253257
setResolutionStatus(ext, resStatus)
254258
setResolvedStatusConditionSuccess(ext, fmt.Sprintf("resolved to %q", resolvedBundle.Image))
@@ -264,20 +268,18 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
264268
unpackResult, err := r.Unpacker.Unpack(ctx, bundleSource)
265269
if err != nil {
266270
setStatusUnpackFailed(ext, err.Error())
271+
// Wrap the error passed to this with the resolution information until we have successfully
272+
// installed since we intend for the progressing condition to replace the resolved condition
273+
// and will be removing the .status.resolution field from the ClusterExtension status API
274+
setStatusProgressing(ext, wrapErrorWithResolutionInfo(resolvedBundleMetadata, err))
267275
return ctrl.Result{}, err
268276
}
269277

270278
switch unpackResult.State {
271-
case rukpaksource.StatePending:
272-
setStatusUnpackFailed(ext, unpackResult.Message)
273-
ensureAllConditionsWithReason(ext, ocv1alpha1.ReasonFailed, "unpack pending")
274-
return ctrl.Result{}, nil
275279
case rukpaksource.StateUnpacked:
276280
setStatusUnpacked(ext, unpackResult.Message)
277281
default:
278-
setStatusUnpackFailed(ext, "unexpected unpack status")
279-
// We previously exit with a failed status if error is not nil.
280-
return ctrl.Result{}, fmt.Errorf("unexpected unpack status: %v", unpackResult.Message)
282+
panic(fmt.Sprintf("unexpected unpack state %q", unpackResult.State))
281283
}
282284

283285
objLbls := map[string]string{
@@ -304,25 +306,36 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
304306
managedObjs, _, err := r.Applier.Apply(ctx, unpackResult.Bundle, ext, objLbls, storeLbls)
305307
if err != nil {
306308
setInstalledStatusConditionFailed(ext, err.Error())
309+
setStatusProgressing(ext, wrapErrorWithResolutionInfo(resolvedBundleMetadata, err))
307310
return ctrl.Result{}, err
308311
}
309312

310313
installStatus := &ocv1alpha1.ClusterExtensionInstallStatus{
311-
Bundle: bundleutil.MetadataFor(resolvedBundle.Name, *resolvedBundleVersion),
314+
Bundle: resolvedBundleMetadata,
312315
}
313316
setInstallStatus(ext, installStatus)
314317
setInstalledStatusConditionSuccess(ext, fmt.Sprintf("Installed bundle %s successfully", resolvedBundle.Image))
315318

316319
l.V(1).Info("watching managed objects")
317320
cache, err := r.Manager.Get(ctx, ext)
318321
if err != nil {
322+
// No need to wrap error with resolution information here (or beyond) since the
323+
// bundle was successfully installed and the information will be present in
324+
// the .status.installed field
325+
setStatusProgressing(ext, err)
319326
return ctrl.Result{}, err
320327
}
321328

322329
if err := cache.Watch(ctx, r.controller, managedObjs...); err != nil {
330+
setStatusProgressing(ext, err)
323331
return ctrl.Result{}, err
324332
}
325333

334+
// If we made it here, we have successfully reconciled the ClusterExtension
335+
// and have reached the desired state. Since the Progressing status should reflect
336+
// our progress towards the desired state, we also set it when we have reached
337+
// the desired state by providing a nil error value.
338+
setStatusProgressing(ext, nil)
326339
return ctrl.Result{}, nil
327340
}
328341

@@ -438,6 +451,10 @@ func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
438451
return nil
439452
}
440453

454+
func wrapErrorWithResolutionInfo(resolved ocv1alpha1.BundleMetadata, err error) error {
455+
return fmt.Errorf("%w for resolved bundle %q with version %q", err, resolved.Name, resolved.Version)
456+
}
457+
441458
// Generate reconcile requests for all cluster extensions affected by a catalog change
442459
func clusterExtensionRequestsForCatalog(c client.Reader, logger logr.Logger) crhandler.MapFunc {
443460
return func(ctx context.Context, _ client.Object) []reconcile.Request {

0 commit comments

Comments
 (0)