diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index bd887a93388..89a6b8388f4 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -3092,7 +3092,7 @@ }, "persistentVolumeClaimRetentionPolicy": { "$ref": "#/definitions/io.k8s.api.apps.v1.StatefulSetPersistentVolumeClaimRetentionPolicy", - "description": "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is beta." + "description": "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down." }, "podManagementPolicy": { "description": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.", diff --git a/api/openapi-spec/v3/apis__apps__v1_openapi.json b/api/openapi-spec/v3/apis__apps__v1_openapi.json index 34036de2ae3..66c4da63500 100644 --- a/api/openapi-spec/v3/apis__apps__v1_openapi.json +++ b/api/openapi-spec/v3/apis__apps__v1_openapi.json @@ -1098,7 +1098,7 @@ "$ref": "#/components/schemas/io.k8s.api.apps.v1.StatefulSetPersistentVolumeClaimRetentionPolicy" } ], - "description": "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is beta." + "description": "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down." }, "podManagementPolicy": { "description": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.", diff --git a/pkg/apis/apps/v1/defaults_test.go b/pkg/apis/apps/v1/defaults_test.go index 8c756e0cf6f..1b5c6cdc27e 100644 --- a/pkg/apis/apps/v1/defaults_test.go +++ b/pkg/apis/apps/v1/defaults_test.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/version" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -199,8 +200,8 @@ func TestSetDefaultStatefulSet(t *testing.T) { name string original *appsv1.StatefulSet expected *appsv1.StatefulSet - enablePVCDeletionPolicy bool enableMaxUnavailablePolicy bool + disablePVCDeletionPolicy bool }{ { name: "labels and default update strategy", @@ -218,6 +219,10 @@ func TestSetDefaultStatefulSet(t *testing.T) { MinReadySeconds: int32(0), Template: defaultTemplate, PodManagementPolicy: appsv1.OrderedReadyPodManagement, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, RollingUpdate: &appsv1.RollingUpdateStatefulSetStrategy{ @@ -243,9 +248,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.OrderedReadyPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.OnDeleteStatefulSetStrategyType, @@ -267,9 +276,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.ParallelPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, @@ -298,9 +311,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.OrderedReadyPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, @@ -313,7 +330,7 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, }, { - name: "PVC delete policy enabled, no policy specified", + name: "no PVC policy specified", original: &appsv1.StatefulSet{ Spec: appsv1.StatefulSetSpec{ Template: defaultTemplate, @@ -324,8 +341,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.OrderedReadyPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, @@ -333,17 +354,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Partition: &defaultPartition, }, }, - PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ - WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, - WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, - }, RevisionHistoryLimit: ptr.To[int32](10), }, }, - enablePVCDeletionPolicy: true, }, { - name: "PVC delete policy enabled, with scaledown policy specified", + name: "PVC scaledown policy specified", original: &appsv1.StatefulSet{ Spec: appsv1.StatefulSetSpec{ Template: defaultTemplate, @@ -373,10 +389,9 @@ func TestSetDefaultStatefulSet(t *testing.T) { RevisionHistoryLimit: ptr.To[int32](10), }, }, - enablePVCDeletionPolicy: true, }, { - name: "PVC delete policy disabled, with set deletion policy specified", + name: "PVC with deletion policy specified", original: &appsv1.StatefulSet{ Spec: appsv1.StatefulSetSpec{ Template: defaultTemplate, @@ -406,39 +421,6 @@ func TestSetDefaultStatefulSet(t *testing.T) { RevisionHistoryLimit: ptr.To[int32](10), }, }, - enablePVCDeletionPolicy: true, - }, - { - name: "PVC delete policy disabled, with policy specified", - original: &appsv1.StatefulSet{ - Spec: appsv1.StatefulSetSpec{ - Template: defaultTemplate, - PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ - WhenScaled: appsv1.DeletePersistentVolumeClaimRetentionPolicyType, - }, - }, - }, - expected: &appsv1.StatefulSet{ - ObjectMeta: metav1.ObjectMeta{ - Labels: defaultLabels, - }, - Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, - PodManagementPolicy: appsv1.OrderedReadyPodManagement, - UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ - Type: appsv1.RollingUpdateStatefulSetStrategyType, - RollingUpdate: &appsv1.RollingUpdateStatefulSetStrategy{ - Partition: &defaultPartition, - }, - }, - PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ - WhenScaled: appsv1.DeletePersistentVolumeClaimRetentionPolicyType, - }, - RevisionHistoryLimit: ptr.To[int32](10), - }, - }, - enablePVCDeletionPolicy: false, }, { name: "MaxUnavailable disabled, with maxUnavailable not specified", @@ -452,8 +434,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.OrderedReadyPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, @@ -484,8 +470,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.OrderedReadyPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, @@ -517,8 +507,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.OrderedReadyPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, @@ -544,8 +538,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.OrderedReadyPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, @@ -577,8 +575,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1.OrderedReadyPodManagement, UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ Type: appsv1.RollingUpdateStatefulSetStrategyType, @@ -592,12 +594,76 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, enableMaxUnavailablePolicy: true, }, + { + name: "PVCDeletionPolicy disabled", + original: &appsv1.StatefulSet{ + Spec: appsv1.StatefulSetSpec{ + Template: defaultTemplate, + }, + }, + expected: &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, + Spec: appsv1.StatefulSetSpec{ + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PodManagementPolicy: appsv1.OrderedReadyPodManagement, + UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ + Type: appsv1.RollingUpdateStatefulSetStrategyType, + RollingUpdate: &appsv1.RollingUpdateStatefulSetStrategy{ + Partition: &defaultPartition, + }, + }, + RevisionHistoryLimit: ptr.To[int32](10), + }, + }, + disablePVCDeletionPolicy: true, + }, + { + name: "PVCDeletionPolicy disabled, scaledown set", + original: &appsv1.StatefulSet{ + Spec: appsv1.StatefulSetSpec{ + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenScaled: appsv1.DeletePersistentVolumeClaimRetentionPolicyType, + }, + }, + }, + expected: &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, + Spec: appsv1.StatefulSetSpec{ + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenScaled: appsv1.DeletePersistentVolumeClaimRetentionPolicyType, + }, + PodManagementPolicy: appsv1.OrderedReadyPodManagement, + UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ + Type: appsv1.RollingUpdateStatefulSetStrategyType, + RollingUpdate: &appsv1.RollingUpdateStatefulSetStrategy{ + Partition: &defaultPartition, + }, + }, + RevisionHistoryLimit: ptr.To[int32](10), + }, + }, + disablePVCDeletionPolicy: true, + }, } for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, test.enablePVCDeletionPolicy) + if test.disablePVCDeletionPolicy { + // TODO: this will be removed in 1.35 + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.31")) + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, false) + } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MaxUnavailableStatefulSet, test.enableMaxUnavailablePolicy) obj2 := roundTrip(t, runtime.Object(test.original)) diff --git a/pkg/apis/apps/v1beta1/defaults_test.go b/pkg/apis/apps/v1beta1/defaults_test.go index 729748cf5e1..d9019f8adcc 100644 --- a/pkg/apis/apps/v1beta1/defaults_test.go +++ b/pkg/apis/apps/v1beta1/defaults_test.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/version" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -221,11 +222,11 @@ func TestSetDefaultStatefulSet(t *testing.T) { } tests := []struct { - name string - original *appsv1beta1.StatefulSet - expected *appsv1beta1.StatefulSet - enableMaxUnavailablePolicy bool - enableStatefulSetAutoDelete bool + name string + original *appsv1beta1.StatefulSet + expected *appsv1beta1.StatefulSet + enableMaxUnavailablePolicy bool + disablePVCDeletionPolicy bool }{ { name: "labels and default update strategy", @@ -236,9 +237,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, expected: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.OnDeleteStatefulSetStrategyType, @@ -264,9 +269,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, expected: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.RollingUpdateStatefulSetStrategyType, @@ -290,9 +299,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, expected: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta1.ParallelPodManagement, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.OnDeleteStatefulSetStrategyType, @@ -315,8 +328,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, expected: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.OnDeleteStatefulSetStrategyType, @@ -346,8 +363,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, expected: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.OnDeleteStatefulSetStrategyType, @@ -380,8 +401,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, expected: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.OnDeleteStatefulSetStrategyType, @@ -408,8 +433,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, expected: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.OnDeleteStatefulSetStrategyType, @@ -439,8 +468,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, expected: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.OnDeleteStatefulSetStrategyType, @@ -459,41 +492,80 @@ func TestSetDefaultStatefulSet(t *testing.T) { enableMaxUnavailablePolicy: true, }, { - name: "StatefulSetAutoDeletePVC enabled", + name: "PVCDeletionPolicy disabled", original: &appsv1beta1.StatefulSet{ Spec: appsv1beta1.StatefulSetSpec{ Template: defaultTemplate, }, }, expected: &appsv1beta1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, Spec: appsv1beta1.StatefulSetSpec{ Replicas: &defaultReplicas, + MinReadySeconds: int32(0), Template: defaultTemplate, PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ Type: appsv1beta1.OnDeleteStatefulSetStrategyType, RollingUpdate: nil, }, RevisionHistoryLimit: ptr.To[int32](10), + }, + }, + disablePVCDeletionPolicy: true, + }, + { + name: "PVCDeletionPolicy disabled, scaledown set", + original: &appsv1beta1.StatefulSet{ + Spec: appsv1beta1.StatefulSetSpec{ + Template: defaultTemplate, PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ - WhenDeleted: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, - WhenScaled: appsv1beta1.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta1.DeletePersistentVolumeClaimRetentionPolicyType, }, + }, + }, + expected: &appsv1beta1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, + Spec: appsv1beta1.StatefulSetSpec{ + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenScaled: appsv1beta1.DeletePersistentVolumeClaimRetentionPolicyType, + }, + PodManagementPolicy: appsv1beta1.OrderedReadyPodManagement, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, MatchExpressions: []metav1.LabelSelectorRequirement{}, }, + UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{ + Type: appsv1beta1.OnDeleteStatefulSetStrategyType, + RollingUpdate: nil, + }, + RevisionHistoryLimit: ptr.To[int32](10), }, }, - enableStatefulSetAutoDelete: true, + disablePVCDeletionPolicy: true, }, } for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { + if test.disablePVCDeletionPolicy { + // TODO: this will be removed in 1.35 + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.31")) + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, false) + } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MaxUnavailableStatefulSet, test.enableMaxUnavailablePolicy) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, test.enableStatefulSetAutoDelete) obj2 := roundTrip(t, runtime.Object(test.original)) got, ok := obj2.(*appsv1beta1.StatefulSet) if !ok { diff --git a/pkg/apis/apps/v1beta2/defaults_test.go b/pkg/apis/apps/v1beta2/defaults_test.go index 0ad7dbad1f9..43ac5c518bc 100644 --- a/pkg/apis/apps/v1beta2/defaults_test.go +++ b/pkg/apis/apps/v1beta2/defaults_test.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/version" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -196,11 +197,11 @@ func TestSetDefaultStatefulSet(t *testing.T) { } tests := []struct { - name string - original *appsv1beta2.StatefulSet - expected *appsv1beta2.StatefulSet - enableMaxUnavailablePolicy bool - enableStatefulSetAutoDelete bool + name string + original *appsv1beta2.StatefulSet + expected *appsv1beta2.StatefulSet + enableMaxUnavailablePolicy bool + disablePVCDeletionPolicy bool }{ { name: "labels and default update strategy", @@ -214,9 +215,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1beta2.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, @@ -243,9 +248,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1beta2.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ Type: appsv1beta2.OnDeleteStatefulSetStrategyType, @@ -267,9 +276,13 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1beta2.StatefulSetSpec{ - Replicas: &defaultReplicas, - MinReadySeconds: int32(0), - Template: defaultTemplate, + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta2.ParallelPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, @@ -293,8 +306,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1beta2.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, @@ -325,8 +342,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1beta2.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, @@ -358,8 +379,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1beta2.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, @@ -385,8 +410,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1beta2.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, @@ -418,8 +447,12 @@ func TestSetDefaultStatefulSet(t *testing.T) { Labels: defaultLabels, }, Spec: appsv1beta2.StatefulSetSpec{ - Replicas: &defaultReplicas, - Template: defaultTemplate, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + }, PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, @@ -434,7 +467,7 @@ func TestSetDefaultStatefulSet(t *testing.T) { enableMaxUnavailablePolicy: true, }, { - name: "StatefulSetAutoDeletePVC enabled", + name: "PVCDeletionPolicy disabled", original: &appsv1beta2.StatefulSet{ Spec: appsv1beta2.StatefulSetSpec{ Template: defaultTemplate, @@ -446,6 +479,7 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, Spec: appsv1beta2.StatefulSetSpec{ Replicas: &defaultReplicas, + MinReadySeconds: int32(0), Template: defaultTemplate, PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ @@ -455,21 +489,54 @@ func TestSetDefaultStatefulSet(t *testing.T) { }, }, RevisionHistoryLimit: ptr.To[int32](10), + }, + }, + disablePVCDeletionPolicy: true, + }, + { + name: "PVCDeletionPolicy disabled, scaledown set", + original: &appsv1beta2.StatefulSet{ + Spec: appsv1beta2.StatefulSetSpec{ + Template: defaultTemplate, PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ - WhenDeleted: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, - WhenScaled: appsv1beta2.RetainPersistentVolumeClaimRetentionPolicyType, + WhenScaled: appsv1beta2.DeletePersistentVolumeClaimRetentionPolicyType, }, }, }, - enableStatefulSetAutoDelete: true, + expected: &appsv1beta2.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, + Spec: appsv1beta2.StatefulSetSpec{ + Replicas: &defaultReplicas, + MinReadySeconds: int32(0), + Template: defaultTemplate, + PersistentVolumeClaimRetentionPolicy: &appsv1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy{ + WhenScaled: appsv1beta2.DeletePersistentVolumeClaimRetentionPolicyType, + }, + PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, + UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ + Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, + RollingUpdate: &appsv1beta2.RollingUpdateStatefulSetStrategy{ + Partition: &defaultPartition, + }, + }, + RevisionHistoryLimit: ptr.To[int32](10), + }, + }, + disablePVCDeletionPolicy: true, }, } for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { + if test.disablePVCDeletionPolicy { + // TODO: this will be removed in 1.35 + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.31")) + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, false) + } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MaxUnavailableStatefulSet, test.enableMaxUnavailablePolicy) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, test.enableStatefulSetAutoDelete) obj2 := roundTrip(t, runtime.Object(test.original)) got, ok := obj2.(*appsv1beta2.StatefulSet) if !ok { diff --git a/pkg/apis/apps/validation/validation_test.go b/pkg/apis/apps/validation/validation_test.go index 1155fda2413..876a1bafaeb 100644 --- a/pkg/apis/apps/validation/validation_test.go +++ b/pkg/apis/apps/validation/validation_test.go @@ -31,14 +31,11 @@ import ( "k8s.io/apimachinery/pkg/util/dump" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/validation/field" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/api/pod" podtest "k8s.io/kubernetes/pkg/api/pod/testing" "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" corevalidation "k8s.io/kubernetes/pkg/apis/core/validation" - "k8s.io/kubernetes/pkg/features" "k8s.io/utils/ptr" ) @@ -264,8 +261,6 @@ func TestValidateStatefulSet(t *testing.T) { }, } - const enableStatefulSetAutoDeletePVC = "[enable StatefulSetAutoDeletePVC]" - type testCase struct { name string set apps.StatefulSet @@ -295,7 +290,7 @@ func TestValidateStatefulSet(t *testing.T) { tweakRollingUpdatePartition(2), ), }, { - name: "PVC policy " + enableStatefulSetAutoDeletePVC, + name: "PVC policy", set: mkStatefulSet(&validPodTemplate, tweakPVCPolicy(mkPVCPolicy( tweakPVCDeletedPolicy(apps.DeletePersistentVolumeClaimRetentionPolicyType), @@ -466,7 +461,7 @@ func TestValidateStatefulSet(t *testing.T) { field.Forbidden(field.NewPath("spec", "template", "spec", "activeDeadlineSeconds"), ""), }, }, { - name: "empty PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC, + name: "empty PersistentVolumeClaimRetentionPolicy", set: mkStatefulSet(&validPodTemplate, tweakPVCPolicy(mkPVCPolicy()), ), @@ -475,7 +470,7 @@ func TestValidateStatefulSet(t *testing.T) { field.NotSupported[string](field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil), }, }, { - name: "invalid PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC, + name: "invalid PersistentVolumeClaimRetentionPolicy", set: mkStatefulSet(&validPodTemplate, tweakPVCPolicy(mkPVCPolicy( tweakPVCDeletedPolicy("invalid-retention-policy"), @@ -539,10 +534,6 @@ func TestValidateStatefulSet(t *testing.T) { } t.Run(testTitle, func(t *testing.T) { - if strings.Contains(name, enableStatefulSetAutoDeletePVC) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true) - } - errs := ValidateStatefulSet(&testCase.set, pod.GetValidationOptionsFromPodTemplate(&testCase.set.Spec.Template, nil)) wantErrs := testCase.errs if diff := cmp.Diff(wantErrs, errs, cmpOpts...); diff != "" { diff --git a/pkg/controller/statefulset/stateful_pod_control_test.go b/pkg/controller/statefulset/stateful_pod_control_test.go index fd4447e6fe9..6925b53e4c7 100644 --- a/pkg/controller/statefulset/stateful_pod_control_test.go +++ b/pkg/controller/statefulset/stateful_pod_control_test.go @@ -30,6 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/version" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/kubernetes/fake" corelisters "k8s.io/client-go/listers/core/v1" @@ -540,10 +541,9 @@ func TestStatefulPodControlClaimsMatchDeletionPolcy(t *testing.T) { func TestStatefulPodControlUpdatePodClaimForRetentionPolicy(t *testing.T) { // All the update conditions are tested exhaustively in stateful_set_utils_test. This // tests the wiring from the pod control to that method. + testFn := func(t *testing.T) { _, ctx := ktesting.NewTestContext(t) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true) - testCases := []struct { name string ownerRef []metav1.OwnerReference @@ -589,8 +589,10 @@ func TestStatefulPodControlUpdatePodClaimForRetentionPolicy(t *testing.T) { WhenDeleted: apps.DeletePersistentVolumeClaimRetentionPolicyType, WhenScaled: apps.RetainPersistentVolumeClaimRetentionPolicyType, } - if err := control.UpdatePodClaimForRetentionPolicy(ctx, set, pod0); err != nil { - t.Errorf("Unexpected error for UpdatePodClaimForRetentionPolicy (retain), pod0: %v", err) + if utilfeature.DefaultFeatureGate.Enabled(features.StatefulSetAutoDeletePVC) { + if err := control.UpdatePodClaimForRetentionPolicy(ctx, set, pod0); err != nil { + t.Errorf("Unexpected error for UpdatePodClaimForRetentionPolicy (retain), pod0: %v", err) + } } expectRef := tc.expectRef && utilfeature.DefaultFeatureGate.Enabled(features.StatefulSetAutoDeletePVC) for k := range claims0 { @@ -609,6 +611,8 @@ func TestStatefulPodControlUpdatePodClaimForRetentionPolicy(t *testing.T) { testFn(t) }) t.Run("StatefulSetAutoDeletePVCDisabled", func(t *testing.T) { + // TODO: this will be removed in 1.35 + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.31")) featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, false) testFn(t) }) @@ -740,7 +744,9 @@ func TestStatefulPodControlRetainDeletionPolicyUpdate(t *testing.T) { podLister := corelisters.NewPodLister(podIndexer) claimIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) claimLister := corelisters.NewPersistentVolumeClaimLister(claimIndexer) - podIndexer.Add(pod) + if err := podIndexer.Add(pod); err != nil { + t.Errorf("couldn't add %s to index: %v", pod.GetName(), err) + } claims := getPersistentVolumeClaims(set, pod) if len(claims) < 1 { t.Errorf("Unexpected missing PVCs") @@ -749,7 +755,9 @@ func TestStatefulPodControlRetainDeletionPolicyUpdate(t *testing.T) { claim := claims[k] // This ownerRef should be removed in the update. claim.SetOwnerReferences(addControllerRef(claim.GetOwnerReferences(), set, controllerKind)) - claimIndexer.Add(&claim) + if err := claimIndexer.Add(&claim); err != nil { + t.Errorf("couldn't add %s to index: %v", claim.GetName(), err) + } } control := NewStatefulPodControl(fakeClient, podLister, claimLister, recorder) if err := control.UpdateStatefulPod(ctx, set, pod); err != nil { @@ -777,6 +785,8 @@ func TestStatefulPodControlRetainDeletionPolicyUpdate(t *testing.T) { testFn(t) }) t.Run("StatefulSetAutoDeletePVCDisabled", func(t *testing.T) { + // TODO: this will be removed in 1.35 + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.31")) featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, false) testFn(t) }) @@ -784,8 +794,6 @@ func TestStatefulPodControlRetainDeletionPolicyUpdate(t *testing.T) { func TestStatefulPodControlRetentionPolicyUpdate(t *testing.T) { _, ctx := ktesting.NewTestContext(t) - // Only applicable when the feature gate is on; the off case is tested in TestStatefulPodControlRetainRetentionPolicyUpdate. - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true) recorder := record.NewFakeRecorder(10) set := newStatefulSet(1) @@ -833,8 +841,6 @@ func TestStatefulPodControlRetentionPolicyUpdate(t *testing.T) { func TestStatefulPodControlRetentionPolicyUpdateMissingClaims(t *testing.T) { _, ctx := ktesting.NewTestContext(t) - // Only applicable when the feature gate is on. - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true) recorder := record.NewFakeRecorder(10) set := newStatefulSet(1) diff --git a/pkg/controller/statefulset/stateful_set_control_test.go b/pkg/controller/statefulset/stateful_set_control_test.go index 3fc41e1553c..f5bb2a44b1b 100644 --- a/pkg/controller/statefulset/stateful_set_control_test.go +++ b/pkg/controller/statefulset/stateful_set_control_test.go @@ -101,13 +101,14 @@ func runTestOverPVCRetentionPolicies(t *testing.T, testName string, testFn func( subtestName = fmt.Sprintf("%s/%s", testName, subtestName) } t.Run(subtestName, func(t *testing.T) { + // TODO: this will be removed in 1.35 + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, utilversion.MustParse("1.31")) featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, false) testFn(t, &apps.StatefulSetPersistentVolumeClaimRetentionPolicy{ WhenScaled: apps.RetainPersistentVolumeClaimRetentionPolicyType, WhenDeleted: apps.RetainPersistentVolumeClaimRetentionPolicyType, }) }) - for _, policy := range []*apps.StatefulSetPersistentVolumeClaimRetentionPolicy{ { WhenScaled: apps.RetainPersistentVolumeClaimRetentionPolicyType, @@ -133,7 +134,6 @@ func runTestOverPVCRetentionPolicies(t *testing.T, testName string, testFn func( subtestName = fmt.Sprintf("%s/%s", testName, subtestName) } t.Run(subtestName, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true) testFn(t, policy) }) } diff --git a/pkg/controller/statefulset/stateful_set_test.go b/pkg/controller/statefulset/stateful_set_test.go index 8e834bd5e2b..8cd58752518 100644 --- a/pkg/controller/statefulset/stateful_set_test.go +++ b/pkg/controller/statefulset/stateful_set_test.go @@ -32,17 +32,14 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/strategicpatch" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes/fake" core "k8s.io/client-go/testing" "k8s.io/client-go/tools/cache" - featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/klog/v2" "k8s.io/klog/v2/ktesting" "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller/history" - "k8s.io/kubernetes/pkg/features" ) var parentKind = apps.SchemeGroupVersion.WithKind("StatefulSet") @@ -669,8 +666,6 @@ func TestGetPodsForStatefulSetRelease(t *testing.T) { } func TestOrphanedPodsWithPVCDeletePolicy(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true) - testFn := func(t *testing.T, scaledownPolicy, deletionPolicy apps.PersistentVolumeClaimRetentionPolicyType) { set := newStatefulSet(4) *set.Spec.Replicas = 2 @@ -804,8 +799,6 @@ func TestOrphanedPodsWithPVCDeletePolicy(t *testing.T) { } func TestStaleOwnerRefOnScaleup(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true) - for _, policy := range []*apps.StatefulSetPersistentVolumeClaimRetentionPolicy{ { WhenScaled: apps.DeletePersistentVolumeClaimRetentionPolicyType, diff --git a/pkg/features/versioned_kube_features.go b/pkg/features/versioned_kube_features.go index df9c7ab6430..8d656ad30ff 100644 --- a/pkg/features/versioned_kube_features.go +++ b/pkg/features/versioned_kube_features.go @@ -695,6 +695,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate StatefulSetAutoDeletePVC: { {Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.32, remove in 1.35 }, StatefulSetStartOrdinal: { diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index cc3ea6ed221..7fd42c5d689 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -8168,7 +8168,7 @@ func schema_k8sio_api_apps_v1_StatefulSetSpec(ref common.ReferenceCallback) comm }, "persistentVolumeClaimRetentionPolicy": { SchemaProps: spec.SchemaProps{ - Description: "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is beta.", + Description: "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down.", Ref: ref("k8s.io/api/apps/v1.StatefulSetPersistentVolumeClaimRetentionPolicy"), }, }, @@ -9313,7 +9313,7 @@ func schema_k8sio_api_apps_v1beta1_StatefulSetSpec(ref common.ReferenceCallback) }, "persistentVolumeClaimRetentionPolicy": { SchemaProps: spec.SchemaProps{ - Description: "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates. This requires the StatefulSetAutoDeletePVC feature gate to be enabled.", + Description: "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.", Ref: ref("k8s.io/api/apps/v1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy"), }, }, @@ -11012,7 +11012,7 @@ func schema_k8sio_api_apps_v1beta2_StatefulSetSpec(ref common.ReferenceCallback) }, "persistentVolumeClaimRetentionPolicy": { SchemaProps: spec.SchemaProps{ - Description: "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates. This requires the StatefulSetAutoDeletePVC feature gate to be enabled.", + Description: "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.", Ref: ref("k8s.io/api/apps/v1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy"), }, }, diff --git a/staging/src/k8s.io/api/apps/v1/generated.proto b/staging/src/k8s.io/api/apps/v1/generated.proto index d864f2eebf2..388e638f4df 100644 --- a/staging/src/k8s.io/api/apps/v1/generated.proto +++ b/staging/src/k8s.io/api/apps/v1/generated.proto @@ -737,8 +737,7 @@ message StatefulSetSpec { // volume claims are created as needed and retained until manually deleted. This // policy allows the lifecycle to be altered, for example by deleting persistent // volume claims when their stateful set is deleted, or when their pod is scaled - // down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, - // which is beta. + // down. // +optional optional StatefulSetPersistentVolumeClaimRetentionPolicy persistentVolumeClaimRetentionPolicy = 10; diff --git a/staging/src/k8s.io/api/apps/v1/types.go b/staging/src/k8s.io/api/apps/v1/types.go index e942cd526ec..a68690b4478 100644 --- a/staging/src/k8s.io/api/apps/v1/types.go +++ b/staging/src/k8s.io/api/apps/v1/types.go @@ -142,7 +142,7 @@ const ( // PersistentVolumeClaims associated with StatefulSet VolumeClaimTemplates // will not be deleted. RetainPersistentVolumeClaimRetentionPolicyType PersistentVolumeClaimRetentionPolicyType = "Retain" - // RetentionPersistentVolumeClaimRetentionPolicyType specifies that + // DeletePersistentVolumeClaimRetentionPolicyType specifies that // PersistentVolumeClaims associated with StatefulSet VolumeClaimTemplates // will be deleted in the scenario specified in // StatefulSetPersistentVolumeClaimRetentionPolicy. @@ -255,8 +255,7 @@ type StatefulSetSpec struct { // volume claims are created as needed and retained until manually deleted. This // policy allows the lifecycle to be altered, for example by deleting persistent // volume claims when their stateful set is deleted, or when their pod is scaled - // down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, - // which is beta. + // down. // +optional PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" protobuf:"bytes,10,opt,name=persistentVolumeClaimRetentionPolicy"` diff --git a/staging/src/k8s.io/api/apps/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/apps/v1/types_swagger_doc_generated.go index f3e221a0e95..341ecdadb26 100644 --- a/staging/src/k8s.io/api/apps/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/apps/v1/types_swagger_doc_generated.go @@ -354,7 +354,7 @@ var map_StatefulSetSpec = map[string]string{ "updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.", "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", - "persistentVolumeClaimRetentionPolicy": "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is beta.", + "persistentVolumeClaimRetentionPolicy": "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down.", "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested.", } diff --git a/staging/src/k8s.io/api/apps/v1beta1/generated.proto b/staging/src/k8s.io/api/apps/v1beta1/generated.proto index c601442c5a2..46d7bfdf923 100644 --- a/staging/src/k8s.io/api/apps/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/apps/v1beta1/generated.proto @@ -486,8 +486,7 @@ message StatefulSetSpec { optional int32 minReadySeconds = 9; // PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from - // the StatefulSet VolumeClaimTemplates. This requires the - // StatefulSetAutoDeletePVC feature gate to be enabled. + // the StatefulSet VolumeClaimTemplates. // +optional optional StatefulSetPersistentVolumeClaimRetentionPolicy persistentVolumeClaimRetentionPolicy = 10; diff --git a/staging/src/k8s.io/api/apps/v1beta1/types.go b/staging/src/k8s.io/api/apps/v1beta1/types.go index 6c9fb2cbf94..bc485195781 100644 --- a/staging/src/k8s.io/api/apps/v1beta1/types.go +++ b/staging/src/k8s.io/api/apps/v1beta1/types.go @@ -181,11 +181,11 @@ const ( // PersistentVolumeClaims associated with StatefulSet VolumeClaimTemplates // will not be deleted. RetainPersistentVolumeClaimRetentionPolicyType PersistentVolumeClaimRetentionPolicyType = "Retain" - // RetentionPersistentVolumeClaimRetentionPolicyType specifies that + // DeletePersistentVolumeClaimRetentionPolicyType specifies that // PersistentVolumeClaims associated with StatefulSet VolumeClaimTemplates // will be deleted in the scenario specified in // StatefulSetPersistentVolumeClaimRetentionPolicy. - RetentionPersistentVolumeClaimRetentionPolicyType PersistentVolumeClaimRetentionPolicyType = "Delete" + DeletePersistentVolumeClaimRetentionPolicyType PersistentVolumeClaimRetentionPolicyType = "Delete" ) // StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs @@ -290,8 +290,7 @@ type StatefulSetSpec struct { MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,9,opt,name=minReadySeconds"` // PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from - // the StatefulSet VolumeClaimTemplates. This requires the - // StatefulSetAutoDeletePVC feature gate to be enabled. + // the StatefulSet VolumeClaimTemplates. // +optional PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" protobuf:"bytes,10,opt,name=persistentVolumeClaimRetentionPolicy"` diff --git a/staging/src/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go index 4740cb9b297..1381d75dc04 100644 --- a/staging/src/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go @@ -258,7 +258,7 @@ var map_StatefulSetSpec = map[string]string{ "updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.", "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", "minReadySeconds": "minReadySeconds is the minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", - "persistentVolumeClaimRetentionPolicy": "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates. This requires the StatefulSetAutoDeletePVC feature gate to be enabled.", + "persistentVolumeClaimRetentionPolicy": "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.", "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested.", } diff --git a/staging/src/k8s.io/api/apps/v1beta2/generated.proto b/staging/src/k8s.io/api/apps/v1beta2/generated.proto index 371f6aa8307..c08a4c78bc9 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/generated.proto +++ b/staging/src/k8s.io/api/apps/v1beta2/generated.proto @@ -778,8 +778,7 @@ message StatefulSetSpec { optional int32 minReadySeconds = 9; // PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from - // the StatefulSet VolumeClaimTemplates. This requires the - // StatefulSetAutoDeletePVC feature gate to be enabled. + // the StatefulSet VolumeClaimTemplates. // +optional optional StatefulSetPersistentVolumeClaimRetentionPolicy persistentVolumeClaimRetentionPolicy = 10; diff --git a/staging/src/k8s.io/api/apps/v1beta2/types.go b/staging/src/k8s.io/api/apps/v1beta2/types.go index 23048124857..c2624a941df 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/types.go +++ b/staging/src/k8s.io/api/apps/v1beta2/types.go @@ -191,11 +191,11 @@ const ( // PersistentVolumeClaims associated with StatefulSet VolumeClaimTemplates // will not be deleted. RetainPersistentVolumeClaimRetentionPolicyType PersistentVolumeClaimRetentionPolicyType = "Retain" - // RetentionPersistentVolumeClaimRetentionPolicyType specifies that + // DeletePersistentVolumeClaimRetentionPolicyType specifies that // PersistentVolumeClaims associated with StatefulSet VolumeClaimTemplates // will be deleted in the scenario specified in // StatefulSetPersistentVolumeClaimRetentionPolicy. - RetentionPersistentVolumeClaimRetentionPolicyType PersistentVolumeClaimRetentionPolicyType = "Delete" + DeletePersistentVolumeClaimRetentionPolicyType PersistentVolumeClaimRetentionPolicyType = "Delete" ) // StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs @@ -300,8 +300,7 @@ type StatefulSetSpec struct { MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,9,opt,name=minReadySeconds"` // PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from - // the StatefulSet VolumeClaimTemplates. This requires the - // StatefulSetAutoDeletePVC feature gate to be enabled. + // the StatefulSet VolumeClaimTemplates. // +optional PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" protobuf:"bytes,10,opt,name=persistentVolumeClaimRetentionPolicy"` diff --git a/staging/src/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go b/staging/src/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go index 30ec9fa8106..beec4b7555a 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go @@ -382,7 +382,7 @@ var map_StatefulSetSpec = map[string]string{ "updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.", "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", - "persistentVolumeClaimRetentionPolicy": "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates. This requires the StatefulSetAutoDeletePVC feature gate to be enabled.", + "persistentVolumeClaimRetentionPolicy": "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.", "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested.", } diff --git a/test/featuregates_linter/test_data/versioned_feature_list.yaml b/test/featuregates_linter/test_data/versioned_feature_list.yaml index eec43e298dc..39412962bde 100644 --- a/test/featuregates_linter/test_data/versioned_feature_list.yaml +++ b/test/featuregates_linter/test_data/versioned_feature_list.yaml @@ -1188,6 +1188,10 @@ lockToDefault: false preRelease: Beta version: "1.27" + - default: true + lockToDefault: true + preRelease: GA + version: "1.32" - name: StatefulSetStartOrdinal versionedSpecs: - default: false