Skip to content

Commit 4b35f42

Browse files
fix(Boxcutter): Re-resolve bundle when rollout is stuck
Implements catalog spec digest tracking to detect spec changes during stuck rollouts, enabling recovery by updating the ClusterExtension spec. **Problem**: When a ClusterExtension rollout gets stuck (e.g., bad image causing probe failures), updating the spec to a different version doesn't trigger re-resolution. The controller reuses the stuck revision indefinitely. **Solution**: Track a digest of resolution-relevant spec fields (packageName, version, channels, selector, upgradeConstraintPolicy) in ClusterObjectSet annotations. When spec changes during rollout, detect digest mismatch and trigger re-resolution to create a new revision. Generated-by: Claude
1 parent afa2e7a commit 4b35f42

9 files changed

Lines changed: 1395 additions & 72 deletions

File tree

internal/operator-controller/controllers/boxcutter_reconcile_steps.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ func (d *BoxcutterRevisionStatesGetter) GetRevisionStates(ctx context.Context, e
6262
// is fairly decoupled from this code where we get the annotations back out. We may want to co-locate
6363
// the set/get logic a bit better to make it more maintainable and less likely to get out of sync.
6464
rm := &RevisionMetadata{
65-
RevisionName: rev.Name,
66-
Package: rev.Annotations[labels.PackageNameKey],
67-
Image: rev.Annotations[labels.BundleReferenceKey],
68-
Conditions: rev.Status.Conditions,
65+
RevisionName: rev.Name,
66+
Package: rev.Annotations[labels.PackageNameKey],
67+
Image: rev.Annotations[labels.BundleReferenceKey],
68+
CatalogSpecDigest: rev.Annotations[labels.CatalogSpecDigestKey],
69+
Conditions: rev.Status.Conditions,
6970
BundleMetadata: ocv1.BundleMetadata{
7071
Name: rev.Annotations[labels.BundleNameKey],
7172
Version: rev.Annotations[labels.BundleVersionKey],
@@ -104,10 +105,11 @@ func ApplyBundleWithBoxcutter(apply func(ctx context.Context, contentFS fs.FS, e
104105
return func(ctx context.Context, state *reconcileState, ext *ocv1.ClusterExtension) (*ctrl.Result, error) {
105106
l := log.FromContext(ctx)
106107
revisionAnnotations := map[string]string{
107-
labels.BundleNameKey: state.resolvedRevisionMetadata.Name,
108-
labels.PackageNameKey: state.resolvedRevisionMetadata.Package,
109-
labels.BundleVersionKey: state.resolvedRevisionMetadata.Version,
110-
labels.BundleReferenceKey: state.resolvedRevisionMetadata.Image,
108+
labels.BundleNameKey: state.resolvedRevisionMetadata.Name,
109+
labels.PackageNameKey: state.resolvedRevisionMetadata.Package,
110+
labels.BundleVersionKey: state.resolvedRevisionMetadata.Version,
111+
labels.BundleReferenceKey: state.resolvedRevisionMetadata.Image,
112+
labels.CatalogSpecDigestKey: CatalogSpecDigest(ext),
111113
}
112114
if state.resolvedRevisionMetadata.Release != nil {
113115
revisionAnnotations[labels.BundleReleaseKey] = *state.resolvedRevisionMetadata.Release

internal/operator-controller/controllers/clusterextension_controller.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -499,9 +499,10 @@ func clusterExtensionRequestsForCatalog(c client.Reader, logger logr.Logger) crh
499499
}
500500

501501
type RevisionMetadata struct {
502-
RevisionName string
503-
Package string
504-
Image string
502+
RevisionName string
503+
Package string
504+
Image string
505+
CatalogSpecDigest string
505506
ocv1.BundleMetadata
506507
Conditions []metav1.Condition
507508
}

0 commit comments

Comments
 (0)