From b0919d81a0c8c1f002a28797e701f66901c6a76b Mon Sep 17 00:00:00 2001 From: Daniel Fajmon Date: Fri, 13 Feb 2026 11:00:09 +0100 Subject: [PATCH] Promote SELinuxChangePolicy & SELinuxMountReadWriteOncePod to GA --- pkg/api/pod/util_test.go | 5 ++++- pkg/apis/storage/v1/defaults_test.go | 3 ++- pkg/apis/storage/v1beta1/defaults_test.go | 3 ++- pkg/apis/storage/validation/validation_test.go | 11 +++++++---- .../selinuxwarning/selinux_warning_controller_test.go | 5 ----- pkg/features/kube_features.go | 2 ++ pkg/registry/storage/csidriver/strategy_test.go | 2 +- pkg/volume/csi/csi_mounter_test.go | 4 ++++ pkg/volume/csi/csi_plugin_test.go | 3 +++ pkg/volume/util/selinux_test.go | 6 +++++- .../compatibility_lifecycle/reference/feature_list.md | 4 ++-- .../reference/versioned_feature_list.yaml | 8 ++++++++ 12 files changed, 40 insertions(+), 16 deletions(-) diff --git a/pkg/api/pod/util_test.go b/pkg/api/pod/util_test.go index 3701535c049..1dd6b7518cd 100644 --- a/pkg/api/pod/util_test.go +++ b/pkg/api/pod/util_test.go @@ -4380,7 +4380,10 @@ func TestDropSELinuxChangePolicy(t *testing.T) { } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - + // un-lock locked feature gates, if necessary + if !sets.New(tc.gates...).Has(features.SELinuxChangePolicy) { + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.35")) + } // Set feature gates for the test. *Disable* those that are not in tc.gates. allGates := []featuregate.Feature{features.SELinuxChangePolicy, features.SELinuxMount} enabledGates := sets.New(tc.gates...) diff --git a/pkg/apis/storage/v1/defaults_test.go b/pkg/apis/storage/v1/defaults_test.go index ecb99686a12..ea295aa1e3f 100644 --- a/pkg/apis/storage/v1/defaults_test.go +++ b/pkg/apis/storage/v1/defaults_test.go @@ -23,6 +23,7 @@ import ( "github.com/google/go-cmp/cmp" storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/runtime" + "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" @@ -122,7 +123,6 @@ func TestSetDefaultCSIDriver(t *testing.T) { } func TestSetDefaultSELinuxMountReadWriteOncePodEnabled(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) driver := &storagev1.CSIDriver{} // field should be defaulted @@ -137,6 +137,7 @@ func TestSetDefaultSELinuxMountReadWriteOncePodEnabled(t *testing.T) { } func TestSetDefaultSELinuxMountReadWriteOncePodDisabled(t *testing.T) { + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.35")) featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, false) driver := &storagev1.CSIDriver{} diff --git a/pkg/apis/storage/v1beta1/defaults_test.go b/pkg/apis/storage/v1beta1/defaults_test.go index cf1ce6003b4..cd40fc1ee5c 100644 --- a/pkg/apis/storage/v1beta1/defaults_test.go +++ b/pkg/apis/storage/v1beta1/defaults_test.go @@ -23,6 +23,7 @@ import ( "github.com/google/go-cmp/cmp" storagev1beta1 "k8s.io/api/storage/v1beta1" "k8s.io/apimachinery/pkg/runtime" + "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" @@ -152,7 +153,6 @@ func TestSetDefaultCSIDriver(t *testing.T) { } func TestSetDefaultSELinuxMountReadWriteOncePodEnabled(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) driver := &storagev1beta1.CSIDriver{} // field should be defaulted @@ -167,6 +167,7 @@ func TestSetDefaultSELinuxMountReadWriteOncePodEnabled(t *testing.T) { } func TestSetDefaultSELinuxMountReadWriteOncePodDisabled(t *testing.T) { + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.35")) featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, false) driver := &storagev1beta1.CSIDriver{} diff --git a/pkg/apis/storage/validation/validation_test.go b/pkg/apis/storage/validation/validation_test.go index fe54ebb2eb4..839e3bae6b9 100644 --- a/pkg/apis/storage/validation/validation_test.go +++ b/pkg/apis/storage/validation/validation_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/version" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" api "k8s.io/kubernetes/pkg/apis/core" @@ -1502,8 +1503,6 @@ func TestCSINodeUpdateValidation(t *testing.T) { } func TestCSIDriverValidation(t *testing.T) { - // assume this feature is on for this test, detailed enabled/disabled tests in TestCSIDriverValidationSELinuxMountEnabledDisabled - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) // assume this feature is on for this test, detailed enabled/disabled tests in TestMutableCSINodeAllocatableCountEnabledDisabled featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MutableCSINodeAllocatableCount, true) @@ -1840,8 +1839,6 @@ func TestCSIDriverValidation(t *testing.T) { } func TestCSIDriverValidationUpdate(t *testing.T) { - // assume this feature is on for this test, detailed enabled/disabled tests in TestCSIDriverValidationSELinuxMountEnabledDisabled - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) // assume this feature is on for this test, detailed enabled/disabled tests in TestMutableCSINodeAllocatableCountEnabledDisabled featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MutableCSINodeAllocatableCount, true) @@ -2288,6 +2285,9 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { }} for _, test := range tests { t.Run(test.name, func(t *testing.T) { + if !test.featureEnabled { + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.35")) + } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, test.featureEnabled) csiDriver := &storage.CSIDriver{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, @@ -2366,6 +2366,9 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { }} for _, test := range updateTests { t.Run(test.name, func(t *testing.T) { + if !test.featureEnabled { + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.35")) + } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, test.featureEnabled) oldCSIDriver := &storage.CSIDriver{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, diff --git a/pkg/controller/volume/selinuxwarning/selinux_warning_controller_test.go b/pkg/controller/volume/selinuxwarning/selinux_warning_controller_test.go index 9d9998bc62a..ccb4c4bfba3 100644 --- a/pkg/controller/volume/selinuxwarning/selinux_warning_controller_test.go +++ b/pkg/controller/volume/selinuxwarning/selinux_warning_controller_test.go @@ -27,17 +27,14 @@ import ( storagev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" - featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/klog/v2" "k8s.io/klog/v2/ktesting" "k8s.io/kubernetes/pkg/controller" volumecache "k8s.io/kubernetes/pkg/controller/volume/selinuxwarning/cache" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" volumetesting "k8s.io/kubernetes/pkg/volume/testing" "k8s.io/utils/ptr" @@ -497,8 +494,6 @@ func TestSELinuxWarningController_Sync(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxChangePolicy, true) - var wg sync.WaitGroup defer wg.Wait() _, ctx := ktesting.NewTestContext(t) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index fd89103983f..3fb6ddbe7e6 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -1710,6 +1710,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate SELinuxChangePolicy: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.39, locked to default in 1.36 }, SELinuxMount: { @@ -1721,6 +1722,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.39, locked to default in 1.36 }, SchedulerAsyncAPICalls: { diff --git a/pkg/registry/storage/csidriver/strategy_test.go b/pkg/registry/storage/csidriver/strategy_test.go index 342acafac6c..93d4e68a21a 100644 --- a/pkg/registry/storage/csidriver/strategy_test.go +++ b/pkg/registry/storage/csidriver/strategy_test.go @@ -456,7 +456,7 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - if !test.csiServiceAccountTokenSecretsEnabled { + if !test.csiServiceAccountTokenSecretsEnabled || !test.seLinuxMountReadWriteOncePodEnabled { featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.35")) } featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ diff --git a/pkg/volume/csi/csi_mounter_test.go b/pkg/volume/csi/csi_mounter_test.go index 1bf5bbd69a4..3fbe9361f34 100644 --- a/pkg/volume/csi/csi_mounter_test.go +++ b/pkg/volume/csi/csi_mounter_test.go @@ -37,6 +37,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/version" utilfeature "k8s.io/apiserver/pkg/util/feature" fakeclient "k8s.io/client-go/kubernetes/fake" clitesting "k8s.io/client-go/testing" @@ -218,6 +219,9 @@ func TestMounterSetUp(t *testing.T) { currentPodInfoMount := true for _, test := range tests { t.Run(test.name, func(t *testing.T) { + if !test.enableSELinuxFeatureGate { + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.35")) + } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, test.enableSELinuxFeatureGate) modes := []storage.VolumeLifecycleMode{ diff --git a/pkg/volume/csi/csi_plugin_test.go b/pkg/volume/csi/csi_plugin_test.go index 5fb0cc17762..16fb2505d02 100644 --- a/pkg/volume/csi/csi_plugin_test.go +++ b/pkg/volume/csi/csi_plugin_test.go @@ -371,6 +371,9 @@ func TestPluginConstructVolumeSpec(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + if !tc.seLinuxMountEnabled { + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, utilversion.MustParse("1.35")) + } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, tc.seLinuxMountEnabled) mounter, err := plug.NewMounter( diff --git a/pkg/volume/util/selinux_test.go b/pkg/volume/util/selinux_test.go index 6e744e8a62a..c036f29c990 100644 --- a/pkg/volume/util/selinux_test.go +++ b/pkg/volume/util/selinux_test.go @@ -21,6 +21,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/version" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/component-base/featuregate" featuregatetesting "k8s.io/component-base/featuregate/testing" @@ -301,10 +302,13 @@ func TestGetMountSELinuxLabel(t *testing.T) { }, } + // Unlock GA feature gates (SELinuxChangePolicy, SELinuxMount) so they can be disabled in tests + featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.35")) + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Arrange - // Set feature gates for the test. *Disable* those that are not in tt.featureGates. + // Set feature gates for the test. allGates := []featuregate.Feature{features.SELinuxChangePolicy, features.SELinuxMount} enabledGates := sets.New(tt.featureGates...) for _, fg := range allGates { diff --git a/test/compatibility_lifecycle/reference/feature_list.md b/test/compatibility_lifecycle/reference/feature_list.md index 76af12ac2d1..45c902cd8a8 100644 --- a/test/compatibility_lifecycle/reference/feature_list.md +++ b/test/compatibility_lifecycle/reference/feature_list.md @@ -163,9 +163,9 @@ | RetryGenerateName | :ballot_box_with_check: 1.31+ | :closed_lock_with_key: 1.32+ | 1.30 | 1.31 | 1.32– | | | [code](https://cs.k8s.io/?q=%5CbRetryGenerateName%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbRetryGenerateName%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | RotateKubeletServerCertificate | :ballot_box_with_check: 1.12+ | | 1.7–1.11 | 1.12– | | | | [code](https://cs.k8s.io/?q=%5CbRotateKubeletServerCertificate%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbRotateKubeletServerCertificate%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | RuntimeClassInImageCriApi | | | 1.29– | | | | | [code](https://cs.k8s.io/?q=%5CbRuntimeClassInImageCriApi%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbRuntimeClassInImageCriApi%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | -| SELinuxChangePolicy | :ballot_box_with_check: 1.33+ | | 1.32 | 1.33– | | | | [code](https://cs.k8s.io/?q=%5CbSELinuxChangePolicy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSELinuxChangePolicy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | +| SELinuxChangePolicy | :ballot_box_with_check: 1.33+ | :closed_lock_with_key: 1.36+ | 1.32 | 1.33–1.35 | 1.36– | | | [code](https://cs.k8s.io/?q=%5CbSELinuxChangePolicy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSELinuxChangePolicy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | SELinuxMount | | | 1.30–1.32 | 1.33– | | | | [code](https://cs.k8s.io/?q=%5CbSELinuxMount%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSELinuxMount%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | -| SELinuxMountReadWriteOncePod | :ballot_box_with_check: 1.28+ | | 1.25–1.26 | 1.27– | | | | [code](https://cs.k8s.io/?q=%5CbSELinuxMountReadWriteOncePod%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSELinuxMountReadWriteOncePod%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | +| SELinuxMountReadWriteOncePod | :ballot_box_with_check: 1.28+ | :closed_lock_with_key: 1.36+ | 1.25–1.26 | 1.27–1.35 | 1.36– | | | [code](https://cs.k8s.io/?q=%5CbSELinuxMountReadWriteOncePod%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSELinuxMountReadWriteOncePod%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | SchedulerAsyncAPICalls | | | | 1.34– | | | | [code](https://cs.k8s.io/?q=%5CbSchedulerAsyncAPICalls%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSchedulerAsyncAPICalls%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | SchedulerAsyncPreemption | :ballot_box_with_check: 1.33+ | | 1.32 | 1.33– | | | | [code](https://cs.k8s.io/?q=%5CbSchedulerAsyncPreemption%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSchedulerAsyncPreemption%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | SchedulerPopFromBackoffQ | :ballot_box_with_check: 1.33+ | | | 1.33– | | | | [code](https://cs.k8s.io/?q=%5CbSchedulerPopFromBackoffQ%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSchedulerPopFromBackoffQ%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | diff --git a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml index ed916ccbb12..2f826ee867d 100644 --- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml +++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml @@ -1601,6 +1601,10 @@ lockToDefault: false preRelease: Beta version: "1.33" + - default: true + lockToDefault: true + preRelease: GA + version: "1.36" - name: SELinuxMount versionedSpecs: - default: false @@ -1625,6 +1629,10 @@ lockToDefault: false preRelease: Beta version: "1.28" + - default: true + lockToDefault: true + preRelease: GA + version: "1.36" - name: SeparateCacheWatchRPC versionedSpecs: - default: true