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
12 changes: 0 additions & 12 deletions api/v1/clusterobjectset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,6 @@ type ClusterObjectSetSpec struct {
// +optional
Phases []ClusterObjectSetPhase `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
// require manual intervention. This functionality is disabled when no value
// is provided. The minimum period is 10 minutes, and the maximum is 720 minutes (12 hours).
//
// +kubebuilder:validation:Minimum:=10
// +kubebuilder:validation:Maximum:=720
// +optional
// <opcon:experimental>
ProgressDeadlineMinutes int32 `json:"progressDeadlineMinutes,omitempty"`

// progressionProbes is an optional field which provides the ability to define custom readiness probes
// for objects defined within spec.phases. As documented in that field, most kubernetes-native objects
// within the phases already have some kind of readiness check built-in, but this field allows for checks
Expand Down Expand Up @@ -527,7 +516,6 @@ type ClusterObjectSetStatus struct {
// - False with reason ObjectCollision: one or more objects are controlled by another owner, or are unowned while collision protection prevents adoption, so this revision cannot take ownership of them.
// - False with reason PreconditionsNotMet: a precondition for applying the revision is not yet satisfied (a referenced Secret is mutable or has invalid or changed content, or a preflight dry-run was rejected, e.g. an immutable field, a conflicting object, or RBAC/dependency CRDs not yet propagated); the revision keeps retrying and recovers once the precondition is met.
// - False with reason InvalidSpecification: the revision spec is invalid (a malformed revision/phase object or progression probe) and requires a spec change to proceed.
// - False with reason ProgressDeadlineExceeded: the revision did not roll out within spec.progressDeadlineMinutes.
// - False with reason Archiving: the revision is being archived and its owned objects are still being torn down.
// - False with reason Archived: the revision has been archived and its objects have been torn down.
//
Expand Down
71 changes: 0 additions & 71 deletions api/v1/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,77 +102,6 @@ func TestValidate(t *testing.T) {
},
want: want{valid: true},
},
"ClusterObjectSet: invalid progress deadline < 10": {
args: args{
object: ClusterObjectSetSpec{
Group: "validation-1",
Revision: 1,
CollisionProtection: CollisionProtectionPrevent,
LifecycleState: ClusterObjectSetLifecycleStateActive,
ProgressDeadlineMinutes: 9,
},
},
want: want{valid: false, errContains: "spec.progressDeadlineMinutes"},
},
"ClusterObjectSet: valid progress deadline = 10": {
args: args{
object: ClusterObjectSetSpec{
Group: "validation-2",
Revision: 1,
CollisionProtection: CollisionProtectionPrevent,
LifecycleState: ClusterObjectSetLifecycleStateActive,
ProgressDeadlineMinutes: 10,
},
},
want: want{valid: true},
},
"ClusterObjectSet: valid progress deadline = 360": {
args: args{
object: ClusterObjectSetSpec{
Group: "validation-3",
Revision: 1,
CollisionProtection: CollisionProtectionPrevent,
LifecycleState: ClusterObjectSetLifecycleStateActive,
ProgressDeadlineMinutes: 360,
},
},
want: want{valid: true},
},
"ClusterObjectSet: valid progress deadline = 720": {
args: args{
object: ClusterObjectSetSpec{
Group: "validation-4",
Revision: 1,
CollisionProtection: CollisionProtectionPrevent,
LifecycleState: ClusterObjectSetLifecycleStateActive,
ProgressDeadlineMinutes: 720,
},
},
want: want{valid: true},
},
"ClusterObjectSet: invalid progress deadline > 720": {
args: args{
object: ClusterObjectSetSpec{
Group: "validation-5",
Revision: 1,
CollisionProtection: CollisionProtectionPrevent,
LifecycleState: ClusterObjectSetLifecycleStateActive,
ProgressDeadlineMinutes: 721,
},
},
want: want{valid: false, errContains: "spec.progressDeadlineMinutes"},
},
"ClusterObjectSet: no progress deadline set": {
args: args{
object: ClusterObjectSetSpec{
Group: "validation-6",
Revision: 1,
CollisionProtection: CollisionProtectionPrevent,
LifecycleState: ClusterObjectSetLifecycleStateActive,
},
},
want: want{valid: true},
},
"ClusterObjectDeployment: invalid progress deadline < 10": {
args: args{
object: ClusterObjectDeploymentSpec{
Expand Down
15 changes: 0 additions & 15 deletions applyconfigurations/api/v1/clusterobjectsetspec.go

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

1 change: 0 additions & 1 deletion applyconfigurations/api/v1/clusterobjectsetstatus.go

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

3 changes: 0 additions & 3 deletions applyconfigurations/internal/internal.go

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

22 changes: 9 additions & 13 deletions docs/draft/concepts/clusterobjectsets.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This document explains what ClusterObjectSets are, how they enable safe phased r

A `ClusterObjectSet` is a cluster-scoped Kubernetes API that represents a versioned set of Kubernetes resources organized into ordered phases. It provides a declarative way to roll out a group of related resources sequentially, with built-in readiness checks between phases.

The revision content — the `group` identifier, `revision` number, `collisionProtection` strategy, and `phases` (including all objects within them) — is immutable once set. This guarantees that the record of what was deployed at a given revision cannot change after creation. Other fields like `lifecycleState` can change over the object's lifecycle (e.g. transitioning from `Active` to `Archived`), and optional fields like `progressDeadlineMinutes` and `progressionProbes` can be configured independently.
The revision content — the `group` identifier, `revision` number, `collisionProtection` strategy, and `phases` (including all objects within them) — is immutable once set. This guarantees that the record of what was deployed at a given revision cannot change after creation. Other fields like `lifecycleState` can change over the object's lifecycle (e.g. transitioning from `Active` to `Archived`), and optional fields like `progressionProbes` can be configured independently.

Each ClusterObjectSet has:

Expand Down Expand Up @@ -226,7 +226,6 @@ Indicates whether all objects in the revision have been successfully rolled out
| False | `ObjectCollision` | One or more objects are controlled by another owner, or are unowned and collision protection prevents adoption |
| False | `PreconditionsNotMet` | A precondition for applying the revision is not yet satisfied (a referenced Secret is mutable or has invalid or changed content, or a preflight dry-run was rejected, e.g. an immutable field, a conflicting object, or RBAC/dependency CRDs not yet propagated); the revision keeps retrying and recovers once the precondition is met |
| False | `InvalidSpecification` | The revision spec is invalid (a malformed revision/phase object or progression probe); requires a spec change |
| False | `ProgressDeadlineExceeded` | The revision did not roll out within `spec.progressDeadlineMinutes` |
| False | `Archiving` | The revision is being archived; owned objects are still being torn down |
| False | `Archived` | Objects torn down after archival |
| Unknown | `Pending` | The revision has not yet been evaluated (initial state) |
Expand All @@ -235,17 +234,14 @@ On a revision's first reconciliation the `Ready` condition is initialized to `Un

### Progress deadline

`spec.progressDeadlineMinutes` sets one time budget for the entire
ClusterObjectSet (COS) revision, measured from its creation timestamp until its
first successful rollout, recorded in `status.completedAt`. Completing a phase
does not reset the timer.

For a ClusterObjectDeployment (COD), this is the time allowed for the deployment to
progress to its desired new revision. Configure it through
`spec.template.spec.progressDeadlineMinutes`. The COD enforces this budget without
setting `spec.progressDeadlineMinutes` on the ClusterObjectSets it creates. Time
spent waiting for the ClusterObjectSet to be created is not counted. Each new
revision receives its own budget.
The progress deadline is a ClusterObjectDeployment (COD) concept: the time allowed
for the deployment to progress to its desired new revision. Configure it through
`spec.template.spec.progressDeadlineMinutes`. The COD enforces this budget itself;
the ClusterObjectSets it creates do not carry a deadline. Time spent waiting for
the ClusterObjectSet to be created is not counted, and each new revision receives
its own budget, measured from the revision's creation timestamp until its first
successful rollout (recorded in `status.completedAt`). Completing a phase does not
reset the timer.

If the desired revision is still incomplete when that budget expires, the COD
reports `Progressing=False` with reason `ProgressDeadlineExceeded`. A five-phase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,16 +284,6 @@ spec:
x-kubernetes-validations:
- message: phases is immutable
rule: self == oldSelf || oldSelf.size() == 0
progressDeadlineMinutes:
description: |-
progressDeadlineMinutes is an optional field that defines the maximum period
of time in minutes after which an installation should be considered failed and
require manual intervention. This functionality is disabled when no value
is provided. The minimum period is 10 minutes, and the maximum is 720 minutes (12 hours).
format: int32
maximum: 720
minimum: 10
type: integer
progressionProbes:
description: |-
progressionProbes is an optional field which provides the ability to define custom readiness probes
Expand Down Expand Up @@ -609,7 +599,6 @@ spec:
- False with reason ObjectCollision: one or more objects are controlled by another owner, or are unowned while collision protection prevents adoption, so this revision cannot take ownership of them.
- False with reason PreconditionsNotMet: a precondition for applying the revision is not yet satisfied (a referenced Secret is mutable or has invalid or changed content, or a preflight dry-run was rejected, e.g. an immutable field, a conflicting object, or RBAC/dependency CRDs not yet propagated); the revision keeps retrying and recovers once the precondition is met.
- False with reason InvalidSpecification: the revision spec is invalid (a malformed revision/phase object or progression probe) and requires a spec change to proceed.
- False with reason ProgressDeadlineExceeded: the revision did not roll out within spec.progressDeadlineMinutes.
- False with reason Archiving: the revision is being archived and its owned objects are still being torn down.
- False with reason Archived: the revision has been archived and its objects have been torn down.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ func Test_ClusterObjectDeploymentReconciler_CreatesFirstRevision(t *testing.T) {
require.Equal(t, int64(1), cos.Spec.Revision)
require.Equal(t, ocv1.ClusterObjectSetLifecycleStateActive, cos.Spec.LifecycleState)
require.Equal(t, ocv1.CollisionProtectionPrevent, cos.Spec.CollisionProtection)
require.Zero(t, cos.Spec.ProgressDeadlineMinutes, "the deployment enforces its own progress deadline")
require.NotEmpty(t, cos.Labels[labels.TemplateHashKey])

ref := metav1.GetControllerOf(cos)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ func TestClusterObjectDeploymentReconcilerDeadlineCoversEntireRevision(t *testin
cos, found := getCOS(t, c, cosName)
require.True(t, found)
require.True(t, cos.CreationTimestamp.Time.Equal(creation))
require.Zero(t, cos.Spec.ProgressDeadlineMinutes, "the COD owns the deadline budget")
require.Len(t, cos.Spec.Phases, 5)
require.Equal(t, metav1.ConditionTrue, progressing(t, c).Status)
// Start after finalizer initialization; the fake client's metadata patch
Expand Down
Loading
Loading