Skip to content
Open
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
25 changes: 25 additions & 0 deletions api/v1/clusterobjectset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,31 @@ type ClusterObjectSetStatus struct {
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// observedPhases records the content hashes of resolved phases
// at first successful reconciliation. This is used to detect if
// referenced object sources were deleted and recreated with
// different content. Each entry covers all fully-resolved object
// manifests within a phase, making it source-agnostic.
//
// +listType=map
// +listMapKey=name
// +optional
ObservedPhases []ObservedPhase `json:"observedPhases,omitempty"`
}

// ObservedPhase records the observed content hash of a resolved phase.
type ObservedPhase struct {
// name is the phase name matching a phase in spec.phases.
//
// +required
Name string `json:"name"`

// hash is the hex-encoded SHA-256 hash of the phase's resolved
// object content at first successful reconciliation.
//
// +required
Hash string `json:"hash"`
}

// +genclient
Expand Down
20 changes: 20 additions & 0 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions applyconfigurations/api/v1/clusterobjectsetstatus.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions applyconfigurations/api/v1/observedphase.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions applyconfigurations/utils.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions docs/api-reference/olmv1-api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ _Appears in:_





#### PreflightConfig


Expand Down
28 changes: 20 additions & 8 deletions docs/draft/concepts/large-bundle-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,18 @@ Recommended conventions:
1. **Secret type**: Secrets should use the dedicated type
`olm.operatorframework.io/object-data` to distinguish them from user-created
Secrets and enable easy identification. The system always sets this type on
Secrets it creates. The reconciler does not enforce the type when resolving
refs — Secrets with any type are accepted — but producers should set it for
consistency.

2. **Immutability**: Secrets should set `immutable: true`. Because COS phases
are immutable, the content backing a ref should not change after creation.
Mutable referenced Secrets are not rejected, but modifying them after the
COS is created leads to undefined behavior.
Secrets it creates. The reconciler does not enforce the Secret type when
resolving refs, but it does enforce that referenced Secrets have
`immutable: true` set and that their content has not changed since first
resolution.

2. **Immutability**: Secrets must set `immutable: true`. The reconciler verifies
that all referenced Secrets have `immutable: true` set before proceeding.
Mutable referenced Secrets are rejected and reconciliation is blocked with
`Progressing=False, Reason=Blocked`. Additionally, the reconciler records
content hashes of the resolved phases on first successful reconciliation
and blocks reconciliation if the content changes (e.g., if a Secret is
deleted and recreated with the same name but different data).

3. **Owner references**: Referenced Secrets should carry an ownerReference to
the COS so that Kubernetes garbage collection removes them when the COS is
Expand Down Expand Up @@ -388,6 +392,14 @@ Key properties:

### COS reconciler behavior

Before resolving individual object refs, the reconciler verifies that all
referenced Secrets have `immutable: true` set. After successfully building
the phases (resolving all refs), the reconciler computes a per-phase content
hash and compares it against the hashes recorded in `.status.observedPhases`
(if present). If any phase's content has changed, reconciliation is blocked
with `Progressing=False, Reason=Blocked`. On first successful build, phase
content hashes are persisted to status for future comparisons.

When processing a COS phase:
- For each object entry in the phase:
- If `object` is set, use it directly (current behavior, unchanged).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,33 @@ spec:
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
observedPhases:
description: |-
observedPhases records the content hashes of resolved phases
at first successful reconciliation. This is used to detect if
referenced object sources were deleted and recreated with
different content. Each entry covers all fully-resolved object
manifests within a phase, making it source-agnostic.
items:
description: ObservedPhase records the observed content hash of
a resolved phase.
properties:
hash:
description: |-
hash is the hex-encoded SHA-256 hash of the phase's resolved
object content at first successful reconciliation.
type: string
name:
description: name is the phase name matching a phase in spec.phases.
type: string
required:
- hash
- name
type: object
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
type: object
type: object
served: true
Expand Down
Loading
Loading