From 4759d344998afe56c98bfbd019d11f9a6cd461ef Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Wed, 15 Jul 2026 14:47:55 -0400 Subject: [PATCH 1/4] Move VolumeLimitScaling to beta --- pkg/apis/storage/types.go | 2 +- pkg/features/kube_features.go | 3 +++ staging/src/k8s.io/api/storage/v1/types.go | 2 +- staging/src/k8s.io/api/storage/v1beta1/types.go | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/apis/storage/types.go b/pkg/apis/storage/types.go index f32c5268cee..537d85a97c8 100644 --- a/pkg/apis/storage/types.go +++ b/pkg/apis/storage/types.go @@ -474,7 +474,7 @@ type CSIDriverSpec struct { // newly created node may be rejected by the scheduler because of missing CSI driver // information from the node. // - // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // This is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. // Default is "false". // +featureGate=VolumeLimitScaling // +optional diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index a6c888a4e40..46907f81e94 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -1146,6 +1146,8 @@ const ( // owner: @gnufied // kep: https://kep.k8s.io/5030 + // alpha: v1.35 + // beta: v1.37 // // Enables volume limit scaling for CSI drivers. This allows scheduler to // co-ordinate better with cluster-autoscaler for storage limits. @@ -2028,6 +2030,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate VolumeLimitScaling: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.37"), Default: true, PreRelease: featuregate.Beta}, }, WinDSR: { diff --git a/staging/src/k8s.io/api/storage/v1/types.go b/staging/src/k8s.io/api/storage/v1/types.go index 91d9b54420c..689177342ed 100644 --- a/staging/src/k8s.io/api/storage/v1/types.go +++ b/staging/src/k8s.io/api/storage/v1/types.go @@ -501,7 +501,7 @@ type CSIDriverSpec struct { // newly created node may be rejected by the scheduler because of missing CSI driver // information from the node. // - // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // This is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. // Default is "false". // +featureGate=VolumeLimitScaling // +optional diff --git a/staging/src/k8s.io/api/storage/v1beta1/types.go b/staging/src/k8s.io/api/storage/v1beta1/types.go index ee0d11033d2..d6f628b30df 100644 --- a/staging/src/k8s.io/api/storage/v1beta1/types.go +++ b/staging/src/k8s.io/api/storage/v1beta1/types.go @@ -514,7 +514,7 @@ type CSIDriverSpec struct { // newly created node may be rejected by the scheduler because of missing CSI driver // information from the node. // - // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // This is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. // Default is "false". // +featureGate=VolumeLimitScaling // +optional From 55a7b8edce06adb6c71c9dc94f2be08f14cfcc44 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Wed, 15 Jul 2026 14:48:05 -0400 Subject: [PATCH 2/4] Update generated files --- api/openapi-spec/swagger.json | 2 +- api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json | 2 +- pkg/generated/openapi/zz_generated.openapi.go | 4 ++-- staging/src/k8s.io/api/storage/v1/generated.proto | 2 +- .../src/k8s.io/api/storage/v1/types_swagger_doc_generated.go | 2 +- staging/src/k8s.io/api/storage/v1beta1/generated.proto | 2 +- .../k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go | 2 +- .../client-go/applyconfigurations/storage/v1/csidriverspec.go | 2 +- .../applyconfigurations/storage/v1beta1/csidriverspec.go | 2 +- test/compatibility_lifecycle/reference/feature_list.md | 2 +- .../reference/versioned_feature_list.yaml | 4 ++++ 11 files changed, 15 insertions(+), 11 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 9b9df528a27..9996a8eddd4 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -20201,7 +20201,7 @@ "type": "boolean" }, "preventPodSchedulingIfMissing": { - "description": "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", + "description": "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", "type": "boolean" }, "requiresRepublish": { diff --git a/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json index 07eb448dfbc..a60df861920 100644 --- a/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json @@ -1268,7 +1268,7 @@ "type": "boolean" }, "preventPodSchedulingIfMissing": { - "description": "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", + "description": "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", "type": "boolean" }, "requiresRepublish": { diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 6af2d9f5296..0e46bf283af 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -55248,7 +55248,7 @@ func schema_k8sio_api_storage_v1_CSIDriverSpec(ref common.ReferenceCallback) com }, "preventPodSchedulingIfMissing": { SchemaProps: spec.SchemaProps{ - Description: "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", + Description: "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", Type: []string{"boolean"}, Format: "", }, @@ -56820,7 +56820,7 @@ func schema_k8sio_api_storage_v1beta1_CSIDriverSpec(ref common.ReferenceCallback }, "preventPodSchedulingIfMissing": { SchemaProps: spec.SchemaProps{ - Description: "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", + Description: "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", Type: []string{"boolean"}, Format: "", }, diff --git a/staging/src/k8s.io/api/storage/v1/generated.proto b/staging/src/k8s.io/api/storage/v1/generated.proto index 4531ebca76b..e2fe1bc47b4 100644 --- a/staging/src/k8s.io/api/storage/v1/generated.proto +++ b/staging/src/k8s.io/api/storage/v1/generated.proto @@ -267,7 +267,7 @@ message CSIDriverSpec { // newly created node may be rejected by the scheduler because of missing CSI driver // information from the node. // - // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // This is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. // Default is "false". // +featureGate=VolumeLimitScaling // +optional diff --git a/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go index f33f55e24e1..23cae1dfebb 100644 --- a/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go @@ -59,7 +59,7 @@ var map_CSIDriverSpec = map[string]string{ "seLinuxMount": "seLinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", "nodeAllocatableUpdatePeriodSeconds": "nodeAllocatableUpdatePeriodSeconds specifies the interval between periodic updates of the CSINode allocatable capacity for this driver. When set, both periodic updates and updates triggered by capacity-related failures are enabled. If not set, no updates occur (neither periodic nor upon detecting capacity-related failures), and the allocatable.count remains static. The minimum allowed value for this field is 10 seconds.\n\nThis feature requires the MutableCSINodeAllocatableCount feature gate to be enabled.\n\nThis field is mutable.", "serviceAccountTokenInSecrets": "serviceAccountTokenInSecrets is an opt-in for CSI drivers to indicate that service account tokens should be passed via the Secrets field in NodePublishVolumeRequest instead of the VolumeContext field. The CSI specification provides a dedicated Secrets field for sensitive information like tokens, which is the appropriate mechanism for handling credentials. This addresses security concerns where sensitive tokens were being logged as part of volume context.\n\nWhen \"true\", kubelet will pass the tokens only in the Secrets field with the key \"csi.storage.k8s.io/serviceAccount.tokens\". The CSI driver must be updated to read tokens from the Secrets field instead of VolumeContext.\n\nWhen \"false\" or not set, kubelet will pass the tokens in VolumeContext with the key \"csi.storage.k8s.io/serviceAccount.tokens\" (existing behavior). This maintains backward compatibility with existing CSI drivers.\n\nThis field can only be set when TokenRequests is configured. The API server will reject CSIDriver specs that set this field without TokenRequests.\n\nDefault behavior if unset is to pass tokens in the VolumeContext field.", - "preventPodSchedulingIfMissing": "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", + "preventPodSchedulingIfMissing": "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", } func (CSIDriverSpec) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/api/storage/v1beta1/generated.proto b/staging/src/k8s.io/api/storage/v1beta1/generated.proto index 14f7c013897..e3a1582433a 100644 --- a/staging/src/k8s.io/api/storage/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/storage/v1beta1/generated.proto @@ -269,7 +269,7 @@ message CSIDriverSpec { // newly created node may be rejected by the scheduler because of missing CSI driver // information from the node. // - // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // This is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. // Default is "false". // +featureGate=VolumeLimitScaling // +optional diff --git a/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go index 40fcac6f130..61c1b94a12c 100644 --- a/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go @@ -59,7 +59,7 @@ var map_CSIDriverSpec = map[string]string{ "seLinuxMount": "seLinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", "nodeAllocatableUpdatePeriodSeconds": "nodeAllocatableUpdatePeriodSeconds specifies the interval between periodic updates of the CSINode allocatable capacity for this driver. When set, both periodic updates and updates triggered by capacity-related failures are enabled. If not set, no updates occur (neither periodic nor upon detecting capacity-related failures), and the allocatable.count remains static. The minimum allowed value for this field is 10 seconds.\n\nThis is a beta feature and requires the MutableCSINodeAllocatableCount feature gate to be enabled.\n\nThis field is mutable.", "serviceAccountTokenInSecrets": "serviceAccountTokenInSecrets is an opt-in for CSI drivers to indicate that service account tokens should be passed via the Secrets field in NodePublishVolumeRequest instead of the VolumeContext field. The CSI specification provides a dedicated Secrets field for sensitive information like tokens, which is the appropriate mechanism for handling credentials. This addresses security concerns where sensitive tokens were being logged as part of volume context.\n\nWhen \"true\", kubelet will pass the tokens only in the Secrets field with the key \"csi.storage.k8s.io/serviceAccount.tokens\". The CSI driver must be updated to read tokens from the Secrets field instead of VolumeContext.\n\nWhen \"false\" or not set, kubelet will pass the tokens in VolumeContext with the key \"csi.storage.k8s.io/serviceAccount.tokens\" (existing behavior). This maintains backward compatibility with existing CSI drivers.\n\nThis field can only be set when TokenRequests is configured. The API server will reject CSIDriver specs that set this field without TokenRequests.\n\nDefault behavior if unset is to pass tokens in the VolumeContext field.", - "preventPodSchedulingIfMissing": "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", + "preventPodSchedulingIfMissing": "preventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", } func (CSIDriverSpec) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go b/staging/src/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go index 4a3d9103462..839b714167a 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go @@ -193,7 +193,7 @@ type CSIDriverSpecApplyConfiguration struct { // newly created node may be rejected by the scheduler because of missing CSI driver // information from the node. // - // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // This is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. // Default is "false". PreventPodSchedulingIfMissing *bool `json:"preventPodSchedulingIfMissing,omitempty"` } diff --git a/staging/src/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go b/staging/src/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go index a1057282178..624fad712cb 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go @@ -193,7 +193,7 @@ type CSIDriverSpecApplyConfiguration struct { // newly created node may be rejected by the scheduler because of missing CSI driver // information from the node. // - // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // This is a beta feature and requires the VolumeLimitScaling feature gate to be enabled. // Default is "false". PreventPodSchedulingIfMissing *bool `json:"preventPodSchedulingIfMissing,omitempty"` } diff --git a/test/compatibility_lifecycle/reference/feature_list.md b/test/compatibility_lifecycle/reference/feature_list.md index 2bedae4d793..98e03557585 100644 --- a/test/compatibility_lifecycle/reference/feature_list.md +++ b/test/compatibility_lifecycle/reference/feature_list.md @@ -218,7 +218,7 @@ | UserNamespacesHostNetworkSupport | | | 1.35– | | | | NodeDeclaredFeatures
UserNamespacesSupport | [code](https://cs.k8s.io/?q=%5CbUserNamespacesHostNetworkSupport%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbUserNamespacesHostNetworkSupport%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | UserNamespacesSupport | :ballot_box_with_check: 1.33+ | :closed_lock_with_key: 1.36+ | 1.25–1.29 | 1.30–1.35 | 1.36– | | | [code](https://cs.k8s.io/?q=%5CbUserNamespacesSupport%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbUserNamespacesSupport%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | VolumeAttributesClass | :ballot_box_with_check: 1.34+ | :closed_lock_with_key: 1.36+ | 1.29–1.30 | 1.31–1.33 | 1.34– | | | [code](https://cs.k8s.io/?q=%5CbVolumeAttributesClass%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbVolumeAttributesClass%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | -| VolumeLimitScaling | | | 1.35– | | | | | [code](https://cs.k8s.io/?q=%5CbVolumeLimitScaling%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbVolumeLimitScaling%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | +| VolumeLimitScaling | :ballot_box_with_check: 1.37+ | | 1.35–1.36 | 1.37– | | | | [code](https://cs.k8s.io/?q=%5CbVolumeLimitScaling%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbVolumeLimitScaling%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | WatchCacheInitializationPostStartHook | :ballot_box_with_check: 1.36+ | :closed_lock_with_key: 1.37+ | | 1.31–1.36 | 1.37– | | | [code](https://cs.k8s.io/?q=%5CbWatchCacheInitializationPostStartHook%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbWatchCacheInitializationPostStartHook%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | WatchList | :ballot_box_with_check: 1.32+ | | 1.27–1.31 | 1.32– | | | | [code](https://cs.k8s.io/?q=%5CbWatchList%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbWatchList%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | WatchListClient | :ballot_box_with_check: 1.35+ | | | 1.30– | | | | [code](https://cs.k8s.io/?q=%5CbWatchListClient%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbWatchListClient%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 af9c00f6636..5516b7bd517 100644 --- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml +++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml @@ -2057,6 +2057,10 @@ lockToDefault: false preRelease: Alpha version: "1.35" + - default: true + lockToDefault: false + preRelease: Beta + version: "1.37" - name: WatchCacheInitializationPostStartHook versionedSpecs: - default: false From 1b512e3ddaac36e8cf32fcd73d8b28834696abf7 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Wed, 15 Jul 2026 17:13:31 -0400 Subject: [PATCH 3/4] Fix declarative validation and defaulting tests --- pkg/apis/storage/v1beta1/defaults.go | 4 +++ pkg/apis/storage/v1beta1/defaults_test.go | 27 +++++++++++++++ .../storage/validation/validation_test.go | 33 +++++++++++-------- .../storage/csidriver/storage/storage_test.go | 24 ++++++++------ .../csidriver/declarative_validation_test.go | 9 ++--- 5 files changed, 69 insertions(+), 28 deletions(-) diff --git a/pkg/apis/storage/v1beta1/defaults.go b/pkg/apis/storage/v1beta1/defaults.go index 75a39a5fd64..6b3b21e3fec 100644 --- a/pkg/apis/storage/v1beta1/defaults.go +++ b/pkg/apis/storage/v1beta1/defaults.go @@ -68,4 +68,8 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) { obj.Spec.SELinuxMount = new(bool) *(obj.Spec.SELinuxMount) = false } + if obj.Spec.PreventPodSchedulingIfMissing == nil && utilfeature.DefaultFeatureGate.Enabled(features.VolumeLimitScaling) { + obj.Spec.PreventPodSchedulingIfMissing = new(bool) + *(obj.Spec.PreventPodSchedulingIfMissing) = false + } } diff --git a/pkg/apis/storage/v1beta1/defaults_test.go b/pkg/apis/storage/v1beta1/defaults_test.go index cd40fc1ee5c..e892a37f243 100644 --- a/pkg/apis/storage/v1beta1/defaults_test.go +++ b/pkg/apis/storage/v1beta1/defaults_test.go @@ -178,3 +178,30 @@ func TestSetDefaultSELinuxMountReadWriteOncePodDisabled(t *testing.T) { t.Errorf("Expected SELinuxMount remain nil, got: %+v", outSELinuxMount) } } + +func TestSetDefaultPreventPodSchedulingIfMissingVolumeLimitScalingEnabled(t *testing.T) { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeLimitScaling, true) + driver := &storagev1beta1.CSIDriver{} + + // field should be defaulted + defaultPreventPodSchedulingIfMissing := false + output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver) + outPreventPodSchedulingIfMissing := output.Spec.PreventPodSchedulingIfMissing + if outPreventPodSchedulingIfMissing == nil { + t.Errorf("Expected PreventPodSchedulingIfMissing to be defaulted to: %+v, got: nil", defaultPreventPodSchedulingIfMissing) + } else if *outPreventPodSchedulingIfMissing != defaultPreventPodSchedulingIfMissing { + t.Errorf("Expected PreventPodSchedulingIfMissing to be defaulted to: %+v, got: %+v", defaultPreventPodSchedulingIfMissing, *outPreventPodSchedulingIfMissing) + } +} + +func TestSetDefaultPreventPodSchedulingIfMissingVolumeLimitScalingDisabled(t *testing.T) { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeLimitScaling, false) + driver := &storagev1beta1.CSIDriver{} + + // field should not be defaulted + output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver) + outPreventPodSchedulingIfMissing := output.Spec.PreventPodSchedulingIfMissing + if outPreventPodSchedulingIfMissing != nil { + t.Errorf("Expected PreventPodSchedulingIfMissing to remain nil, got: %+v", *outPreventPodSchedulingIfMissing) + } +} diff --git a/pkg/apis/storage/validation/validation_test.go b/pkg/apis/storage/validation/validation_test.go index 58dc3c9ba5e..5c2f91fb5c9 100644 --- a/pkg/apis/storage/validation/validation_test.go +++ b/pkg/apis/storage/validation/validation_test.go @@ -2093,13 +2093,15 @@ func TestCSIDriverStorageCapacityEnablement(t *testing.T) { requiresRepublish := true storageCapacity := true seLinuxMount := false + preventPodSchedulingIfMissing := false csiDriver := storage.CSIDriver{ ObjectMeta: metav1.ObjectMeta{Name: driverName}, Spec: storage.CSIDriverSpec{ - AttachRequired: &attachRequired, - PodInfoOnMount: &podInfoOnMount, - RequiresRepublish: &requiresRepublish, - SELinuxMount: &seLinuxMount, + AttachRequired: &attachRequired, + PodInfoOnMount: &podInfoOnMount, + RequiresRepublish: &requiresRepublish, + SELinuxMount: &seLinuxMount, + PreventPodSchedulingIfMissing: &preventPodSchedulingIfMissing, }, } if withField { @@ -2286,6 +2288,7 @@ func TestCSIServiceAccountToken(t *testing.T) { test.csiDriver.Spec.PodInfoOnMount = new(bool) test.csiDriver.Spec.StorageCapacity = new(bool) test.csiDriver.Spec.SELinuxMount = new(bool) + test.csiDriver.Spec.PreventPodSchedulingIfMissing = new(bool) if errs := ValidateCSIDriver(test.csiDriver); test.wantErr != (len(errs) != 0) { t.Errorf("ValidateCSIDriver = %v, want err: %v", errs, test.wantErr) } @@ -2328,11 +2331,12 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { csiDriver := &storage.CSIDriver{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: storage.CSIDriverSpec{ - AttachRequired: ptr.To(true), - PodInfoOnMount: ptr.To(true), - RequiresRepublish: ptr.To(true), - StorageCapacity: ptr.To(true), - SELinuxMount: test.seLinuxMountValue, + AttachRequired: ptr.To(true), + PodInfoOnMount: ptr.To(true), + RequiresRepublish: ptr.To(true), + StorageCapacity: ptr.To(true), + SELinuxMount: test.seLinuxMountValue, + PreventPodSchedulingIfMissing: new(false), }, } err := ValidateCSIDriver(csiDriver) @@ -2409,11 +2413,12 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { oldCSIDriver := &storage.CSIDriver{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: storage.CSIDriverSpec{ - AttachRequired: ptr.To(true), - PodInfoOnMount: ptr.To(true), - RequiresRepublish: ptr.To(true), - StorageCapacity: ptr.To(true), - SELinuxMount: test.oldValue, + AttachRequired: ptr.To(true), + PodInfoOnMount: ptr.To(true), + RequiresRepublish: ptr.To(true), + StorageCapacity: ptr.To(true), + SELinuxMount: test.oldValue, + PreventPodSchedulingIfMissing: new(false), }, } newCSIDriver := oldCSIDriver.DeepCopy() diff --git a/pkg/registry/storage/csidriver/storage/storage_test.go b/pkg/registry/storage/csidriver/storage/storage_test.go index 13c5537ea36..c086c18f676 100644 --- a/pkg/registry/storage/csidriver/storage/storage_test.go +++ b/pkg/registry/storage/csidriver/storage/storage_test.go @@ -51,16 +51,18 @@ func validNewCSIDriver(name string) *storageapi.CSIDriver { requiresRepublish := true storageCapacity := true seLinuxMount := true + preventPodSchedulingIfMissing := false return &storageapi.CSIDriver{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, Spec: storageapi.CSIDriverSpec{ - AttachRequired: &attachRequired, - PodInfoOnMount: &podInfoOnMount, - RequiresRepublish: &requiresRepublish, - StorageCapacity: &storageCapacity, - SELinuxMount: &seLinuxMount, + AttachRequired: &attachRequired, + PodInfoOnMount: &podInfoOnMount, + RequiresRepublish: &requiresRepublish, + StorageCapacity: &storageCapacity, + SELinuxMount: &seLinuxMount, + PreventPodSchedulingIfMissing: &preventPodSchedulingIfMissing, }, } } @@ -77,6 +79,7 @@ func TestCreate(t *testing.T) { notRequiresRepublish := false notStorageCapacity := false notSELinuxMount := false + notPreventPodSchedulingIfMissing := false test.TestCreate( // valid csiDriver, @@ -84,11 +87,12 @@ func TestCreate(t *testing.T) { &storageapi.CSIDriver{ ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, Spec: storageapi.CSIDriverSpec{ - AttachRequired: &attachNotRequired, - PodInfoOnMount: ¬PodInfoOnMount, - RequiresRepublish: ¬RequiresRepublish, - StorageCapacity: ¬StorageCapacity, - SELinuxMount: ¬SELinuxMount, + AttachRequired: &attachNotRequired, + PodInfoOnMount: ¬PodInfoOnMount, + RequiresRepublish: ¬RequiresRepublish, + StorageCapacity: ¬StorageCapacity, + SELinuxMount: ¬SELinuxMount, + PreventPodSchedulingIfMissing: ¬PreventPodSchedulingIfMissing, }, }, ) diff --git a/test/declarative_validation/storage/csidriver/declarative_validation_test.go b/test/declarative_validation/storage/csidriver/declarative_validation_test.go index cee4d49784e..41f9ba8d1c5 100644 --- a/test/declarative_validation/storage/csidriver/declarative_validation_test.go +++ b/test/declarative_validation/storage/csidriver/declarative_validation_test.go @@ -119,10 +119,11 @@ func mkCSIDriver(tweaks ...func(csi *storage.CSIDriver)) storage.CSIDriver { Name: "valid-obj", }, Spec: storage.CSIDriverSpec{ - AttachRequired: &falsePtr, - PodInfoOnMount: &falsePtr, - StorageCapacity: &falsePtr, - SELinuxMount: &falsePtr, + AttachRequired: &falsePtr, + PodInfoOnMount: &falsePtr, + StorageCapacity: &falsePtr, + SELinuxMount: &falsePtr, + PreventPodSchedulingIfMissing: &falsePtr, }, } for _, tweak := range tweaks { From c065dc627e99481d294b9c9fe9bcfee9deb15cff Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Wed, 15 Jul 2026 18:23:17 -0400 Subject: [PATCH 4/4] Fix fuzzer for defaults --- pkg/apis/storage/fuzzer/fuzzer.go | 4 +++ .../storage/validation/validation_test.go | 36 +++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/pkg/apis/storage/fuzzer/fuzzer.go b/pkg/apis/storage/fuzzer/fuzzer.go index 9351a1dedc7..6b266d2a46a 100644 --- a/pkg/apis/storage/fuzzer/fuzzer.go +++ b/pkg/apis/storage/fuzzer/fuzzer.go @@ -100,6 +100,10 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { obj.Spec.SELinuxMount = new(bool) *(obj.Spec.SELinuxMount) = false } + if obj.Spec.PreventPodSchedulingIfMissing == nil { + obj.Spec.PreventPodSchedulingIfMissing = new(bool) + *(obj.Spec.PreventPodSchedulingIfMissing) = false + } }, } } diff --git a/pkg/apis/storage/validation/validation_test.go b/pkg/apis/storage/validation/validation_test.go index 5c2f91fb5c9..00f0aa7662c 100644 --- a/pkg/apis/storage/validation/validation_test.go +++ b/pkg/apis/storage/validation/validation_test.go @@ -2309,7 +2309,7 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { }, { name: "feature enabled, non-nil value", featureEnabled: true, - seLinuxMountValue: ptr.To(true), + seLinuxMountValue: new(true), expectError: false, }, { name: "feature disabled, nil value", @@ -2319,7 +2319,7 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { }, { name: "feature disabled, non-nil value", featureEnabled: false, - seLinuxMountValue: ptr.To(true), + seLinuxMountValue: new(true), expectError: false, }} for _, test := range tests { @@ -2331,10 +2331,10 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { csiDriver := &storage.CSIDriver{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: storage.CSIDriverSpec{ - AttachRequired: ptr.To(true), - PodInfoOnMount: ptr.To(true), - RequiresRepublish: ptr.To(true), - StorageCapacity: ptr.To(true), + AttachRequired: new(true), + PodInfoOnMount: new(true), + RequiresRepublish: new(true), + StorageCapacity: new(true), SELinuxMount: test.seLinuxMountValue, PreventPodSchedulingIfMissing: new(false), }, @@ -2365,18 +2365,18 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { name: "feature enabled, nil->set", featureEnabled: true, oldValue: nil, - newValue: ptr.To(true), + newValue: new(true), expectError: false, }, { name: "feature enabled, set->set", featureEnabled: true, - oldValue: ptr.To(true), - newValue: ptr.To(true), + oldValue: new(true), + newValue: new(true), expectError: false, }, { name: "feature enabled, set->nil", featureEnabled: true, - oldValue: ptr.To(true), + oldValue: new(true), newValue: nil, expectError: true, // populated by defaulting and required when feature is enabled }, { @@ -2389,18 +2389,18 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { name: "feature disabled, nil->set", featureEnabled: false, oldValue: nil, - newValue: ptr.To(true), + newValue: new(true), expectError: false, }, { name: "feature disabled, set->set", featureEnabled: false, - oldValue: ptr.To(true), - newValue: ptr.To(true), + oldValue: new(true), + newValue: new(true), expectError: false, }, { name: "feature disabled, set->nil", featureEnabled: false, - oldValue: ptr.To(true), + oldValue: new(true), newValue: nil, expectError: false, }} @@ -2413,10 +2413,10 @@ func TestCSIDriverValidationSELinuxMountEnabledDisabled(t *testing.T) { oldCSIDriver := &storage.CSIDriver{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: storage.CSIDriverSpec{ - AttachRequired: ptr.To(true), - PodInfoOnMount: ptr.To(true), - RequiresRepublish: ptr.To(true), - StorageCapacity: ptr.To(true), + AttachRequired: new(true), + PodInfoOnMount: new(true), + RequiresRepublish: new(true), + StorageCapacity: new(true), SELinuxMount: test.oldValue, PreventPodSchedulingIfMissing: new(false), },