Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5ed8cf4
add PDB to make sure at least 1 pod is always available during upgrad…
jianzhangbjz Nov 27, 2025
4355cde
Update ClusterExtensionRevision API docs (#2350)
perdasilva Nov 27, 2025
91b03c7
🌱 new tag symmetry and required validations (#2358)
grokspawn Dec 1, 2025
4e5542f
:seedling: Bump pymdown-extensions from 10.17.1 to 10.17.2 (#2364)
dependabot[bot] Dec 1, 2025
b23e124
institute 2wk dependency cooldown policy (#2363)
grokspawn Dec 1, 2025
34394ce
Fix testCatalogName conflict in parallel e2e tests (#2367)
jianzhangbjz Dec 2, 2025
0072857
Merge branch 'main' into synchronize
Dec 2, 2025
4a547db
UPSTREAM: <carry>: Add OpenShift specific files
dtfranz Oct 26, 2023
b6f4da7
UPSTREAM: <carry>: Add new tests for single/own namespaces install modes
camilamacedo86 Oct 6, 2025
93b3929
UPSTREAM: <carry>: Upgrade OCP image from 4.20 to 4.21
camilamacedo86 Oct 13, 2025
b3b6d06
UPSTREAM: <carry>: [Default Catalog Tests] - Change logic to get ocp …
camilamacedo86 Oct 13, 2025
58c2f61
UPSTREAM: <carry>: Update OCP catalogs to v4.21
tmshort Oct 13, 2025
3fa03ea
UPSTREAM: <carry>: support singleown cases in disconnected
kuiwang02 Oct 16, 2025
9d58caa
UPSTREAM: <carry>: fix cases 81696 and 74618 for product code changes
kuiwang02 Oct 17, 2025
84201cb
UPSTREAM: <carry>: Define Default timeouts and apply their usage accr…
camilamacedo86 Oct 22, 2025
ec5a401
UPSTREAM: <carry>: Update to new feature-gate options in helm
tmshort Oct 22, 2025
df6d7d4
UPSTREAM: <carry>: Fix flake for single/own ns tests by ensuring uniq…
camilamacedo86 Oct 22, 2025
27c04e5
UPSTREAM: <carry>: [OTE]: Enhance single/own ns based on review comme…
camilamacedo86 Oct 24, 2025
9393d7f
UPSTREAM: <carry>: Update OwnSingle template to use spec.config.inlin…
kuiwang02 Nov 3, 2025
1a4b54e
UPSTREAM: <carry>: [OTE]: Add webhook cleanup validation on extension…
camilamacedo86 Nov 4, 2025
be96547
UPSTREAM: <carry>: Add [OTP] to migrated cases
kuiwang02 Nov 7, 2025
f3f9743
UPSTREAM: <carry>: [OTE]: Upgrade dependencies used
camilamacedo86 Nov 5, 2025
0ae57c7
UPSTREAM: <carry>: fix(OTE): fix OpenShift Kubernetes replace version…
camilamacedo86 Nov 10, 2025
31c8501
UPSTREAM: <carry>: [Default Catalog Tests] Upgrade go 1.24.6 and depe…
camilamacedo86 Nov 11, 2025
f7ae9c3
UPSTREAM: <carry>: add disconnected environment support with custom p…
kuiwang02 Nov 12, 2025
63848dc
UPSTREAM: <carry>: migrate jiazha test cases to OTE
jianzhangbjz Nov 14, 2025
bac284b
UPSTREAM: <carry>: migrate clustercatalog case to ote
Xia-Zhao-rh Oct 17, 2025
7ad780d
UPSTREAM: <carry>: migrate olmv1 QE stress cases
kuiwang02 Nov 20, 2025
e037806
UPSTREAM: <carry>: Use busybox/httpd to simulate probes
tmshort Nov 25, 2025
ed96aa9
UPSTREAM: <carry>: migrate olmv1 QE cases
Xia-Zhao-rh Nov 25, 2025
71859c9
UPSTREAM: <carry>: add agent for olmv1 qe cases
kuiwang02 Oct 21, 2025
e4972ac
UPSTREAM: <drop>: go mod vendor
Dec 2, 2025
0176527
UPSTREAM: <drop>: remove upstream GitHub configuration
Dec 2, 2025
f45bd14
UPSTREAM: <drop>: configure the commit-checker
Dec 2, 2025
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
134 changes: 109 additions & 25 deletions api/v1/clusterextensionrevision_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@ import (
const (
ClusterExtensionRevisionKind = "ClusterExtensionRevision"

// Condition Types
// ClusterExtensionRevisionTypeAvailable is the condition type that represents whether the
// ClusterExtensionRevision is available and has been successfully rolled out.
ClusterExtensionRevisionTypeAvailable = "Available"

// ClusterExtensionRevisionTypeSucceeded is the condition type that represents whether the
// ClusterExtensionRevision rollout has succeeded.
ClusterExtensionRevisionTypeSucceeded = "Succeeded"

// Condition Reasons
// Condition reasons
ClusterExtensionRevisionReasonAvailable = "Available"
ClusterExtensionRevisionReasonReconcileFailure = "ReconcileFailure"
ClusterExtensionRevisionReasonRevisionValidationFailure = "RevisionValidationFailure"
Expand All @@ -44,22 +48,47 @@ const (

// ClusterExtensionRevisionSpec defines the desired state of ClusterExtensionRevision.
type ClusterExtensionRevisionSpec struct {
// Specifies the lifecycle state of the ClusterExtensionRevision.
// lifecycleState specifies the lifecycle state of the ClusterExtensionRevision.
//
// When set to "Active" (the default), 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.
// The revision is removed from the owner list of all objects previously under management.
// All objects that did not transition to a succeeding revision are deleted.
//
// Once a revision is set to "Archived", it cannot be un-archived.
//
// +kubebuilder:default="Active"
// +kubebuilder:validation:Enum=Active;Paused;Archived
// +kubebuilder:validation:XValidation:rule="oldSelf == 'Active' || oldSelf == 'Paused' || oldSelf == 'Archived' && oldSelf == self", message="can not un-archive"
// +kubebuilder:validation:Enum=Active;Archived
// +kubebuilder:validation:XValidation:rule="oldSelf == 'Active' || oldSelf == 'Archived' && oldSelf == self", message="cannot un-archive"
LifecycleState ClusterExtensionRevisionLifecycleState `json:"lifecycleState,omitempty"`
// Revision is a sequence number representing a specific revision of the ClusterExtension instance.
// Must be positive. Each ClusterExtensionRevision of the same parent ClusterExtension needs to have
// a unique value assigned. It is immutable after creation. The new revision number must always be previous revision +1.

// 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.
// The revision number must always be the previous revision number plus one, or 1 for the first revision.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:Minimum:=1
// +kubebuilder:validation:XValidation:rule="self == oldSelf", message="revision is immutable"
Revision int64 `json:"revision"`
// Phases are groups of objects that will be applied at the same time.
// All objects in the phase will have to pass their probes in order to progress to the next phase.

// phases is an optional, immutable list of phases that group objects to be applied together.
//
// Objects are organized into phases based on their Group-Kind. Common phases include:
// - namespaces: Namespace objects
// - policies: ResourceQuota, LimitRange, NetworkPolicy objects
// - rbac: ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding objects
// - crds: CustomResourceDefinition objects
// - storage: PersistentVolume, PersistentVolumeClaim, StorageClass objects
// - deploy: Deployment, StatefulSet, DaemonSet, Service, ConfigMap, Secret objects
// - publish: Ingress, APIService, Route, Webhook objects
//
// All objects in a phase are applied in no particular order.
// The revision progresses to the next phase only after all objects in the current phase pass their readiness probes.
//
// Once set, even if empty, the phases field is immutable.
//
// +kubebuilder:validation:XValidation:rule="self == oldSelf || oldSelf.size() == 0", message="phases is immutable"
// +listType=map
Expand All @@ -75,33 +104,62 @@ const (
// ClusterExtensionRevisionLifecycleStateActive / "Active" is the default lifecycle state.
ClusterExtensionRevisionLifecycleStateActive ClusterExtensionRevisionLifecycleState = "Active"
// ClusterExtensionRevisionLifecycleStatePaused / "Paused" disables reconciliation of the ClusterExtensionRevision.
// Only Status updates will still propagated, but object changes will not be reconciled.
// Object changes will not be reconciled. However, status updates will be propagated.
ClusterExtensionRevisionLifecycleStatePaused ClusterExtensionRevisionLifecycleState = "Paused"
// ClusterExtensionRevisionLifecycleStateArchived / "Archived" disables reconciliation while also "scaling to zero",
// which deletes all objects that are not excluded via the pausedFor property and
// removes itself from the owner list of all other objects previously under management.
// ClusterExtensionRevisionLifecycleStateArchived / "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"
)

// ClusterExtensionRevisionPhase are groups of objects that will be applied at the same time.
// All objects in the a phase will have to pass their probes in order to progress to the next phase.
// ClusterExtensionRevisionPhase 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 {
// Name identifies this phase.
// name is a required identifier for this phase.
//
// phase names must follow the DNS label standard as defined in [RFC 1123].
// They must contain only lowercase alphanumeric characters or hyphens (-),
// start and end with an alphanumeric character, and be no longer than 63 characters.
//
// Common phase names include: namespaces, policies, rbac, crds, storage, deploy, publish.
//
// [RFC 1123]: https://tools.ietf.org/html/rfc1123
//
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:validation:Pattern=`^[a-z]([-a-z0-9]*[a-z0-9])?$`
Name string `json:"name"`
// Objects are a list of all the objects within this phase.

// objects is a required list of all Kubernetes objects that belong to this phase.
//
// All objects in this list are applied to the cluster in no particular order.
Objects []ClusterExtensionRevisionObject `json:"objects"`
}

// ClusterExtensionRevisionObject contains an object and settings for it.
// ClusterExtensionRevisionObject represents a Kubernetes object to be applied as part
// of a phase, along with its collision protection settings.
type ClusterExtensionRevisionObject 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.
//
// +kubebuilder:validation:EmbeddedResource
// +kubebuilder:pruning:PreserveUnknownFields
Object unstructured.Unstructured `json:"object"`
// CollisionProtection controls whether OLM can adopt and modify objects
// already existing on the cluster or even owned by another controller.

// collisionProtection controls whether the operator can adopt and modify objects
// that already exist on the cluster.
//
// When set to "Prevent" (the default), the operator only manages objects it created itself.
// This prevents ownership collisions.
//
// When set to "IfNoController", the operator can adopt and modify pre-existing objects
// that are not owned by another controller.
// This is useful for taking over management of manually-created resources.
//
// When set to "None", the operator can adopt and modify any pre-existing object, even if
// owned by another controller.
// Use this setting with extreme caution as it may cause multiple controllers to fight over
// the same resource, resulting in increased load on the API server and etcd.
//
// +kubebuilder:default="Prevent"
// +kubebuilder:validation:Enum=Prevent;IfNoController;None
Expand All @@ -128,6 +186,27 @@ const (

// ClusterExtensionRevisionStatus defines the observed state of a ClusterExtensionRevision.
type ClusterExtensionRevisionStatus struct {
// conditions is an optional list of status conditions describing the state of the
// ClusterExtensionRevision.
//
// The Progressing condition represents whether the revision is actively rolling out:
// - When status is True and reason is Progressing, the revision rollout is actively making progress and is in transition.
// - When Progressing is not present, the revision is not currently in transition.
//
// The Available condition represents whether the revision has been successfully rolled out and is available:
// - When status is True and reason is Available, the revision has been successfully rolled out and all objects pass their readiness probes.
// - When status is False and reason is Incomplete, the revision rollout has not yet completed but no specific failures have been detected.
// - When status is False and reason is ProbeFailure, one or more objects are failing their readiness probes during rollout.
// - When status is False and reason is ReconcileFailure, the revision has encountered a general reconciliation failure.
// - When status is False and reason is RevisionValidationFailure, the revision failed preflight validation checks.
// - When status is False and reason is PhaseValidationError, a phase within the revision failed preflight validation checks.
// - When status is False and reason is ObjectCollisions, objects in the revision collide with existing cluster objects that cannot be adopted.
// - When status is Unknown and reason is Archived, the revision has been archived and its objects have been torn down.
// - When status is Unknown and reason is Migrated, the revision 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 RolloutSuccess, the revision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable.
//
// +listType=map
// +listMapKey=type
// +optional
Expand All @@ -137,19 +216,24 @@ type ClusterExtensionRevisionStatus struct {
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:subresource:status

// ClusterExtensionRevision is the Schema for the clusterextensionrevisions API
// +kubebuilder:printcolumn:name="Available",type=string,JSONPath=`.status.conditions[?(@.type=='Available')].status`
// +kubebuilder:printcolumn:name=Age,type=date,JSONPath=`.metadata.creationTimestamp`

// ClusterExtensionRevision 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 {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// spec is an optional field that defines the desired state of the ClusterExtension.
// spec defines the desired state of the ClusterExtensionRevision.
// +optional
Spec ClusterExtensionRevisionSpec `json:"spec,omitempty"`

// status is an optional field that defines the observed state of the ClusterExtension.
// status is optional and defines the observed state of the ClusterExtensionRevision.
// +optional
Status ClusterExtensionRevisionStatus `json:"status,omitempty"`
}
Expand Down
2 changes: 1 addition & 1 deletion commitchecker.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
expectedMergeBase: 045989d84a7570b1cfddeee47eae64d47245aff2
expectedMergeBase: 34394ce0a7067e1f1622dc2c381a9a12439b10d2
upstreamBranch: main
upstreamOrg: operator-framework
upstreamRepo: operator-controller
5 changes: 4 additions & 1 deletion hack/test/install-prometheus.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ echo "Patching namespace to ${PROMETHEUS_NAMESPACE}..."
echo "Applying Prometheus base..."
kubectl apply -k "$TMPDIR" --server-side

echo "Waiting for Prometheus Operator deployment to become available..."
kubectl wait --for=condition=Available deployment/prometheus-operator -n "$PROMETHEUS_NAMESPACE" --timeout=180s

echo "Waiting for Prometheus Operator pod to become ready..."
kubectl wait --for=condition=Ready pod -n "$PROMETHEUS_NAMESPACE" -l app.kubernetes.io/name=prometheus-operator
kubectl wait --for=condition=Ready pod -n "$PROMETHEUS_NAMESPACE" -l app.kubernetes.io/name=prometheus-operator --timeout=120s

echo "Applying prometheus Helm chart..."
${HELM} template prometheus helm/prometheus ${PROMETHEUS_VALUES} | sed "s/cert-git-version/cert-${VERSION}/g" | kubectl apply -f -
Expand Down
20 changes: 20 additions & 0 deletions hack/tools/crd-generator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ A semi-colon separated list of enumerations, similar to the `+kubebuilder:valida

An XValidation scheme, similar to the `+kubebuilder:validation:XValidation` scheme, but more limited.

* `Optional`

Indicating that this field should not be listed as required in its parent.

* `Required`

Indicating that this field should be listed as required in its parent.

## Experimental Description

* Start Tag: `<opcon:experimental:description>`
Expand All @@ -44,6 +52,18 @@ All text between the tags is included in the experimental CRD, but removed from
This is only useful if the field is included in the standard CRD, but there's additional meaning in
the experimental CRD when feature gates are enabled.

## Standard Description

* Start Tag: `<opcon:standard:description>`
* End Tag: `</opcon:standard:description>`

Descriptive text that is only included as part of the field description within the standard CRD.
All text between the tags is included in the standard CRD, but removed from the experimental CRD.

This is useful if the field is included in the standard CRD and has differing meaning than when the
field is used in the experimental CRD when feature gates are enabled.


## Exclude from CRD Description

* Start Tag: `<opcon:util:excludeFromCRD>`
Expand Down
Loading