Skip to content

Commit 19b184b

Browse files
pedjakclaude
andcommitted
Replace per-Secret hashing with source-agnostic phase content hashing
Addresses PR review feedback: - Compute SHA-256 hash per resolved phase (name + objects) instead of per-Secret, making immutability verification source-agnostic and futureproof for bundle refs. - Move hash computation after buildBoxcutterPhases succeeds so hashes are only persisted for successfully resolved content. - Remove Blocked reason from skipTerminallyBlockedPredicate so blocked COS can be re-reconciled when the underlying issue is fixed. API: rename ObservedObjectContainer → ObservedPhase, field observedObjectContainers → observedPhases in ClusterObjectSetStatus. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f7217e2 commit 19b184b

File tree

14 files changed

+230
-287
lines changed

14 files changed

+230
-287
lines changed

api/v1/clusterobjectset_types.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -511,26 +511,27 @@ type ClusterObjectSetStatus struct {
511511
// +optional
512512
Conditions []metav1.Condition `json:"conditions,omitempty"`
513513

514-
// observedObjectContainers records the content hashes of referenced Secrets
515-
// at first successful resolution. This is used to detect if a referenced
516-
// Secret was deleted and recreated with different content.
514+
// observedPhases records the content hashes of resolved phases
515+
// at first successful reconciliation. This is used to detect if
516+
// referenced object sources were deleted and recreated with
517+
// different content. Each entry covers all fully-resolved object
518+
// manifests within a phase, making it source-agnostic.
517519
//
518520
// +listType=map
519521
// +listMapKey=name
520522
// +optional
521-
ObservedObjectContainers []ObservedObjectContainer `json:"observedObjectContainers,omitempty"`
523+
ObservedPhases []ObservedPhase `json:"observedPhases,omitempty"`
522524
}
523525

524-
// ObservedObjectContainer records the observed state of a referenced Secret
525-
// used as an object source.
526-
type ObservedObjectContainer struct {
527-
// name identifies the referenced Secret in "namespace/name" format.
526+
// ObservedPhase records the observed content hash of a resolved phase.
527+
type ObservedPhase struct {
528+
// name is the phase name matching a phase in spec.phases.
528529
//
529530
// +required
530531
Name string `json:"name"`
531532

532-
// hash is the hex-encoded SHA-256 hash of the Secret's .data field
533-
// at first successful resolution.
533+
// hash is the hex-encoded SHA-256 hash of the phase's resolved
534+
// object content at first successful reconciliation.
534535
//
535536
// +required
536537
Hash string `json:"hash"`

api/v1/zz_generated.deepcopy.go

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

applyconfigurations/api/v1/clusterobjectsetstatus.go

Lines changed: 11 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

applyconfigurations/api/v1/observedobjectcontainer.go renamed to applyconfigurations/api/v1/observedphase.go

Lines changed: 11 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

applyconfigurations/utils.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/api-reference/olmv1-api-reference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,8 @@ _Appears in:_
477477

478478

479479

480+
481+
480482
#### PreflightConfig
481483

482484

docs/draft/concepts/large-bundle-support.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ Recommended conventions:
151151
that all referenced Secrets have `immutable: true` set before proceeding.
152152
Mutable referenced Secrets are rejected and reconciliation is blocked with
153153
`Progressing=False, Reason=Blocked`. Additionally, the reconciler records
154-
content hashes of referenced Secrets on first resolution and blocks
155-
reconciliation if the content changes (e.g., if a Secret is deleted and
156-
recreated with the same name but different data).
154+
content hashes of the resolved phases on first successful reconciliation
155+
and blocks reconciliation if the content changes (e.g., if a Secret is
156+
deleted and recreated with the same name but different data).
157157

158158
3. **Owner references**: Referenced Secrets should carry an ownerReference to
159159
the COS so that Kubernetes garbage collection removes them when the COS is
@@ -392,12 +392,13 @@ Key properties:
392392
393393
### COS reconciler behavior
394394
395-
Before resolving individual object refs, the reconciler verifies all referenced
396-
Secrets: each must have `immutable: true` set, and its content hash must match
397-
the hash recorded in `.status.observedObjectContainers` (if present). If any Secret
398-
fails verification, reconciliation is blocked with `Progressing=False,
399-
Reason=Blocked`. On first successful verification, content hashes are persisted
400-
to status for future comparisons.
395+
Before resolving individual object refs, the reconciler verifies that all
396+
referenced Secrets have `immutable: true` set. After successfully building
397+
the phases (resolving all refs), the reconciler computes a per-phase content
398+
hash and compares it against the hashes recorded in `.status.observedPhases`
399+
(if present). If any phase's content has changed, reconciliation is blocked
400+
with `Progressing=False, Reason=Blocked`. On first successful build, phase
401+
content hashes are persisted to status for future comparisons.
401402
402403
When processing a COS phase:
403404
- For each object entry in the phase:

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -621,24 +621,24 @@ spec:
621621
x-kubernetes-list-map-keys:
622622
- type
623623
x-kubernetes-list-type: map
624-
observedObjectContainers:
624+
observedPhases:
625625
description: |-
626-
observedObjectContainers records the content hashes of referenced Secrets
627-
at first successful resolution. This is used to detect if a referenced
628-
Secret was deleted and recreated with different content.
626+
observedPhases records the content hashes of resolved phases
627+
at first successful reconciliation. This is used to detect if
628+
referenced object sources were deleted and recreated with
629+
different content. Each entry covers all fully-resolved object
630+
manifests within a phase, making it source-agnostic.
629631
items:
630-
description: |-
631-
ObservedObjectContainer records the observed state of a referenced Secret
632-
used as an object source.
632+
description: ObservedPhase records the observed content hash of
633+
a resolved phase.
633634
properties:
634635
hash:
635636
description: |-
636-
hash is the hex-encoded SHA-256 hash of the Secret's .data field
637-
at first successful resolution.
637+
hash is the hex-encoded SHA-256 hash of the phase's resolved
638+
object content at first successful reconciliation.
638639
type: string
639640
name:
640-
description: name identifies the referenced Secret in "namespace/name"
641-
format.
641+
description: name is the phase name matching a phase in spec.phases.
642642
type: string
643643
required:
644644
- hash

0 commit comments

Comments
 (0)