mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
storage capacity: GA, always enabled, remove feature check
The code and tests for scenarios where the feature is disabled are no longer needed because the feature is graduating to GA.
This commit is contained in:
parent
faa027ca2b
commit
3a7deaa141
@ -357,9 +357,6 @@ type CSIDriverSpec struct {
|
|||||||
//
|
//
|
||||||
// This field was immutable in Kubernetes <= 1.22 and now is mutable.
|
// This field was immutable in Kubernetes <= 1.22 and now is mutable.
|
||||||
//
|
//
|
||||||
// This is a beta field and only available when the CSIStorageCapacity
|
|
||||||
// feature is enabled. The default is false.
|
|
||||||
//
|
|
||||||
// +optional
|
// +optional
|
||||||
StorageCapacity *bool
|
StorageCapacity *bool
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) {
|
|||||||
obj.Spec.PodInfoOnMount = new(bool)
|
obj.Spec.PodInfoOnMount = new(bool)
|
||||||
*(obj.Spec.PodInfoOnMount) = false
|
*(obj.Spec.PodInfoOnMount) = false
|
||||||
}
|
}
|
||||||
if obj.Spec.StorageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
if obj.Spec.StorageCapacity == nil {
|
||||||
obj.Spec.StorageCapacity = new(bool)
|
obj.Spec.StorageCapacity = new(bool)
|
||||||
*(obj.Spec.StorageCapacity) = false
|
*(obj.Spec.StorageCapacity) = false
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,6 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
|
func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)()
|
|
||||||
driver := &storagev1.CSIDriver{}
|
driver := &storagev1.CSIDriver{}
|
||||||
|
|
||||||
// field should be defaulted
|
// field should be defaulted
|
||||||
@ -66,18 +65,6 @@ func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultStorageCapacityDisabled(t *testing.T) {
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, false)()
|
|
||||||
driver := &storagev1.CSIDriver{}
|
|
||||||
|
|
||||||
// field should not be defaulted
|
|
||||||
output := roundTrip(t, runtime.Object(driver)).(*storagev1.CSIDriver)
|
|
||||||
outStorageCapacity := output.Spec.StorageCapacity
|
|
||||||
if outStorageCapacity != nil {
|
|
||||||
t.Errorf("Expected StorageCapacity to remain nil, got: %+v", outStorageCapacity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetDefaultVolumeBindingMode(t *testing.T) {
|
func TestSetDefaultVolumeBindingMode(t *testing.T) {
|
||||||
class := &storagev1.StorageClass{}
|
class := &storagev1.StorageClass{}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) {
|
|||||||
obj.Spec.PodInfoOnMount = new(bool)
|
obj.Spec.PodInfoOnMount = new(bool)
|
||||||
*(obj.Spec.PodInfoOnMount) = false
|
*(obj.Spec.PodInfoOnMount) = false
|
||||||
}
|
}
|
||||||
if obj.Spec.StorageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
if obj.Spec.StorageCapacity == nil {
|
||||||
obj.Spec.StorageCapacity = new(bool)
|
obj.Spec.StorageCapacity = new(bool)
|
||||||
*(obj.Spec.StorageCapacity) = false
|
*(obj.Spec.StorageCapacity) = false
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,6 @@ func TestSetDefaultAttachRequired(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
|
func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)()
|
|
||||||
driver := &storagev1beta1.CSIDriver{}
|
driver := &storagev1beta1.CSIDriver{}
|
||||||
|
|
||||||
// field should be defaulted
|
// field should be defaulted
|
||||||
@ -101,18 +100,6 @@ func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultStorageCapacityDisabled(t *testing.T) {
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, false)()
|
|
||||||
driver := &storagev1beta1.CSIDriver{}
|
|
||||||
|
|
||||||
// field should not be defaulted
|
|
||||||
output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver)
|
|
||||||
outStorageCapacity := output.Spec.StorageCapacity
|
|
||||||
if outStorageCapacity != nil {
|
|
||||||
t.Errorf("Expected StorageCapacity to remain nil, got: %+v", outStorageCapacity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetDefaultVolumeLifecycleModesEnabled(t *testing.T) {
|
func TestSetDefaultVolumeLifecycleModesEnabled(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
||||||
driver := &storagev1beta1.CSIDriver{}
|
driver := &storagev1beta1.CSIDriver{}
|
||||||
|
@ -469,7 +469,7 @@ func validatePodInfoOnMount(podInfoOnMount *bool, fldPath *field.Path) field.Err
|
|||||||
// validateStorageCapacity tests if storageCapacity is set for CSIDriver.
|
// validateStorageCapacity tests if storageCapacity is set for CSIDriver.
|
||||||
func validateStorageCapacity(storageCapacity *bool, fldPath *field.Path) field.ErrorList {
|
func validateStorageCapacity(storageCapacity *bool, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
if storageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
if storageCapacity == nil {
|
||||||
allErrs = append(allErrs, field.Required(fldPath, ""))
|
allErrs = append(allErrs, field.Required(fldPath, ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2093,9 +2093,7 @@ func TestCSIDriverValidationUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCSIDriverStorageCapacityEnablement(t *testing.T) {
|
func TestCSIDriverStorageCapacityEnablement(t *testing.T) {
|
||||||
run := func(t *testing.T, enabled, withField bool) {
|
run := func(t *testing.T, withField bool) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, enabled)()
|
|
||||||
|
|
||||||
driverName := "test-driver"
|
driverName := "test-driver"
|
||||||
attachRequired := true
|
attachRequired := true
|
||||||
podInfoOnMount := true
|
podInfoOnMount := true
|
||||||
@ -2113,7 +2111,7 @@ func TestCSIDriverStorageCapacityEnablement(t *testing.T) {
|
|||||||
csiDriver.Spec.StorageCapacity = &storageCapacity
|
csiDriver.Spec.StorageCapacity = &storageCapacity
|
||||||
}
|
}
|
||||||
errs := ValidateCSIDriver(&csiDriver)
|
errs := ValidateCSIDriver(&csiDriver)
|
||||||
success := !enabled || withField
|
success := withField
|
||||||
if success && len(errs) != 0 {
|
if success && len(errs) != 0 {
|
||||||
t.Errorf("expected success, got: %v", errs)
|
t.Errorf("expected success, got: %v", errs)
|
||||||
}
|
}
|
||||||
@ -2123,13 +2121,9 @@ func TestCSIDriverStorageCapacityEnablement(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
yesNo := []bool{true, false}
|
yesNo := []bool{true, false}
|
||||||
for _, enabled := range yesNo {
|
|
||||||
t.Run(fmt.Sprintf("CSIStorageCapacity=%v", enabled), func(t *testing.T) {
|
|
||||||
for _, withField := range yesNo {
|
for _, withField := range yesNo {
|
||||||
t.Run(fmt.Sprintf("with-field=%v", withField), func(t *testing.T) {
|
t.Run(fmt.Sprintf("with-field=%v", withField), func(t *testing.T) {
|
||||||
run(t, enabled, withField)
|
run(t, withField)
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,7 @@ const (
|
|||||||
// owner: @pohly
|
// owner: @pohly
|
||||||
// alpha: v1.19
|
// alpha: v1.19
|
||||||
// beta: v1.21
|
// beta: v1.21
|
||||||
|
// GA: v1.24
|
||||||
//
|
//
|
||||||
// Enables tracking of available storage capacity that CSI drivers provide.
|
// Enables tracking of available storage capacity that CSI drivers provide.
|
||||||
CSIStorageCapacity featuregate.Feature = "CSIStorageCapacity"
|
CSIStorageCapacity featuregate.Feature = "CSIStorageCapacity"
|
||||||
@ -879,7 +880,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
CSIMigrationPortworx: {Default: false, PreRelease: featuregate.Alpha}, // Off by default (requires Portworx CSI driver)
|
CSIMigrationPortworx: {Default: false, PreRelease: featuregate.Alpha}, // Off by default (requires Portworx CSI driver)
|
||||||
InTreePluginPortworxUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
InTreePluginPortworxUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
|
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
|
||||||
CSIStorageCapacity: {Default: true, PreRelease: featuregate.Beta},
|
CSIStorageCapacity: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
|
||||||
CSIServiceAccountToken: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
CSIServiceAccountToken: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||||
GenericEphemeralVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
GenericEphemeralVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
||||||
CSIVolumeFSGroupPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
CSIVolumeFSGroupPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
||||||
|
@ -47,7 +47,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/duration"
|
"k8s.io/apimachinery/pkg/util/duration"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/client-go/util/certificate/csr"
|
"k8s.io/client-go/util/certificate/csr"
|
||||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||||
"k8s.io/kubernetes/pkg/apis/apiserverinternal"
|
"k8s.io/kubernetes/pkg/apis/apiserverinternal"
|
||||||
@ -68,7 +67,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/apis/scheduling"
|
"k8s.io/kubernetes/pkg/apis/scheduling"
|
||||||
"k8s.io/kubernetes/pkg/apis/storage"
|
"k8s.io/kubernetes/pkg/apis/storage"
|
||||||
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
"k8s.io/kubernetes/pkg/util/node"
|
"k8s.io/kubernetes/pkg/util/node"
|
||||||
)
|
)
|
||||||
@ -516,11 +514,7 @@ func AddHandlers(h printers.PrintHandler) {
|
|||||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||||
{Name: "AttachRequired", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["attachRequired"]},
|
{Name: "AttachRequired", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["attachRequired"]},
|
||||||
{Name: "PodInfoOnMount", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["podInfoOnMount"]},
|
{Name: "PodInfoOnMount", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["podInfoOnMount"]},
|
||||||
}
|
{Name: "StorageCapacity", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["storageCapacity"]},
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
|
||||||
csiDriverColumnDefinitions = append(csiDriverColumnDefinitions, metav1.TableColumnDefinition{
|
|
||||||
Name: "StorageCapacity", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["storageCapacity"],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
csiDriverColumnDefinitions = append(csiDriverColumnDefinitions, []metav1.TableColumnDefinition{
|
csiDriverColumnDefinitions = append(csiDriverColumnDefinitions, []metav1.TableColumnDefinition{
|
||||||
{Name: "TokenRequests", Type: "string", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["tokenRequests"]},
|
{Name: "TokenRequests", Type: "string", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["tokenRequests"]},
|
||||||
@ -1413,13 +1407,11 @@ func printCSIDriver(obj *storage.CSIDriver, options printers.GenerateOptions) ([
|
|||||||
}
|
}
|
||||||
|
|
||||||
row.Cells = append(row.Cells, obj.Name, attachRequired, podInfoOnMount)
|
row.Cells = append(row.Cells, obj.Name, attachRequired, podInfoOnMount)
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
|
||||||
storageCapacity := false
|
storageCapacity := false
|
||||||
if obj.Spec.StorageCapacity != nil {
|
if obj.Spec.StorageCapacity != nil {
|
||||||
storageCapacity = *obj.Spec.StorageCapacity
|
storageCapacity = *obj.Spec.StorageCapacity
|
||||||
}
|
}
|
||||||
row.Cells = append(row.Cells, storageCapacity)
|
row.Cells = append(row.Cells, storageCapacity)
|
||||||
}
|
|
||||||
|
|
||||||
tokenRequests := "<unset>"
|
tokenRequests := "<unset>"
|
||||||
if obj.Spec.TokenRequests != nil {
|
if obj.Spec.TokenRequests != nil {
|
||||||
|
@ -47,9 +47,6 @@ func (csiDriverStrategy) NamespaceScoped() bool {
|
|||||||
// PrepareForCreate clears the fields for which the corresponding feature is disabled.
|
// PrepareForCreate clears the fields for which the corresponding feature is disabled.
|
||||||
func (csiDriverStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
|
func (csiDriverStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
|
||||||
csiDriver := obj.(*storage.CSIDriver)
|
csiDriver := obj.(*storage.CSIDriver)
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
|
||||||
csiDriver.Spec.StorageCapacity = nil
|
|
||||||
}
|
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
||||||
csiDriver.Spec.VolumeLifecycleModes = nil
|
csiDriver.Spec.VolumeLifecycleModes = nil
|
||||||
}
|
}
|
||||||
@ -84,10 +81,6 @@ func (csiDriverStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.
|
|||||||
newCSIDriver := obj.(*storage.CSIDriver)
|
newCSIDriver := obj.(*storage.CSIDriver)
|
||||||
oldCSIDriver := old.(*storage.CSIDriver)
|
oldCSIDriver := old.(*storage.CSIDriver)
|
||||||
|
|
||||||
if oldCSIDriver.Spec.StorageCapacity == nil &&
|
|
||||||
!utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
|
||||||
newCSIDriver.Spec.StorageCapacity = nil
|
|
||||||
}
|
|
||||||
if oldCSIDriver.Spec.VolumeLifecycleModes == nil &&
|
if oldCSIDriver.Spec.VolumeLifecycleModes == nil &&
|
||||||
!utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
!utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
||||||
newCSIDriver.Spec.VolumeLifecycleModes = nil
|
newCSIDriver.Spec.VolumeLifecycleModes = nil
|
||||||
|
@ -93,7 +93,6 @@ func TestCSIDriverPrepareForCreate(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
withCapacity bool
|
|
||||||
withInline bool
|
withInline bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -104,19 +103,10 @@ func TestCSIDriverPrepareForCreate(t *testing.T) {
|
|||||||
name: "inline disabled",
|
name: "inline disabled",
|
||||||
withInline: false,
|
withInline: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "capacity enabled",
|
|
||||||
withCapacity: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "capacity disabled",
|
|
||||||
withCapacity: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, test.withCapacity)()
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.withInline)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.withInline)()
|
||||||
|
|
||||||
csiDriver := &storage.CSIDriver{
|
csiDriver := &storage.CSIDriver{
|
||||||
@ -139,15 +129,9 @@ func TestCSIDriverPrepareForCreate(t *testing.T) {
|
|||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
t.Errorf("unexpected validating errors: %v", errs)
|
t.Errorf("unexpected validating errors: %v", errs)
|
||||||
}
|
}
|
||||||
if test.withCapacity {
|
|
||||||
if csiDriver.Spec.StorageCapacity == nil || *csiDriver.Spec.StorageCapacity != storageCapacity {
|
if csiDriver.Spec.StorageCapacity == nil || *csiDriver.Spec.StorageCapacity != storageCapacity {
|
||||||
t.Errorf("StorageCapacity modified: %v", csiDriver.Spec.StorageCapacity)
|
t.Errorf("StorageCapacity modified: %v", csiDriver.Spec.StorageCapacity)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if csiDriver.Spec.StorageCapacity != nil {
|
|
||||||
t.Errorf("StorageCapacity not stripped: %v", csiDriver.Spec.StorageCapacity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if test.withInline {
|
if test.withInline {
|
||||||
if len(csiDriver.Spec.VolumeLifecycleModes) != 1 {
|
if len(csiDriver.Spec.VolumeLifecycleModes) != 1 {
|
||||||
t.Errorf("VolumeLifecycleModes modified: %v", csiDriver.Spec)
|
t.Errorf("VolumeLifecycleModes modified: %v", csiDriver.Spec)
|
||||||
@ -233,7 +217,6 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
old, update *storage.CSIDriver
|
old, update *storage.CSIDriver
|
||||||
csiStorageCapacityEnabled bool
|
|
||||||
csiInlineVolumeEnabled bool
|
csiInlineVolumeEnabled bool
|
||||||
wantCapacity *bool
|
wantCapacity *bool
|
||||||
wantModes []storage.VolumeLifecycleMode
|
wantModes []storage.VolumeLifecycleMode
|
||||||
@ -243,19 +226,12 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "capacity feature enabled, before: none, update: enabled",
|
name: "capacity feature enabled, before: none, update: enabled",
|
||||||
csiStorageCapacityEnabled: true,
|
|
||||||
old: driverWithNothing,
|
old: driverWithNothing,
|
||||||
update: driverWithCapacityEnabled,
|
update: driverWithCapacityEnabled,
|
||||||
wantCapacity: &enabled,
|
wantCapacity: &enabled,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "capacity feature disabled, before: none, update: disabled",
|
name: "capacity feature enabled, before: enabled, update: disabled",
|
||||||
old: driverWithNothing,
|
|
||||||
update: driverWithCapacityDisabled,
|
|
||||||
wantCapacity: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "capacity feature disabled, before: enabled, update: disabled",
|
|
||||||
old: driverWithCapacityEnabled,
|
old: driverWithCapacityEnabled,
|
||||||
update: driverWithCapacityDisabled,
|
update: driverWithCapacityDisabled,
|
||||||
wantCapacity: &disabled,
|
wantCapacity: &disabled,
|
||||||
@ -291,7 +267,6 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, test.csiStorageCapacityEnabled)()
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.csiInlineVolumeEnabled)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.csiInlineVolumeEnabled)()
|
||||||
|
|
||||||
csiDriver := test.update.DeepCopy()
|
csiDriver := test.update.DeepCopy()
|
||||||
|
@ -24,10 +24,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/diff"
|
"k8s.io/apimachinery/pkg/util/diff"
|
||||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
"k8s.io/kubernetes/pkg/apis/storage"
|
"k8s.io/kubernetes/pkg/apis/storage"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// getValidCSIStorageCapacity returns a fully-populated CSIStorageCapacity.
|
// getValidCSIStorageCapacity returns a fully-populated CSIStorageCapacity.
|
||||||
@ -159,8 +156,6 @@ func TestCSIStorageCapacityValidation(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)()
|
|
||||||
|
|
||||||
oldCapacity := test.old.DeepCopy()
|
oldCapacity := test.old.DeepCopy()
|
||||||
Strategy.PrepareForCreate(ctx, oldCapacity)
|
Strategy.PrepareForCreate(ctx, oldCapacity)
|
||||||
errs := Strategy.Validate(ctx, oldCapacity)
|
errs := Strategy.Validate(ctx, oldCapacity)
|
||||||
|
@ -25,6 +25,5 @@ type Features struct {
|
|||||||
EnablePodOverhead bool
|
EnablePodOverhead bool
|
||||||
EnableReadWriteOncePod bool
|
EnableReadWriteOncePod bool
|
||||||
EnableVolumeCapacityPriority bool
|
EnableVolumeCapacityPriority bool
|
||||||
EnableCSIStorageCapacity bool
|
|
||||||
EnableMinDomainsInPodTopologySpread bool
|
EnableMinDomainsInPodTopologySpread bool
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,6 @@ func NewInTreeRegistry() runtime.Registry {
|
|||||||
EnablePodOverhead: feature.DefaultFeatureGate.Enabled(features.PodOverhead),
|
EnablePodOverhead: feature.DefaultFeatureGate.Enabled(features.PodOverhead),
|
||||||
EnableReadWriteOncePod: feature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
EnableReadWriteOncePod: feature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||||
EnableVolumeCapacityPriority: feature.DefaultFeatureGate.Enabled(features.VolumeCapacityPriority),
|
EnableVolumeCapacityPriority: feature.DefaultFeatureGate.Enabled(features.VolumeCapacityPriority),
|
||||||
EnableCSIStorageCapacity: feature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity),
|
|
||||||
EnableMinDomainsInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.MinDomainsInPodTopologySpread),
|
EnableMinDomainsInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.MinDomainsInPodTopologySpread),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,6 @@ type volumeBinder struct {
|
|||||||
|
|
||||||
translator InTreeToCSITranslator
|
translator InTreeToCSITranslator
|
||||||
|
|
||||||
capacityCheckEnabled bool
|
|
||||||
csiDriverLister storagelisters.CSIDriverLister
|
csiDriverLister storagelisters.CSIDriverLister
|
||||||
csiStorageCapacityLister storagelistersv1beta1.CSIStorageCapacityLister
|
csiStorageCapacityLister storagelistersv1beta1.CSIStorageCapacityLister
|
||||||
}
|
}
|
||||||
@ -224,7 +223,7 @@ type CapacityCheck struct {
|
|||||||
|
|
||||||
// NewVolumeBinder sets up all the caches needed for the scheduler to make volume binding decisions.
|
// NewVolumeBinder sets up all the caches needed for the scheduler to make volume binding decisions.
|
||||||
//
|
//
|
||||||
// capacityCheck determines whether storage capacity is checked (CSIStorageCapacity feature).
|
// capacityCheck determines how storage capacity is checked (CSIStorageCapacity feature).
|
||||||
func NewVolumeBinder(
|
func NewVolumeBinder(
|
||||||
kubeClient clientset.Interface,
|
kubeClient clientset.Interface,
|
||||||
podInformer coreinformers.PodInformer,
|
podInformer coreinformers.PodInformer,
|
||||||
@ -233,7 +232,7 @@ func NewVolumeBinder(
|
|||||||
pvcInformer coreinformers.PersistentVolumeClaimInformer,
|
pvcInformer coreinformers.PersistentVolumeClaimInformer,
|
||||||
pvInformer coreinformers.PersistentVolumeInformer,
|
pvInformer coreinformers.PersistentVolumeInformer,
|
||||||
storageClassInformer storageinformers.StorageClassInformer,
|
storageClassInformer storageinformers.StorageClassInformer,
|
||||||
capacityCheck *CapacityCheck,
|
capacityCheck CapacityCheck,
|
||||||
bindTimeout time.Duration) SchedulerVolumeBinder {
|
bindTimeout time.Duration) SchedulerVolumeBinder {
|
||||||
b := &volumeBinder{
|
b := &volumeBinder{
|
||||||
kubeClient: kubeClient,
|
kubeClient: kubeClient,
|
||||||
@ -247,11 +246,8 @@ func NewVolumeBinder(
|
|||||||
translator: csitrans.New(),
|
translator: csitrans.New(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if capacityCheck != nil {
|
|
||||||
b.capacityCheckEnabled = true
|
|
||||||
b.csiDriverLister = capacityCheck.CSIDriverInformer.Lister()
|
b.csiDriverLister = capacityCheck.CSIDriverInformer.Lister()
|
||||||
b.csiStorageCapacityLister = capacityCheck.CSIStorageCapacityInformer.Lister()
|
b.csiStorageCapacityLister = capacityCheck.CSIStorageCapacityInformer.Lister()
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
@ -922,12 +918,6 @@ func (b *volumeBinder) revertAssumedPVCs(claims []*v1.PersistentVolumeClaim) {
|
|||||||
// hasEnoughCapacity checks whether the provisioner has enough capacity left for a new volume of the given size
|
// hasEnoughCapacity checks whether the provisioner has enough capacity left for a new volume of the given size
|
||||||
// that is available from the node.
|
// that is available from the node.
|
||||||
func (b *volumeBinder) hasEnoughCapacity(provisioner string, claim *v1.PersistentVolumeClaim, storageClass *storagev1.StorageClass, node *v1.Node) (bool, error) {
|
func (b *volumeBinder) hasEnoughCapacity(provisioner string, claim *v1.PersistentVolumeClaim, storageClass *storagev1.StorageClass, node *v1.Node) (bool, error) {
|
||||||
// This is an optional feature. If disabled, we assume that
|
|
||||||
// there is enough storage.
|
|
||||||
if !b.capacityCheckEnabled {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
quantity, ok := claim.Spec.Resources.Requests[v1.ResourceStorage]
|
quantity, ok := claim.Spec.Resources.Requests[v1.ResourceStorage]
|
||||||
if !ok {
|
if !ok {
|
||||||
// No capacity to check for.
|
// No capacity to check for.
|
||||||
|
@ -144,7 +144,7 @@ type testEnv struct {
|
|||||||
internalCSIStorageCapacityInformer storageinformersv1beta1.CSIStorageCapacityInformer
|
internalCSIStorageCapacityInformer storageinformersv1beta1.CSIStorageCapacityInformer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestBinder(t *testing.T, stopCh <-chan struct{}, csiStorageCapacity ...bool) *testEnv {
|
func newTestBinder(t *testing.T, stopCh <-chan struct{}) *testEnv {
|
||||||
client := &fake.Clientset{}
|
client := &fake.Clientset{}
|
||||||
reactor := pvtesting.NewVolumeReactor(client, nil, nil, nil)
|
reactor := pvtesting.NewVolumeReactor(client, nil, nil, nil)
|
||||||
// TODO refactor all tests to use real watch mechanism, see #72327
|
// TODO refactor all tests to use real watch mechanism, see #72327
|
||||||
@ -166,13 +166,10 @@ func newTestBinder(t *testing.T, stopCh <-chan struct{}, csiStorageCapacity ...b
|
|||||||
classInformer := informerFactory.Storage().V1().StorageClasses()
|
classInformer := informerFactory.Storage().V1().StorageClasses()
|
||||||
csiDriverInformer := informerFactory.Storage().V1().CSIDrivers()
|
csiDriverInformer := informerFactory.Storage().V1().CSIDrivers()
|
||||||
csiStorageCapacityInformer := informerFactory.Storage().V1beta1().CSIStorageCapacities()
|
csiStorageCapacityInformer := informerFactory.Storage().V1beta1().CSIStorageCapacities()
|
||||||
var capacityCheck *CapacityCheck
|
capacityCheck := CapacityCheck{
|
||||||
if len(csiStorageCapacity) > 0 && csiStorageCapacity[0] {
|
|
||||||
capacityCheck = &CapacityCheck{
|
|
||||||
CSIDriverInformer: csiDriverInformer,
|
CSIDriverInformer: csiDriverInformer,
|
||||||
CSIStorageCapacityInformer: csiStorageCapacityInformer,
|
CSIStorageCapacityInformer: csiStorageCapacityInformer,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
binder := NewVolumeBinder(
|
binder := NewVolumeBinder(
|
||||||
client,
|
client,
|
||||||
podInformer,
|
podInformer,
|
||||||
@ -970,12 +967,12 @@ func TestFindPodVolumesWithoutProvisioning(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, scenario scenarioType, csiStorageCapacity bool, csiDriver *storagev1.CSIDriver) {
|
run := func(t *testing.T, scenario scenarioType, csiDriver *storagev1.CSIDriver) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
testEnv := newTestBinder(t, ctx.Done(), csiStorageCapacity)
|
testEnv := newTestBinder(t, ctx.Done())
|
||||||
testEnv.initVolumes(scenario.pvs, scenario.pvs)
|
testEnv.initVolumes(scenario.pvs, scenario.pvs)
|
||||||
if csiDriver != nil {
|
if csiDriver != nil {
|
||||||
testEnv.addCSIDriver(csiDriver)
|
testEnv.addCSIDriver(csiDriver)
|
||||||
@ -1009,8 +1006,6 @@ func TestFindPodVolumesWithoutProvisioning(t *testing.T) {
|
|||||||
testEnv.validatePodCache(t, testNode.Name, scenario.pod, podVolumes, scenario.expectedBindings, nil)
|
testEnv.validatePodCache(t, testNode.Name, scenario.pod, podVolumes, scenario.expectedBindings, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
for prefix, csiStorageCapacity := range map[string]bool{"with": true, "without": false} {
|
|
||||||
t.Run(fmt.Sprintf("%s CSIStorageCapacity", prefix), func(t *testing.T) {
|
|
||||||
for description, csiDriver := range map[string]*storagev1.CSIDriver{
|
for description, csiDriver := range map[string]*storagev1.CSIDriver{
|
||||||
"no CSIDriver": nil,
|
"no CSIDriver": nil,
|
||||||
"CSIDriver with capacity tracking": makeCSIDriver(provisioner, true),
|
"CSIDriver with capacity tracking": makeCSIDriver(provisioner, true),
|
||||||
@ -1018,9 +1013,7 @@ func TestFindPodVolumesWithoutProvisioning(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
t.Run(description, func(t *testing.T) {
|
t.Run(description, func(t *testing.T) {
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
t.Run(name, func(t *testing.T) { run(t, scenario, csiStorageCapacity, csiDriver) })
|
t.Run(name, func(t *testing.T) { run(t, scenario, csiDriver) })
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1101,12 +1094,12 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, scenario scenarioType, csiStorageCapacity bool, csiDriver *storagev1.CSIDriver) {
|
run := func(t *testing.T, scenario scenarioType, csiDriver *storagev1.CSIDriver) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
testEnv := newTestBinder(t, ctx.Done(), csiStorageCapacity)
|
testEnv := newTestBinder(t, ctx.Done())
|
||||||
testEnv.initVolumes(scenario.pvs, scenario.pvs)
|
testEnv.initVolumes(scenario.pvs, scenario.pvs)
|
||||||
if csiDriver != nil {
|
if csiDriver != nil {
|
||||||
testEnv.addCSIDriver(csiDriver)
|
testEnv.addCSIDriver(csiDriver)
|
||||||
@ -1138,7 +1131,7 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) {
|
|||||||
}
|
}
|
||||||
expectedReasons := scenario.reasons
|
expectedReasons := scenario.reasons
|
||||||
expectedProvisions := scenario.expectedProvisions
|
expectedProvisions := scenario.expectedProvisions
|
||||||
if scenario.needsCapacity && csiStorageCapacity &&
|
if scenario.needsCapacity &&
|
||||||
csiDriver != nil && csiDriver.Spec.StorageCapacity != nil && *csiDriver.Spec.StorageCapacity {
|
csiDriver != nil && csiDriver.Spec.StorageCapacity != nil && *csiDriver.Spec.StorageCapacity {
|
||||||
// Without CSIStorageCapacity objects, provisioning is blocked.
|
// Without CSIStorageCapacity objects, provisioning is blocked.
|
||||||
expectedReasons = append(expectedReasons, ErrReasonNotEnoughSpace)
|
expectedReasons = append(expectedReasons, ErrReasonNotEnoughSpace)
|
||||||
@ -1148,8 +1141,6 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) {
|
|||||||
testEnv.validatePodCache(t, testNode.Name, scenario.pod, podVolumes, scenario.expectedBindings, expectedProvisions)
|
testEnv.validatePodCache(t, testNode.Name, scenario.pod, podVolumes, scenario.expectedBindings, expectedProvisions)
|
||||||
}
|
}
|
||||||
|
|
||||||
for prefix, csiStorageCapacity := range map[string]bool{"with": true, "without": false} {
|
|
||||||
t.Run(fmt.Sprintf("%s CSIStorageCapacity", prefix), func(t *testing.T) {
|
|
||||||
for description, csiDriver := range map[string]*storagev1.CSIDriver{
|
for description, csiDriver := range map[string]*storagev1.CSIDriver{
|
||||||
"no CSIDriver": nil,
|
"no CSIDriver": nil,
|
||||||
"CSIDriver with capacity tracking": makeCSIDriver(provisioner, true),
|
"CSIDriver with capacity tracking": makeCSIDriver(provisioner, true),
|
||||||
@ -1157,9 +1148,7 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
t.Run(description, func(t *testing.T) {
|
t.Run(description, func(t *testing.T) {
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
t.Run(name, func(t *testing.T) { run(t, scenario, csiStorageCapacity, csiDriver) })
|
t.Run(name, func(t *testing.T) { run(t, scenario, csiDriver) })
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -2261,13 +2250,12 @@ func TestCapacity(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, scenario scenarioType, featureEnabled, optIn bool) {
|
run := func(t *testing.T, scenario scenarioType, optIn bool) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, featureEnabled)()
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Setup: the driver has the feature enabled, but the scheduler might not.
|
// Setup: the driver has the feature enabled, but the scheduler might not.
|
||||||
testEnv := newTestBinder(t, ctx.Done(), featureEnabled)
|
testEnv := newTestBinder(t, ctx.Done())
|
||||||
testEnv.addCSIDriver(makeCSIDriver(provisioner, optIn))
|
testEnv.addCSIDriver(makeCSIDriver(provisioner, optIn))
|
||||||
testEnv.addCSIStorageCapacities(scenario.capacities)
|
testEnv.addCSIStorageCapacities(scenario.capacities)
|
||||||
|
|
||||||
@ -2286,7 +2274,7 @@ func TestCapacity(t *testing.T) {
|
|||||||
// Validate
|
// Validate
|
||||||
shouldFail := scenario.shouldFail
|
shouldFail := scenario.shouldFail
|
||||||
expectedReasons := scenario.reasons
|
expectedReasons := scenario.reasons
|
||||||
if !featureEnabled || !optIn {
|
if !optIn {
|
||||||
shouldFail = false
|
shouldFail = false
|
||||||
expectedReasons = nil
|
expectedReasons = nil
|
||||||
}
|
}
|
||||||
@ -2305,16 +2293,11 @@ func TestCapacity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
yesNo := []bool{true, false}
|
yesNo := []bool{true, false}
|
||||||
for _, featureEnabled := range yesNo {
|
|
||||||
name := fmt.Sprintf("CSIStorageCapacity=%v", featureEnabled)
|
|
||||||
t.Run(name, func(t *testing.T) {
|
|
||||||
for _, optIn := range yesNo {
|
for _, optIn := range yesNo {
|
||||||
name := fmt.Sprintf("CSIDriver.StorageCapacity=%v", optIn)
|
name := fmt.Sprintf("CSIDriver.StorageCapacity=%v", optIn)
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
t.Run(name, func(t *testing.T) { run(t, scenario, featureEnabled, optIn) })
|
t.Run(name, func(t *testing.T) { run(t, scenario, optIn) })
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -107,14 +107,10 @@ func (pl *VolumeBinding) EventsToRegister() []framework.ClusterEvent {
|
|||||||
{Resource: framework.Node, ActionType: framework.Add | framework.UpdateNodeLabel},
|
{Resource: framework.Node, ActionType: framework.Add | framework.UpdateNodeLabel},
|
||||||
// We rely on CSI node to translate in-tree PV to CSI.
|
// We rely on CSI node to translate in-tree PV to CSI.
|
||||||
{Resource: framework.CSINode, ActionType: framework.Add | framework.Update},
|
{Resource: framework.CSINode, ActionType: framework.Add | framework.Update},
|
||||||
}
|
|
||||||
if pl.fts.EnableCSIStorageCapacity {
|
|
||||||
// When CSIStorageCapacity is enabled, pods may become schedulable
|
// When CSIStorageCapacity is enabled, pods may become schedulable
|
||||||
// on CSI driver & storage capacity changes.
|
// on CSI driver & storage capacity changes.
|
||||||
events = append(events, []framework.ClusterEvent{
|
|
||||||
{Resource: framework.CSIDriver, ActionType: framework.Add | framework.Update},
|
{Resource: framework.CSIDriver, ActionType: framework.Add | framework.Update},
|
||||||
{Resource: framework.CSIStorageCapacity, ActionType: framework.Add | framework.Update},
|
{Resource: framework.CSIStorageCapacity, ActionType: framework.Add | framework.Update},
|
||||||
}...)
|
|
||||||
}
|
}
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
@ -379,13 +375,10 @@ func New(plArgs runtime.Object, fh framework.Handle, fts feature.Features) (fram
|
|||||||
pvInformer := fh.SharedInformerFactory().Core().V1().PersistentVolumes()
|
pvInformer := fh.SharedInformerFactory().Core().V1().PersistentVolumes()
|
||||||
storageClassInformer := fh.SharedInformerFactory().Storage().V1().StorageClasses()
|
storageClassInformer := fh.SharedInformerFactory().Storage().V1().StorageClasses()
|
||||||
csiNodeInformer := fh.SharedInformerFactory().Storage().V1().CSINodes()
|
csiNodeInformer := fh.SharedInformerFactory().Storage().V1().CSINodes()
|
||||||
var capacityCheck *CapacityCheck
|
capacityCheck := CapacityCheck{
|
||||||
if fts.EnableCSIStorageCapacity {
|
|
||||||
capacityCheck = &CapacityCheck{
|
|
||||||
CSIDriverInformer: fh.SharedInformerFactory().Storage().V1().CSIDrivers(),
|
CSIDriverInformer: fh.SharedInformerFactory().Storage().V1().CSIDrivers(),
|
||||||
CSIStorageCapacityInformer: fh.SharedInformerFactory().Storage().V1beta1().CSIStorageCapacities(),
|
CSIStorageCapacityInformer: fh.SharedInformerFactory().Storage().V1beta1().CSIStorageCapacities(),
|
||||||
}
|
}
|
||||||
}
|
|
||||||
binder := NewVolumeBinder(fh.ClientSet(), podInformer, nodeInformer, csiNodeInformer, pvcInformer, pvInformer, storageClassInformer, capacityCheck, time.Duration(args.BindTimeoutSeconds)*time.Second)
|
binder := NewVolumeBinder(fh.ClientSet(), podInformer, nodeInformer, csiNodeInformer, pvcInformer, pvInformer, storageClassInformer, capacityCheck, time.Duration(args.BindTimeoutSeconds)*time.Second)
|
||||||
|
|
||||||
// build score function
|
// build score function
|
||||||
|
@ -551,12 +551,8 @@ func ClusterRoles() []rbacv1.ClusterRole {
|
|||||||
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csinodes").RuleOrDie(),
|
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csinodes").RuleOrDie(),
|
||||||
// Needed for namespaceSelector feature in pod affinity
|
// Needed for namespaceSelector feature in pod affinity
|
||||||
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
|
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
|
||||||
}
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
|
||||||
kubeSchedulerRules = append(kubeSchedulerRules,
|
|
||||||
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csidrivers").RuleOrDie(),
|
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csidrivers").RuleOrDie(),
|
||||||
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csistoragecapacities").RuleOrDie(),
|
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csistoragecapacities").RuleOrDie(),
|
||||||
)
|
|
||||||
}
|
}
|
||||||
roles = append(roles, rbacv1.ClusterRole{
|
roles = append(roles, rbacv1.ClusterRole{
|
||||||
// a role to use for the kube-scheduler
|
// a role to use for the kube-scheduler
|
||||||
|
@ -364,11 +364,7 @@ type CSIDriverSpec struct {
|
|||||||
//
|
//
|
||||||
// This field was immutable in Kubernetes <= 1.22 and now is mutable.
|
// This field was immutable in Kubernetes <= 1.22 and now is mutable.
|
||||||
//
|
//
|
||||||
// This is a beta field and only available when the CSIStorageCapacity
|
|
||||||
// feature is enabled. The default is false.
|
|
||||||
//
|
|
||||||
// +optional
|
// +optional
|
||||||
// +featureGate=CSIStorageCapacity
|
|
||||||
StorageCapacity *bool `json:"storageCapacity,omitempty" protobuf:"bytes,4,opt,name=storageCapacity"`
|
StorageCapacity *bool `json:"storageCapacity,omitempty" protobuf:"bytes,4,opt,name=storageCapacity"`
|
||||||
|
|
||||||
// Defines if the underlying volume supports changing ownership and
|
// Defines if the underlying volume supports changing ownership and
|
||||||
|
@ -30,16 +30,13 @@ import (
|
|||||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
diskcached "k8s.io/client-go/discovery/cached/disk"
|
diskcached "k8s.io/client-go/discovery/cached/disk"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
"k8s.io/gengo/examples/set-gen/sets"
|
"k8s.io/gengo/examples/set-gen/sets"
|
||||||
"k8s.io/kubectl/pkg/cmd/util"
|
"k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
||||||
"k8s.io/kubernetes/test/integration/framework"
|
"k8s.io/kubernetes/test/integration/framework"
|
||||||
@ -123,8 +120,6 @@ var missingHanlders = sets.NewString(
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestServerSidePrint(t *testing.T) {
|
func TestServerSidePrint(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)()
|
|
||||||
|
|
||||||
s, _, closeFn := setupWithResources(t,
|
s, _, closeFn := setupWithResources(t,
|
||||||
// additional groupversions needed for the test to run
|
// additional groupversions needed for the test to run
|
||||||
[]schema.GroupVersion{
|
[]schema.GroupVersion{
|
||||||
|
@ -29,14 +29,12 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/uuid"
|
"k8s.io/apimachinery/pkg/util/uuid"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/tools/events"
|
"k8s.io/client-go/tools/events"
|
||||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||||
"k8s.io/kubernetes/pkg/controlplane"
|
"k8s.io/kubernetes/pkg/controlplane"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/scheduler"
|
"k8s.io/kubernetes/pkg/scheduler"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/profile"
|
"k8s.io/kubernetes/pkg/scheduler/profile"
|
||||||
"k8s.io/kubernetes/test/integration/framework"
|
"k8s.io/kubernetes/test/integration/framework"
|
||||||
@ -73,12 +71,6 @@ func initTestAPIServer(t *testing.T, nsPrefix string, admission admission.Interf
|
|||||||
|
|
||||||
controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfig()
|
controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfig()
|
||||||
resourceConfig := controlplane.DefaultAPIResourceConfigSource()
|
resourceConfig := controlplane.DefaultAPIResourceConfigSource()
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
|
|
||||||
resourceConfig.EnableVersions(schema.GroupVersion{
|
|
||||||
Group: "storage.k8s.io",
|
|
||||||
Version: "v1alpha1",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
controlPlaneConfig.ExtraConfig.APIResourceConfigSource = resourceConfig
|
controlPlaneConfig.ExtraConfig.APIResourceConfigSource = resourceConfig
|
||||||
|
|
||||||
if admission != nil {
|
if admission != nil {
|
||||||
|
@ -37,13 +37,10 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/rand"
|
"k8s.io/apimachinery/pkg/util/rand"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
"k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
|
"k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits"
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits"
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||||
@ -704,13 +701,6 @@ func TestPVAffinityConflict(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestVolumeProvision(t *testing.T) {
|
func TestVolumeProvision(t *testing.T) {
|
||||||
t.Run("with CSIStorageCapacity", func(t *testing.T) { testVolumeProvision(t, true) })
|
|
||||||
t.Run("without CSIStorageCapacity", func(t *testing.T) { testVolumeProvision(t, false) })
|
|
||||||
}
|
|
||||||
|
|
||||||
func testVolumeProvision(t *testing.T, storageCapacity bool) {
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, storageCapacity)()
|
|
||||||
|
|
||||||
config := setupCluster(t, "volume-scheduling", 1, 0, 0)
|
config := setupCluster(t, "volume-scheduling", 1, 0, 0)
|
||||||
defer config.teardown()
|
defer config.teardown()
|
||||||
|
|
||||||
@ -859,8 +849,6 @@ func testVolumeProvision(t *testing.T, storageCapacity bool) {
|
|||||||
|
|
||||||
// TestCapacity covers different scenarios involving CSIStorageCapacity objects.
|
// TestCapacity covers different scenarios involving CSIStorageCapacity objects.
|
||||||
func TestCapacity(t *testing.T) {
|
func TestCapacity(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)()
|
|
||||||
|
|
||||||
config := setupCluster(t, "volume-scheduling", 1, 0, 0)
|
config := setupCluster(t, "volume-scheduling", 1, 0, 0)
|
||||||
defer config.teardown()
|
defer config.teardown()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user