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
2 changes: 1 addition & 1 deletion .claude/commands/list-e2e-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Organize steps into these 10 categories. For each step, document:
2. **Catalog Management** - ClusterCatalog creation, updates, image tagging, deletion
3. **ClusterExtension Lifecycle** - Apply, update, remove ClusterExtension resources
4. **ClusterExtension Status & Conditions** - Condition checks, transition times, reconciliation
5. **ClusterExtensionRevision** - Revision-specific condition checks, archival, annotations, labels, active revisions
5. **ObjectSet** - Revision-specific condition checks, archival, annotations, labels, active revisions
6. **Generic Resource Operations** - Get, delete, restore, match arbitrary resources
7. **Test Operator Control** - Marking test-operator deployment ready/not-ready
8. **Metrics** - Fetching and validating Prometheus metrics
Expand Down
8 changes: 4 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ operator-controller is the central component of Operator Lifecycle Manager (OLM)
install and manage cluster extensions. The project follows a microservices architecture with two main binaries:

**operator-controller**
- manages `ClusterExtension` and `ClusterExtensionRevision` CRDs
- manages `ClusterExtension` and `ObjectSet` CRDs
- resolves bundles from configured source
- unpacks bundles and renders manifests from them
- applies manifests with phase-based rollouts
Expand Down Expand Up @@ -193,7 +193,7 @@ make generate

- **Primary CRDs:**
- `ClusterExtension` - declares desired extension installations
- `ClusterExtensionRevision` - revision management (experimental)
- `ObjectSet` - revision management (experimental)
- `ClusterCatalog` - catalog source definitions
- **API domain:** `olm.operatorframework.io`
- This is the API group of our user-facing CRDs
Expand All @@ -204,7 +204,7 @@ make generate

Two manifest variants exist:
- **Standard:** Production-ready features
- **Experimental:** Features under development/testing (includes `ClusterExtensionRevision` API)
- **Experimental:** Features under development/testing (includes `ObjectSet` API)

---

Expand Down Expand Up @@ -330,7 +330,7 @@ Two manifest variants exist:

**operator-controller:**
- `ClusterExtension` controller - manages extension installations
- `ClusterExtensionRevision` controller - manages revision lifecycle
- `ObjectSet` controller - manages revision lifecycle
- Resolver - bundle version selection
- Applier - applies manifests to cluster
- Content Manager - manages extension content
Expand Down
8 changes: 4 additions & 4 deletions api/v1/clusterextension_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,9 @@ type BundleMetadata struct {
Version string `json:"version"`
}

// RevisionStatus defines the observed state of a ClusterExtensionRevision.
// RevisionStatus defines the observed state of a ObjectSet.
type RevisionStatus struct {
// name of the ClusterExtensionRevision resource
// name of the ObjectSet resource
Name string `json:"name"`
// conditions optionally expose Progressing and Available condition of the revision,
// in case when it is not yet marked as successfully installed (condition Succeeded is not set to True).
Expand Down Expand Up @@ -498,7 +498,7 @@ type ClusterExtensionStatus struct {
// When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts.
// When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery.
// <opcon:experimental:description>
// When Progressing is True and Reason is RollingOut, the ClusterExtension has one or more ClusterExtensionRevisions in active roll out.
// When Progressing is True and Reason is RollingOut, the ClusterExtension has one or more ObjectSets in active roll out.
// </opcon:experimental:description>
//
// When the ClusterExtension is sourced from a catalog, it surfaces deprecation conditions based on catalog metadata.
Expand All @@ -518,7 +518,7 @@ type ClusterExtensionStatus struct {
// +optional
Install *ClusterExtensionInstallStatus `json:"install,omitempty"`

// activeRevisions holds a list of currently active (non-archived) ClusterExtensionRevisions,
// activeRevisions holds a list of currently active (non-archived) ObjectSets,
// including both installed and rolling out revisions.
// +listType=map
// +listMapKey=name
Expand Down
102 changes: 51 additions & 51 deletions api/v1/clusterextensionrevision_types.go → api/v1/objectset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,25 @@ import (
)

const (
ClusterExtensionRevisionKind = "ClusterExtensionRevision"
ObjectSetKind = "ObjectSet"

// Condition Types
ClusterExtensionRevisionTypeAvailable = "Available"
ClusterExtensionRevisionTypeProgressing = "Progressing"
ClusterExtensionRevisionTypeSucceeded = "Succeeded"
ObjectSetTypeAvailable = "Available"
ObjectSetTypeProgressing = "Progressing"
ObjectSetTypeSucceeded = "Succeeded"

// Condition Reasons
ClusterExtensionRevisionReasonArchived = "Archived"
ClusterExtensionRevisionReasonBlocked = "Blocked"
ClusterExtensionRevisionReasonProbeFailure = "ProbeFailure"
ClusterExtensionRevisionReasonProbesSucceeded = "ProbesSucceeded"
ClusterExtensionRevisionReasonReconciling = "Reconciling"
ClusterExtensionRevisionReasonRetrying = "Retrying"
ObjectSetReasonArchived = "Archived"
ObjectSetReasonBlocked = "Blocked"
ObjectSetReasonProbeFailure = "ProbeFailure"
ObjectSetReasonProbesSucceeded = "ProbesSucceeded"
ObjectSetReasonReconciling = "Reconciling"
ObjectSetReasonRetrying = "Retrying"
)

// ClusterExtensionRevisionSpec defines the desired state of ClusterExtensionRevision.
type ClusterExtensionRevisionSpec struct {
// lifecycleState specifies the lifecycle state of the ClusterExtensionRevision.
// ObjectSetSpec defines the desired state of ObjectSet.
type ObjectSetSpec struct {
// lifecycleState specifies the lifecycle state of the ObjectSet.
//
// When set to "Active", the revision is actively managed and reconciled.
// When set to "Archived", the revision is inactive and any resources not managed by a subsequent revision are deleted.
Expand All @@ -56,13 +56,13 @@ type ClusterExtensionRevisionSpec struct {
// +required
// +kubebuilder:validation:Enum=Active;Archived
// +kubebuilder:validation:XValidation:rule="oldSelf == 'Active' || oldSelf == 'Archived' && oldSelf == self", message="cannot un-archive"
LifecycleState ClusterExtensionRevisionLifecycleState `json:"lifecycleState,omitempty"`
LifecycleState ObjectSetLifecycleState `json:"lifecycleState,omitempty"`

// revision is a required, immutable sequence number representing a specific revision
// of the parent ClusterExtension.
//
// The revision field must be a positive integer.
// Each ClusterExtensionRevision belonging to the same parent ClusterExtension must have a unique revision number.
// Each ObjectSet belonging to the same parent ClusterExtension must have a unique revision number.
// The revision number must always be the previous revision number plus one, or 1 for the first revision.
//
// +required
Expand Down Expand Up @@ -93,7 +93,7 @@ type ClusterExtensionRevisionSpec struct {
// +listType=map
// +listMapKey=name
// +optional
Phases []ClusterExtensionRevisionPhase `json:"phases,omitempty"`
Phases []ObjectSetPhase `json:"phases,omitempty"`

// progressDeadlineMinutes is an optional field that defines the maximum period
// of time in minutes after which an installation should be considered failed and
Expand Down Expand Up @@ -338,21 +338,21 @@ type FieldValueProbe struct {
Value string `json:"value,omitempty"`
}

// ClusterExtensionRevisionLifecycleState specifies the lifecycle state of the ClusterExtensionRevision.
type ClusterExtensionRevisionLifecycleState string
// ObjectSetLifecycleState specifies the lifecycle state of the ObjectSet.
type ObjectSetLifecycleState string

const (
// ClusterExtensionRevisionLifecycleStateActive / "Active" is the default lifecycle state.
ClusterExtensionRevisionLifecycleStateActive ClusterExtensionRevisionLifecycleState = "Active"
// ClusterExtensionRevisionLifecycleStateArchived / "Archived" archives the revision for historical or auditing purposes.
// ObjectSetLifecycleStateActive / "Active" is the default lifecycle state.
ObjectSetLifecycleStateActive ObjectSetLifecycleState = "Active"
// ObjectSetLifecycleStateArchived / "Archived" archives the revision for historical or auditing purposes.
// The revision is removed from the owner list of all other objects previously under management and all objects
// that did not transition to a succeeding revision are deleted.
ClusterExtensionRevisionLifecycleStateArchived ClusterExtensionRevisionLifecycleState = "Archived"
ObjectSetLifecycleStateArchived ObjectSetLifecycleState = "Archived"
)

// ClusterExtensionRevisionPhase represents a group of objects that are applied together. The phase is considered
// ObjectSetPhase represents a group of objects that are applied together. The phase is considered
// complete only after all objects pass their status probes.
type ClusterExtensionRevisionPhase struct {
type ObjectSetPhase struct {
// name is a required identifier for this phase.
//
// phase names must follow the DNS label standard as defined in [RFC 1123].
Expand All @@ -374,7 +374,7 @@ type ClusterExtensionRevisionPhase struct {
// All objects in this list are applied to the cluster in no particular order. The maximum number of objects per phase is 50.
// +required
// +kubebuilder:validation:MaxItems=50
Objects []ClusterExtensionRevisionObject `json:"objects"`
Objects []ObjectSetObject `json:"objects"`

// collisionProtection specifies the default collision protection strategy for all objects
// in this phase. Individual objects can override this value.
Expand All @@ -390,9 +390,9 @@ type ClusterExtensionRevisionPhase struct {
CollisionProtection CollisionProtection `json:"collisionProtection,omitempty"`
}

// ClusterExtensionRevisionObject represents a Kubernetes object to be applied as part
// ObjectSetObject represents a Kubernetes object to be applied as part
// of a phase, along with its collision protection settings.
type ClusterExtensionRevisionObject struct {
type ObjectSetObject struct {
// object is a required embedded Kubernetes object to be applied.
//
// This object must be a valid Kubernetes resource with apiVersion, kind, and metadata fields.
Expand Down Expand Up @@ -442,27 +442,27 @@ const (
CollisionProtectionNone CollisionProtection = "None"
)

// ClusterExtensionRevisionStatus defines the observed state of a ClusterExtensionRevision.
type ClusterExtensionRevisionStatus struct {
// ObjectSetStatus defines the observed state of a ObjectSet.
type ObjectSetStatus struct {
// conditions is an optional list of status conditions describing the state of the
// ClusterExtensionRevision.
// ObjectSet.
//
// The Progressing condition represents whether the revision is actively rolling out:
// - When status is True and reason is RollingOut, the ClusterExtensionRevision rollout is actively making progress and is in transition.
// - When status is True and reason is Retrying, the ClusterExtensionRevision has encountered an error that could be resolved on subsequent reconciliation attempts.
// - When status is True and reason is Succeeded, the ClusterExtensionRevision has reached the desired state.
// - When status is False and reason is Blocked, the ClusterExtensionRevision has encountered an error that requires manual intervention for recovery.
// - When status is False and reason is Archived, the ClusterExtensionRevision is archived and not being actively reconciled.
// - When status is True and reason is RollingOut, the ObjectSet rollout is actively making progress and is in transition.
// - When status is True and reason is Retrying, the ObjectSet has encountered an error that could be resolved on subsequent reconciliation attempts.
// - When status is True and reason is Succeeded, the ObjectSet has reached the desired state.
// - When status is False and reason is Blocked, the ObjectSet has encountered an error that requires manual intervention for recovery.
// - When status is False and reason is Archived, the ObjectSet is archived and not being actively reconciled.
//
// The Available condition represents whether the revision has been successfully rolled out and is available:
// - When status is True and reason is ProbesSucceeded, the ClusterExtensionRevision has been successfully rolled out and all objects pass their readiness probes.
// - When status is True and reason is ProbesSucceeded, the ObjectSet has been successfully rolled out and all objects pass their readiness probes.
// - When status is False and reason is ProbeFailure, one or more objects are failing their readiness probes during rollout.
// - When status is Unknown and reason is Reconciling, the ClusterExtensionRevision has encountered an error that prevented it from observing the probes.
// - When status is Unknown and reason is Archived, the ClusterExtensionRevision has been archived and its objects have been torn down.
// - When status is Unknown and reason is Migrated, the ClusterExtensionRevision was migrated from an existing release and object status probe results have not yet been observed.
// - When status is Unknown and reason is Reconciling, the ObjectSet has encountered an error that prevented it from observing the probes.
// - When status is Unknown and reason is Archived, the ObjectSet has been archived and its objects have been torn down.
// - When status is Unknown and reason is Migrated, the ObjectSet was migrated from an existing release and object status probe results have not yet been observed.
//
// The Succeeded condition represents whether the revision has successfully completed its rollout:
// - When status is True and reason is Succeeded, the ClusterExtensionRevision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable.
// - When status is True and reason is Succeeded, the ObjectSet has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable.
//
// +listType=map
// +listMapKey=type
Expand All @@ -479,44 +479,44 @@ type ClusterExtensionRevisionStatus struct {
// +kubebuilder:printcolumn:name="Progressing",type=string,JSONPath=`.status.conditions[?(@.type=='Progressing')].status`
// +kubebuilder:printcolumn:name=Age,type=date,JSONPath=`.metadata.creationTimestamp`

// ClusterExtensionRevision represents an immutable snapshot of Kubernetes objects
// ObjectSet represents an immutable snapshot of Kubernetes objects
// for a specific version of a ClusterExtension. Each revision contains objects
// organized into phases that roll out sequentially. The same object can only be managed by a single revision
// at a time. Ownership of objects is transitioned from one revision to the next as the extension is upgraded
// or reconfigured. Once the latest revision has rolled out successfully, previous active revisions are archived for
// posterity.
type ClusterExtensionRevision struct {
type ObjectSet struct {
metav1.TypeMeta `json:",inline"`

// metadata is the standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`

// spec defines the desired state of the ClusterExtensionRevision.
// spec defines the desired state of the ObjectSet.
// +optional
Spec ClusterExtensionRevisionSpec `json:"spec,omitempty"`
Spec ObjectSetSpec `json:"spec,omitempty"`

// status is optional and defines the observed state of the ClusterExtensionRevision.
// status is optional and defines the observed state of the ObjectSet.
// +optional
Status ClusterExtensionRevisionStatus `json:"status,omitempty"`
Status ObjectSetStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// ClusterExtensionRevisionList contains a list of ClusterExtensionRevision
type ClusterExtensionRevisionList struct {
// ObjectSetList contains a list of ObjectSet
type ObjectSetList struct {
metav1.TypeMeta `json:",inline"`

// +optional
metav1.ListMeta `json:"metadata,omitempty"`

// items is a required list of ClusterExtensionRevision objects.
// items is a required list of ObjectSet objects.
//
// +required
Items []ClusterExtensionRevision `json:"items"`
Items []ObjectSet `json:"items"`
}

func init() {
SchemeBuilder.Register(&ClusterExtensionRevision{}, &ClusterExtensionRevisionList{})
SchemeBuilder.Register(&ObjectSet{}, &ObjectSetList{})
}
Loading
Loading