mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +00:00 
			
		
		
		
	Merge pull request #72382 from liggitt/volumescheduling-ga
Stop checking VolumeScheduling feature gate
This commit is contained in:
		@@ -14,7 +14,6 @@ go_library(
 | 
				
			|||||||
        "//cmd/kube-scheduler/app/options:go_default_library",
 | 
					        "//cmd/kube-scheduler/app/options:go_default_library",
 | 
				
			||||||
        "//pkg/api/legacyscheme:go_default_library",
 | 
					        "//pkg/api/legacyscheme:go_default_library",
 | 
				
			||||||
        "//pkg/controller:go_default_library",
 | 
					        "//pkg/controller:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/scheduler:go_default_library",
 | 
					        "//pkg/scheduler:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/algorithmprovider:go_default_library",
 | 
					        "//pkg/scheduler/algorithmprovider:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/api:go_default_library",
 | 
					        "//pkg/scheduler/api:go_default_library",
 | 
				
			||||||
@@ -38,10 +37,8 @@ go_library(
 | 
				
			|||||||
        "//staging/src/k8s.io/apiserver/pkg/server/healthz:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/server/healthz:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/server/mux:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/server/mux:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/server/routes:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/server/routes:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/flag:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/util/flag:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/globalflag:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/util/globalflag:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/storage/v1:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/tools/leaderelection:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/tools/leaderelection:go_default_library",
 | 
				
			||||||
        "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
 | 
					        "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,17 +38,14 @@ import (
 | 
				
			|||||||
	"k8s.io/apiserver/pkg/server/healthz"
 | 
						"k8s.io/apiserver/pkg/server/healthz"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/server/mux"
 | 
						"k8s.io/apiserver/pkg/server/mux"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/server/routes"
 | 
						"k8s.io/apiserver/pkg/server/routes"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	apiserverflag "k8s.io/apiserver/pkg/util/flag"
 | 
						apiserverflag "k8s.io/apiserver/pkg/util/flag"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/util/globalflag"
 | 
						"k8s.io/apiserver/pkg/util/globalflag"
 | 
				
			||||||
	storageinformers "k8s.io/client-go/informers/storage/v1"
 | 
					 | 
				
			||||||
	v1core "k8s.io/client-go/kubernetes/typed/core/v1"
 | 
						v1core "k8s.io/client-go/kubernetes/typed/core/v1"
 | 
				
			||||||
	"k8s.io/client-go/tools/leaderelection"
 | 
						"k8s.io/client-go/tools/leaderelection"
 | 
				
			||||||
	schedulerserverconfig "k8s.io/kubernetes/cmd/kube-scheduler/app/config"
 | 
						schedulerserverconfig "k8s.io/kubernetes/cmd/kube-scheduler/app/config"
 | 
				
			||||||
	"k8s.io/kubernetes/cmd/kube-scheduler/app/options"
 | 
						"k8s.io/kubernetes/cmd/kube-scheduler/app/options"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
						"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controller"
 | 
						"k8s.io/kubernetes/pkg/controller"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler"
 | 
						"k8s.io/kubernetes/pkg/scheduler"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/algorithmprovider"
 | 
						"k8s.io/kubernetes/pkg/scheduler/algorithmprovider"
 | 
				
			||||||
	schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
 | 
						schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
 | 
				
			||||||
@@ -165,11 +162,6 @@ func runCommand(cmd *cobra.Command, args []string, opts *options.Options) error
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Run executes the scheduler based on the given configuration. It only return on error or when stopCh is closed.
 | 
					// Run executes the scheduler based on the given configuration. It only return on error or when stopCh is closed.
 | 
				
			||||||
func Run(cc schedulerserverconfig.CompletedConfig, stopCh <-chan struct{}) error {
 | 
					func Run(cc schedulerserverconfig.CompletedConfig, stopCh <-chan struct{}) error {
 | 
				
			||||||
	var storageClassInformer storageinformers.StorageClassInformer
 | 
					 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		storageClassInformer = cc.InformerFactory.Storage().V1().StorageClasses()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Create the scheduler.
 | 
						// Create the scheduler.
 | 
				
			||||||
	sched, err := scheduler.New(cc.Client,
 | 
						sched, err := scheduler.New(cc.Client,
 | 
				
			||||||
		cc.InformerFactory.Core().V1().Nodes(),
 | 
							cc.InformerFactory.Core().V1().Nodes(),
 | 
				
			||||||
@@ -181,7 +173,7 @@ func Run(cc schedulerserverconfig.CompletedConfig, stopCh <-chan struct{}) error
 | 
				
			|||||||
		cc.InformerFactory.Apps().V1().StatefulSets(),
 | 
							cc.InformerFactory.Apps().V1().StatefulSets(),
 | 
				
			||||||
		cc.InformerFactory.Core().V1().Services(),
 | 
							cc.InformerFactory.Core().V1().Services(),
 | 
				
			||||||
		cc.InformerFactory.Policy().V1beta1().PodDisruptionBudgets(),
 | 
							cc.InformerFactory.Policy().V1beta1().PodDisruptionBudgets(),
 | 
				
			||||||
		storageClassInformer,
 | 
							cc.InformerFactory.Storage().V1().StorageClasses(),
 | 
				
			||||||
		cc.Recorder,
 | 
							cc.Recorder,
 | 
				
			||||||
		cc.ComponentConfig.AlgorithmSource,
 | 
							cc.ComponentConfig.AlgorithmSource,
 | 
				
			||||||
		stopCh,
 | 
							stopCh,
 | 
				
			||||||
@@ -335,11 +327,6 @@ func newHealthzHandler(config *kubeschedulerconfig.KubeSchedulerConfiguration, s
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NewSchedulerConfig creates the scheduler configuration. This is exposed for use by tests.
 | 
					// NewSchedulerConfig creates the scheduler configuration. This is exposed for use by tests.
 | 
				
			||||||
func NewSchedulerConfig(s schedulerserverconfig.CompletedConfig) (*factory.Config, error) {
 | 
					func NewSchedulerConfig(s schedulerserverconfig.CompletedConfig) (*factory.Config, error) {
 | 
				
			||||||
	var storageClassInformer storageinformers.StorageClassInformer
 | 
					 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		storageClassInformer = s.InformerFactory.Storage().V1().StorageClasses()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Set up the configurator which can create schedulers from configs.
 | 
						// Set up the configurator which can create schedulers from configs.
 | 
				
			||||||
	configurator := factory.NewConfigFactory(&factory.ConfigFactoryArgs{
 | 
						configurator := factory.NewConfigFactory(&factory.ConfigFactoryArgs{
 | 
				
			||||||
		SchedulerName:                  s.ComponentConfig.SchedulerName,
 | 
							SchedulerName:                  s.ComponentConfig.SchedulerName,
 | 
				
			||||||
@@ -353,7 +340,7 @@ func NewSchedulerConfig(s schedulerserverconfig.CompletedConfig) (*factory.Confi
 | 
				
			|||||||
		StatefulSetInformer:            s.InformerFactory.Apps().V1().StatefulSets(),
 | 
							StatefulSetInformer:            s.InformerFactory.Apps().V1().StatefulSets(),
 | 
				
			||||||
		ServiceInformer:                s.InformerFactory.Core().V1().Services(),
 | 
							ServiceInformer:                s.InformerFactory.Core().V1().Services(),
 | 
				
			||||||
		PdbInformer:                    s.InformerFactory.Policy().V1beta1().PodDisruptionBudgets(),
 | 
							PdbInformer:                    s.InformerFactory.Policy().V1beta1().PodDisruptionBudgets(),
 | 
				
			||||||
		StorageClassInformer:           storageClassInformer,
 | 
							StorageClassInformer:           s.InformerFactory.Storage().V1().StorageClasses(),
 | 
				
			||||||
		HardPodAffinitySymmetricWeight: s.ComponentConfig.HardPodAffinitySymmetricWeight,
 | 
							HardPodAffinitySymmetricWeight: s.ComponentConfig.HardPodAffinitySymmetricWeight,
 | 
				
			||||||
		DisablePreemption:              s.ComponentConfig.DisablePreemption,
 | 
							DisablePreemption:              s.ComponentConfig.DisablePreemption,
 | 
				
			||||||
		PercentageOfNodesToScore:       s.ComponentConfig.PercentageOfNodesToScore,
 | 
							PercentageOfNodesToScore:       s.ComponentConfig.PercentageOfNodesToScore,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1777,12 +1777,10 @@ func ValidatePersistentVolumeUpdate(newPv, oldPv *core.PersistentVolume) field.E
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.VolumeMode, oldPv.Spec.VolumeMode, field.NewPath("volumeMode"))...)
 | 
						allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.VolumeMode, oldPv.Spec.VolumeMode, field.NewPath("volumeMode"))...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
	// Allow setting NodeAffinity if oldPv NodeAffinity was not set
 | 
						// Allow setting NodeAffinity if oldPv NodeAffinity was not set
 | 
				
			||||||
	if oldPv.Spec.NodeAffinity != nil {
 | 
						if oldPv.Spec.NodeAffinity != nil {
 | 
				
			||||||
		allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.NodeAffinity, oldPv.Spec.NodeAffinity, field.NewPath("nodeAffinity"))...)
 | 
							allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.NodeAffinity, oldPv.Spec.NodeAffinity, field.NewPath("nodeAffinity"))...)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -3160,9 +3158,7 @@ func ValidateTopologySelectorTerm(term core.TopologySelectorTerm, fldPath *field
 | 
				
			|||||||
	exprMap := make(map[string]sets.String)
 | 
						exprMap := make(map[string]sets.String)
 | 
				
			||||||
	exprPath := fldPath.Child("matchLabelExpressions")
 | 
						exprPath := fldPath.Child("matchLabelExpressions")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
	// Allow empty MatchLabelExpressions, in case this field becomes optional in the future.
 | 
						// Allow empty MatchLabelExpressions, in case this field becomes optional in the future.
 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i, req := range term.MatchLabelExpressions {
 | 
						for i, req := range term.MatchLabelExpressions {
 | 
				
			||||||
		idxPath := exprPath.Index(i)
 | 
							idxPath := exprPath.Index(i)
 | 
				
			||||||
		valueSet, exprErrs := validateTopologySelectorLabelRequirement(req, idxPath)
 | 
							valueSet, exprErrs := validateTopologySelectorLabelRequirement(req, idxPath)
 | 
				
			||||||
@@ -3174,9 +3170,6 @@ func ValidateTopologySelectorTerm(term core.TopologySelectorTerm, fldPath *field
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		exprMap[req.Key] = valueSet
 | 
							exprMap[req.Key] = valueSet
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	} else if len(term.MatchLabelExpressions) != 0 {
 | 
					 | 
				
			||||||
		allErrs = append(allErrs, field.Forbidden(fldPath, "field is disabled by feature-gate VolumeScheduling"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return exprMap, allErrs
 | 
						return exprMap, allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -5319,10 +5312,6 @@ func validateVolumeNodeAffinity(nodeAffinity *core.VolumeNodeAffinity, fldPath *
 | 
				
			|||||||
		return false, allErrs
 | 
							return false, allErrs
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		allErrs = append(allErrs, field.Forbidden(fldPath, "Volume node affinity is disabled by feature-gate"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if nodeAffinity.Required != nil {
 | 
						if nodeAffinity.Required != nil {
 | 
				
			||||||
		allErrs = append(allErrs, ValidateNodeSelector(nodeAffinity.Required, fldPath.Child("required"))...)
 | 
							allErrs = append(allErrs, ValidateNodeSelector(nodeAffinity.Required, fldPath.Child("required"))...)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -577,19 +577,6 @@ func TestValidateLocalVolumesDisabled(t *testing.T) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	for name, scenario := range scenarios {
 | 
					 | 
				
			||||||
		t.Run(name+" VolumeScheduling disabled", func(t *testing.T) {
 | 
					 | 
				
			||||||
			defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
 | 
					 | 
				
			||||||
			errs := ValidatePersistentVolume(scenario.volume)
 | 
					 | 
				
			||||||
			if len(errs) == 0 && scenario.isExpectedFailure {
 | 
					 | 
				
			||||||
				t.Errorf("Unexpected success for scenario: %s", name)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if len(errs) > 0 && !scenario.isExpectedFailure {
 | 
					 | 
				
			||||||
				t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func testVolumeWithNodeAffinity(affinity *core.VolumeNodeAffinity) *core.PersistentVolume {
 | 
					func testVolumeWithNodeAffinity(affinity *core.VolumeNodeAffinity) *core.PersistentVolume {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,6 @@ go_test(
 | 
				
			|||||||
    srcs = ["util_test.go"],
 | 
					    srcs = ["util_test.go"],
 | 
				
			||||||
    embed = [":go_default_library"],
 | 
					    embed = [":go_default_library"],
 | 
				
			||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/apis/core:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/apis/storage:go_default_library",
 | 
					        "//pkg/apis/storage:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					        "//pkg/features:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,14 +24,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// DropDisabledFields removes disabled fields from the StorageClass object.
 | 
					// DropDisabledFields removes disabled fields from the StorageClass object.
 | 
				
			||||||
func DropDisabledFields(class, oldClass *storage.StorageClass) {
 | 
					func DropDisabledFields(class, oldClass *storage.StorageClass) {
 | 
				
			||||||
	if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		class.VolumeBindingMode = nil
 | 
					 | 
				
			||||||
		class.AllowedTopologies = nil
 | 
					 | 
				
			||||||
		if oldClass != nil {
 | 
					 | 
				
			||||||
			oldClass.VolumeBindingMode = nil
 | 
					 | 
				
			||||||
			oldClass.AllowedTopologies = nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) && !allowVolumeExpansionInUse(oldClass) {
 | 
						if !utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) && !allowVolumeExpansionInUse(oldClass) {
 | 
				
			||||||
		class.AllowVolumeExpansion = nil
 | 
							class.AllowVolumeExpansion = nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,53 +24,10 @@ import (
 | 
				
			|||||||
	"k8s.io/apimachinery/pkg/util/diff"
 | 
						"k8s.io/apimachinery/pkg/util/diff"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
						utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/storage"
 | 
						"k8s.io/kubernetes/pkg/apis/storage"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestDropAlphaFields(t *testing.T) {
 | 
					 | 
				
			||||||
	bindingMode := storage.VolumeBindingWaitForFirstConsumer
 | 
					 | 
				
			||||||
	allowedTopologies := []api.TopologySelectorTerm{
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			MatchLabelExpressions: []api.TopologySelectorLabelRequirement{
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					Key:    "kubernetes.io/hostname",
 | 
					 | 
				
			||||||
					Values: []string{"node1"},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Test that field gets dropped when feature gate is not set
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
 | 
					 | 
				
			||||||
	class := &storage.StorageClass{
 | 
					 | 
				
			||||||
		VolumeBindingMode: &bindingMode,
 | 
					 | 
				
			||||||
		AllowedTopologies: allowedTopologies,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	DropDisabledFields(class, nil)
 | 
					 | 
				
			||||||
	if class.VolumeBindingMode != nil {
 | 
					 | 
				
			||||||
		t.Errorf("VolumeBindingMode field didn't get dropped: %+v", class.VolumeBindingMode)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if class.AllowedTopologies != nil {
 | 
					 | 
				
			||||||
		t.Errorf("AllowedTopologies field didn't get dropped: %+v", class.AllowedTopologies)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Test that field does not get dropped when feature gate is set
 | 
					 | 
				
			||||||
	class = &storage.StorageClass{
 | 
					 | 
				
			||||||
		VolumeBindingMode: &bindingMode,
 | 
					 | 
				
			||||||
		AllowedTopologies: allowedTopologies,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	DropDisabledFields(class, nil)
 | 
					 | 
				
			||||||
	if class.VolumeBindingMode != &bindingMode {
 | 
					 | 
				
			||||||
		t.Errorf("VolumeBindingMode field got unexpectantly modified: %+v", class.VolumeBindingMode)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !reflect.DeepEqual(class.AllowedTopologies, allowedTopologies) {
 | 
					 | 
				
			||||||
		t.Errorf("AllowedTopologies field got unexpectantly modified: %+v", class.AllowedTopologies)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestDropAllowVolumeExpansion(t *testing.T) {
 | 
					func TestDropAllowVolumeExpansion(t *testing.T) {
 | 
				
			||||||
	allowVolumeExpansion := false
 | 
						allowVolumeExpansion := false
 | 
				
			||||||
	scWithoutAllowVolumeExpansion := func() *storage.StorageClass {
 | 
						scWithoutAllowVolumeExpansion := func() *storage.StorageClass {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,13 +19,11 @@ go_library(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/apis/core:go_default_library",
 | 
					        "//pkg/apis/core:go_default_library",
 | 
				
			||||||
        "//pkg/apis/storage:go_default_library",
 | 
					        "//pkg/apis/storage:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/api/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/core/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/api/storage/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/storage/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,10 +50,7 @@ go_test(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/api/legacyscheme:go_default_library",
 | 
					        "//pkg/api/legacyscheme:go_default_library",
 | 
				
			||||||
        "//pkg/apis/storage/install:go_default_library",
 | 
					        "//pkg/apis/storage/install:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/api/storage/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/storage/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,6 @@ import (
 | 
				
			|||||||
	"k8s.io/api/core/v1"
 | 
						"k8s.io/api/core/v1"
 | 
				
			||||||
	storagev1 "k8s.io/api/storage/v1"
 | 
						storagev1 "k8s.io/api/storage/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
 | 
					func addDefaultingFuncs(scheme *runtime.Scheme) error {
 | 
				
			||||||
@@ -34,7 +32,7 @@ func SetDefaults_StorageClass(obj *storagev1.StorageClass) {
 | 
				
			|||||||
		*obj.ReclaimPolicy = v1.PersistentVolumeReclaimDelete
 | 
							*obj.ReclaimPolicy = v1.PersistentVolumeReclaimDelete
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if obj.VolumeBindingMode == nil && utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
						if obj.VolumeBindingMode == nil {
 | 
				
			||||||
		obj.VolumeBindingMode = new(storagev1.VolumeBindingMode)
 | 
							obj.VolumeBindingMode = new(storagev1.VolumeBindingMode)
 | 
				
			||||||
		*obj.VolumeBindingMode = storagev1.VolumeBindingImmediate
 | 
							*obj.VolumeBindingMode = storagev1.VolumeBindingImmediate
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,11 +22,8 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	storagev1 "k8s.io/api/storage/v1"
 | 
						storagev1 "k8s.io/api/storage/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
						"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
				
			||||||
	_ "k8s.io/kubernetes/pkg/apis/storage/install"
 | 
						_ "k8s.io/kubernetes/pkg/apis/storage/install"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
 | 
					func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
 | 
				
			||||||
@@ -53,7 +50,7 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
 | 
				
			|||||||
func TestSetDefaultVolumeBindingMode(t *testing.T) {
 | 
					func TestSetDefaultVolumeBindingMode(t *testing.T) {
 | 
				
			||||||
	class := &storagev1.StorageClass{}
 | 
						class := &storagev1.StorageClass{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// When feature gate is enabled, field should be defaulted
 | 
						// field should be defaulted
 | 
				
			||||||
	defaultMode := storagev1.VolumeBindingImmediate
 | 
						defaultMode := storagev1.VolumeBindingImmediate
 | 
				
			||||||
	output := roundTrip(t, runtime.Object(class)).(*storagev1.StorageClass)
 | 
						output := roundTrip(t, runtime.Object(class)).(*storagev1.StorageClass)
 | 
				
			||||||
	outMode := output.VolumeBindingMode
 | 
						outMode := output.VolumeBindingMode
 | 
				
			||||||
@@ -62,13 +59,4 @@ func TestSetDefaultVolumeBindingMode(t *testing.T) {
 | 
				
			|||||||
	} else if *outMode != defaultMode {
 | 
						} else if *outMode != defaultMode {
 | 
				
			||||||
		t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode)
 | 
							t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	class = &storagev1.StorageClass{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// When feature gate is disabled, field should not be defaulted
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
 | 
					 | 
				
			||||||
	output = roundTrip(t, runtime.Object(class)).(*storagev1.StorageClass)
 | 
					 | 
				
			||||||
	if output.VolumeBindingMode != nil {
 | 
					 | 
				
			||||||
		t.Errorf("Expected VolumeBindingMode to not be defaulted, got: %+v", output.VolumeBindingMode)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,13 +19,11 @@ go_library(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/apis/core:go_default_library",
 | 
					        "//pkg/apis/core:go_default_library",
 | 
				
			||||||
        "//pkg/apis/storage:go_default_library",
 | 
					        "//pkg/apis/storage:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/api/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/core/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,10 +50,7 @@ go_test(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/api/legacyscheme:go_default_library",
 | 
					        "//pkg/api/legacyscheme:go_default_library",
 | 
				
			||||||
        "//pkg/apis/storage/install:go_default_library",
 | 
					        "//pkg/apis/storage/install:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,6 @@ import (
 | 
				
			|||||||
	"k8s.io/api/core/v1"
 | 
						"k8s.io/api/core/v1"
 | 
				
			||||||
	storagev1beta1 "k8s.io/api/storage/v1beta1"
 | 
						storagev1beta1 "k8s.io/api/storage/v1beta1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
 | 
					func addDefaultingFuncs(scheme *runtime.Scheme) error {
 | 
				
			||||||
@@ -34,7 +32,7 @@ func SetDefaults_StorageClass(obj *storagev1beta1.StorageClass) {
 | 
				
			|||||||
		*obj.ReclaimPolicy = v1.PersistentVolumeReclaimDelete
 | 
							*obj.ReclaimPolicy = v1.PersistentVolumeReclaimDelete
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if obj.VolumeBindingMode == nil && utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
						if obj.VolumeBindingMode == nil {
 | 
				
			||||||
		obj.VolumeBindingMode = new(storagev1beta1.VolumeBindingMode)
 | 
							obj.VolumeBindingMode = new(storagev1beta1.VolumeBindingMode)
 | 
				
			||||||
		*obj.VolumeBindingMode = storagev1beta1.VolumeBindingImmediate
 | 
							*obj.VolumeBindingMode = storagev1beta1.VolumeBindingImmediate
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,11 +22,8 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	storagev1beta1 "k8s.io/api/storage/v1beta1"
 | 
						storagev1beta1 "k8s.io/api/storage/v1beta1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
						"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
				
			||||||
	_ "k8s.io/kubernetes/pkg/apis/storage/install"
 | 
						_ "k8s.io/kubernetes/pkg/apis/storage/install"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
 | 
					func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
 | 
				
			||||||
@@ -53,7 +50,7 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
 | 
				
			|||||||
func TestSetDefaultVolumeBindingMode(t *testing.T) {
 | 
					func TestSetDefaultVolumeBindingMode(t *testing.T) {
 | 
				
			||||||
	class := &storagev1beta1.StorageClass{}
 | 
						class := &storagev1beta1.StorageClass{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// When feature gate is enabled, field should be defaulted
 | 
						// field should be defaulted
 | 
				
			||||||
	defaultMode := storagev1beta1.VolumeBindingImmediate
 | 
						defaultMode := storagev1beta1.VolumeBindingImmediate
 | 
				
			||||||
	output := roundTrip(t, runtime.Object(class)).(*storagev1beta1.StorageClass)
 | 
						output := roundTrip(t, runtime.Object(class)).(*storagev1beta1.StorageClass)
 | 
				
			||||||
	outMode := output.VolumeBindingMode
 | 
						outMode := output.VolumeBindingMode
 | 
				
			||||||
@@ -62,14 +59,4 @@ func TestSetDefaultVolumeBindingMode(t *testing.T) {
 | 
				
			|||||||
	} else if *outMode != defaultMode {
 | 
						} else if *outMode != defaultMode {
 | 
				
			||||||
		t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode)
 | 
							t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	class = &storagev1beta1.StorageClass{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// When feature gate is disabled, field should not be defaulted
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
 | 
					 | 
				
			||||||
	output = roundTrip(t, runtime.Object(class)).(*storagev1beta1.StorageClass)
 | 
					 | 
				
			||||||
	if output.VolumeBindingMode != nil {
 | 
					 | 
				
			||||||
		t.Errorf("Expected VolumeBindingMode to not be defaulted, got: %+v", output.VolumeBindingMode)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,12 +15,10 @@ go_library(
 | 
				
			|||||||
        "//pkg/apis/core/helper:go_default_library",
 | 
					        "//pkg/apis/core/helper:go_default_library",
 | 
				
			||||||
        "//pkg/apis/core/validation:go_default_library",
 | 
					        "//pkg/apis/core/validation:go_default_library",
 | 
				
			||||||
        "//pkg/apis/storage:go_default_library",
 | 
					        "//pkg/apis/storage:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -31,10 +29,7 @@ go_test(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/apis/core:go_default_library",
 | 
					        "//pkg/apis/core:go_default_library",
 | 
				
			||||||
        "//pkg/apis/storage:go_default_library",
 | 
					        "//pkg/apis/storage:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,12 +24,10 @@ import (
 | 
				
			|||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/validation"
 | 
						"k8s.io/apimachinery/pkg/util/validation"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/validation/field"
 | 
						"k8s.io/apimachinery/pkg/util/validation/field"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						api "k8s.io/kubernetes/pkg/apis/core"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
						"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
				
			||||||
	apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
 | 
						apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/storage"
 | 
						"k8s.io/kubernetes/pkg/apis/storage"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -233,15 +231,11 @@ var supportedVolumeBindingModes = sets.NewString(string(storage.VolumeBindingImm
 | 
				
			|||||||
// validateVolumeBindingMode tests that VolumeBindingMode specifies valid values.
 | 
					// validateVolumeBindingMode tests that VolumeBindingMode specifies valid values.
 | 
				
			||||||
func validateVolumeBindingMode(mode *storage.VolumeBindingMode, fldPath *field.Path) field.ErrorList {
 | 
					func validateVolumeBindingMode(mode *storage.VolumeBindingMode, fldPath *field.Path) field.ErrorList {
 | 
				
			||||||
	allErrs := field.ErrorList{}
 | 
						allErrs := field.ErrorList{}
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
	if mode == nil {
 | 
						if mode == nil {
 | 
				
			||||||
		allErrs = append(allErrs, field.Required(fldPath, ""))
 | 
							allErrs = append(allErrs, field.Required(fldPath, ""))
 | 
				
			||||||
	} else if !supportedVolumeBindingModes.Has(string(*mode)) {
 | 
						} else if !supportedVolumeBindingModes.Has(string(*mode)) {
 | 
				
			||||||
		allErrs = append(allErrs, field.NotSupported(fldPath, mode, supportedVolumeBindingModes.List()))
 | 
							allErrs = append(allErrs, field.NotSupported(fldPath, mode, supportedVolumeBindingModes.List()))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	} else if mode != nil {
 | 
					 | 
				
			||||||
		allErrs = append(allErrs, field.Forbidden(fldPath, "field is disabled by feature-gate VolumeScheduling"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -254,10 +248,6 @@ func validateAllowedTopologies(topologies []api.TopologySelectorTerm, fldPath *f
 | 
				
			|||||||
		return allErrs
 | 
							return allErrs
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		allErrs = append(allErrs, field.Forbidden(fldPath, "field is disabled by feature-gate VolumeScheduling"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rawTopologies := make([]map[string]sets.String, len(topologies))
 | 
						rawTopologies := make([]map[string]sets.String, len(topologies))
 | 
				
			||||||
	for i, term := range topologies {
 | 
						for i, term := range topologies {
 | 
				
			||||||
		idxPath := fldPath.Index(i)
 | 
							idxPath := fldPath.Index(i)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,11 +22,8 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						api "k8s.io/kubernetes/pkg/apis/core"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/storage"
 | 
						"k8s.io/kubernetes/pkg/apis/storage"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@@ -480,22 +477,6 @@ func makeClass(mode *storage.VolumeBindingMode, topologies []api.TopologySelecto
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: Remove these tests once feature gate is not required
 | 
					 | 
				
			||||||
func TestValidateVolumeBindingModeAlphaDisabled(t *testing.T) {
 | 
					 | 
				
			||||||
	errorCases := map[string]*storage.StorageClass{
 | 
					 | 
				
			||||||
		"immediate mode": makeClass(&immediateMode1, nil),
 | 
					 | 
				
			||||||
		"waiting mode":   makeClass(&waitingMode, nil),
 | 
					 | 
				
			||||||
		"invalid mode":   makeClass(&invalidMode, nil),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
 | 
					 | 
				
			||||||
	for testName, storageClass := range errorCases {
 | 
					 | 
				
			||||||
		if errs := ValidateStorageClass(storageClass); len(errs) == 0 {
 | 
					 | 
				
			||||||
			t.Errorf("Expected failure for test: %v", testName)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type bindingTest struct {
 | 
					type bindingTest struct {
 | 
				
			||||||
	class         *storage.StorageClass
 | 
						class         *storage.StorageClass
 | 
				
			||||||
	shouldSucceed bool
 | 
						shouldSucceed bool
 | 
				
			||||||
@@ -521,8 +502,6 @@ func TestValidateVolumeBindingMode(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: remove when feature gate not required
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	for testName, testCase := range cases {
 | 
						for testName, testCase := range cases {
 | 
				
			||||||
		errs := ValidateStorageClass(testCase.class)
 | 
							errs := ValidateStorageClass(testCase.class)
 | 
				
			||||||
		if testCase.shouldSucceed && len(errs) != 0 {
 | 
							if testCase.shouldSucceed && len(errs) != 0 {
 | 
				
			||||||
@@ -579,8 +558,6 @@ func TestValidateUpdateVolumeBindingMode(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: remove when feature gate not required
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	for testName, testCase := range cases {
 | 
						for testName, testCase := range cases {
 | 
				
			||||||
		errs := ValidateStorageClassUpdate(testCase.newClass, testCase.oldClass)
 | 
							errs := ValidateStorageClassUpdate(testCase.newClass, testCase.oldClass)
 | 
				
			||||||
		if testCase.shouldSucceed && len(errs) != 0 {
 | 
							if testCase.shouldSucceed && len(errs) != 0 {
 | 
				
			||||||
@@ -883,7 +860,6 @@ func TestValidateAllowedTopologies(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	for testName, testCase := range cases {
 | 
						for testName, testCase := range cases {
 | 
				
			||||||
		errs := ValidateStorageClass(testCase.class)
 | 
							errs := ValidateStorageClass(testCase.class)
 | 
				
			||||||
		if testCase.shouldSucceed && len(errs) != 0 {
 | 
							if testCase.shouldSucceed && len(errs) != 0 {
 | 
				
			||||||
@@ -893,12 +869,4 @@ func TestValidateAllowedTopologies(t *testing.T) {
 | 
				
			|||||||
			t.Errorf("Expected failure for test %q, got success", testName)
 | 
								t.Errorf("Expected failure for test %q, got success", testName)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
 | 
					 | 
				
			||||||
	for testName, testCase := range cases {
 | 
					 | 
				
			||||||
		errs := ValidateStorageClass(testCase.class)
 | 
					 | 
				
			||||||
		if len(errs) == 0 && testCase.class.AllowedTopologies != nil {
 | 
					 | 
				
			||||||
			t.Errorf("Expected failure for test %q, got success", testName)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,6 @@ go_library(
 | 
				
			|||||||
        "//pkg/api/v1/node:go_default_library",
 | 
					        "//pkg/api/v1/node:go_default_library",
 | 
				
			||||||
        "//pkg/apis/core/v1/helper:go_default_library",
 | 
					        "//pkg/apis/core/v1/helper:go_default_library",
 | 
				
			||||||
        "//pkg/controller:go_default_library",
 | 
					        "//pkg/controller:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/apis:go_default_library",
 | 
					        "//pkg/kubelet/apis:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/api:go_default_library",
 | 
					        "//pkg/scheduler/api:go_default_library",
 | 
				
			||||||
        "//pkg/util/node:go_default_library",
 | 
					        "//pkg/util/node:go_default_library",
 | 
				
			||||||
@@ -33,7 +32,6 @@ go_library(
 | 
				
			|||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
 | 
				
			||||||
@@ -60,7 +58,6 @@ go_test(
 | 
				
			|||||||
        "//pkg/cloudprovider/providers/fake:go_default_library",
 | 
					        "//pkg/cloudprovider/providers/fake:go_default_library",
 | 
				
			||||||
        "//pkg/controller:go_default_library",
 | 
					        "//pkg/controller:go_default_library",
 | 
				
			||||||
        "//pkg/controller/testutil:go_default_library",
 | 
					        "//pkg/controller/testutil:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/apis:go_default_library",
 | 
					        "//pkg/kubelet/apis:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/api:go_default_library",
 | 
					        "//pkg/scheduler/api:go_default_library",
 | 
				
			||||||
        "//pkg/volume/util:go_default_library",
 | 
					        "//pkg/volume/util:go_default_library",
 | 
				
			||||||
@@ -69,8 +66,6 @@ go_test(
 | 
				
			|||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,6 @@ import (
 | 
				
			|||||||
	"k8s.io/apimachinery/pkg/util/strategicpatch"
 | 
						"k8s.io/apimachinery/pkg/util/strategicpatch"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/watch"
 | 
						"k8s.io/apimachinery/pkg/watch"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	"k8s.io/client-go/kubernetes"
 | 
						"k8s.io/client-go/kubernetes"
 | 
				
			||||||
	corelisters "k8s.io/client-go/listers/core/v1"
 | 
						corelisters "k8s.io/client-go/listers/core/v1"
 | 
				
			||||||
	"k8s.io/client-go/tools/cache"
 | 
						"k8s.io/client-go/tools/cache"
 | 
				
			||||||
@@ -41,7 +40,6 @@ import (
 | 
				
			|||||||
	cloudprovider "k8s.io/cloud-provider"
 | 
						cloudprovider "k8s.io/cloud-provider"
 | 
				
			||||||
	v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
 | 
						v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controller"
 | 
						"k8s.io/kubernetes/pkg/controller"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
						kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
				
			||||||
	volumeutil "k8s.io/kubernetes/pkg/volume/util"
 | 
						volumeutil "k8s.io/kubernetes/pkg/volume/util"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -204,7 +202,7 @@ func (pvlc *PersistentVolumeLabelController) addLabelsAndAffinityToVolume(vol *v
 | 
				
			|||||||
func (pvlc *PersistentVolumeLabelController) createPatch(vol *v1.PersistentVolume, volLabels map[string]string) ([]byte, error) {
 | 
					func (pvlc *PersistentVolumeLabelController) createPatch(vol *v1.PersistentVolume, volLabels map[string]string) ([]byte, error) {
 | 
				
			||||||
	volName := vol.Name
 | 
						volName := vol.Name
 | 
				
			||||||
	newVolume := vol.DeepCopyObject().(*v1.PersistentVolume)
 | 
						newVolume := vol.DeepCopyObject().(*v1.PersistentVolume)
 | 
				
			||||||
	populateAffinity := utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) && len(volLabels) != 0
 | 
						populateAffinity := len(volLabels) != 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if newVolume.Labels == nil {
 | 
						if newVolume.Labels == nil {
 | 
				
			||||||
		newVolume.Labels = make(map[string]string)
 | 
							newVolume.Labels = make(map[string]string)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,11 +27,8 @@ import (
 | 
				
			|||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sets "k8s.io/apimachinery/pkg/util/sets"
 | 
						sets "k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	"k8s.io/client-go/kubernetes/fake"
 | 
						"k8s.io/client-go/kubernetes/fake"
 | 
				
			||||||
	core "k8s.io/client-go/testing"
 | 
						core "k8s.io/client-go/testing"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
						kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
				
			||||||
	volumeutil "k8s.io/kubernetes/pkg/volume/util"
 | 
						volumeutil "k8s.io/kubernetes/pkg/volume/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -451,7 +448,6 @@ func TestCreatePatch(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	for d, tc := range testCases {
 | 
						for d, tc := range testCases {
 | 
				
			||||||
		cloud := &fakecloud.FakeCloud{}
 | 
							cloud := &fakecloud.FakeCloud{}
 | 
				
			||||||
		client := fake.NewSimpleClientset()
 | 
							client := fake.NewSimpleClientset()
 | 
				
			||||||
@@ -520,8 +516,6 @@ func TestAddLabelsToVolume(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for d, tc := range testCases {
 | 
						for d, tc := range testCases {
 | 
				
			||||||
		labeledCh := make(chan bool, 1)
 | 
							labeledCh := make(chan bool, 1)
 | 
				
			||||||
		client := fake.NewSimpleClientset()
 | 
							client := fake.NewSimpleClientset()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -286,10 +286,6 @@ func checkVolumeSatisfyClaim(volume *v1.PersistentVolume, claim *v1.PersistentVo
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ctrl *PersistentVolumeController) shouldDelayBinding(claim *v1.PersistentVolumeClaim) (bool, error) {
 | 
					func (ctrl *PersistentVolumeController) shouldDelayBinding(claim *v1.PersistentVolumeClaim) (bool, error) {
 | 
				
			||||||
	if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// When feature VolumeScheduling enabled,
 | 
						// When feature VolumeScheduling enabled,
 | 
				
			||||||
	// Scheduler signal to the PV controller to start dynamic
 | 
						// Scheduler signal to the PV controller to start dynamic
 | 
				
			||||||
	// provisioning by setting the "annSelectedNode" annotation
 | 
						// provisioning by setting the "annSelectedNode" annotation
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,15 +24,12 @@ import (
 | 
				
			|||||||
	storagev1 "k8s.io/api/storage/v1"
 | 
						storagev1 "k8s.io/api/storage/v1"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/watch"
 | 
						"k8s.io/apimachinery/pkg/watch"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	"k8s.io/client-go/informers"
 | 
						"k8s.io/client-go/informers"
 | 
				
			||||||
	"k8s.io/client-go/kubernetes/fake"
 | 
						"k8s.io/client-go/kubernetes/fake"
 | 
				
			||||||
	core "k8s.io/client-go/testing"
 | 
						core "k8s.io/client-go/testing"
 | 
				
			||||||
	"k8s.io/client-go/tools/cache"
 | 
						"k8s.io/client-go/tools/cache"
 | 
				
			||||||
	"k8s.io/klog"
 | 
						"k8s.io/klog"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controller"
 | 
						"k8s.io/kubernetes/pkg/controller"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@@ -336,24 +333,3 @@ func TestDelayBinding(t *testing.T) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestDelayBindingDisabled(t *testing.T) {
 | 
					 | 
				
			||||||
	// When volumeScheduling feature gate is disabled, should always be immediate
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	client := &fake.Clientset{}
 | 
					 | 
				
			||||||
	informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
					 | 
				
			||||||
	classInformer := informerFactory.Storage().V1().StorageClasses()
 | 
					 | 
				
			||||||
	ctrl := &PersistentVolumeController{
 | 
					 | 
				
			||||||
		classLister: classInformer.Lister(),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	name := "volumeScheduling-feature-disabled"
 | 
					 | 
				
			||||||
	shouldDelay, err := ctrl.shouldDelayBinding(makePVCClass(&classWaitMode, false))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Errorf("Test %q returned error: %v", name, err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if shouldDelay {
 | 
					 | 
				
			||||||
		t.Errorf("Test %q returned true, expected false", name)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -413,7 +413,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
 | 
				
			|||||||
	PodShareProcessNamespace:                    {Default: true, PreRelease: utilfeature.Beta},
 | 
						PodShareProcessNamespace:                    {Default: true, PreRelease: utilfeature.Beta},
 | 
				
			||||||
	PodPriority:                                 {Default: true, PreRelease: utilfeature.Beta},
 | 
						PodPriority:                                 {Default: true, PreRelease: utilfeature.Beta},
 | 
				
			||||||
	TaintNodesByCondition:                       {Default: true, PreRelease: utilfeature.Beta},
 | 
						TaintNodesByCondition:                       {Default: true, PreRelease: utilfeature.Beta},
 | 
				
			||||||
	MountPropagation:                            {Default: true, PreRelease: utilfeature.GA},
 | 
						MountPropagation:                            {Default: true, PreRelease: utilfeature.GA, LockToDefault: true}, // remove in 1.14
 | 
				
			||||||
	QOSReserved:                                 {Default: false, PreRelease: utilfeature.Alpha},
 | 
						QOSReserved:                                 {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
	ExpandPersistentVolumes:                     {Default: true, PreRelease: utilfeature.Beta},
 | 
						ExpandPersistentVolumes:                     {Default: true, PreRelease: utilfeature.Beta},
 | 
				
			||||||
	ExpandInUsePersistentVolumes:                {Default: false, PreRelease: utilfeature.Alpha},
 | 
						ExpandInUsePersistentVolumes:                {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
@@ -422,7 +422,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
 | 
				
			|||||||
	CPUCFSQuotaPeriod:                           {Default: false, PreRelease: utilfeature.Alpha},
 | 
						CPUCFSQuotaPeriod:                           {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
	ServiceNodeExclusion:                        {Default: false, PreRelease: utilfeature.Alpha},
 | 
						ServiceNodeExclusion:                        {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
	MountContainers:                             {Default: false, PreRelease: utilfeature.Alpha},
 | 
						MountContainers:                             {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
	VolumeScheduling:                            {Default: true, PreRelease: utilfeature.GA},
 | 
						VolumeScheduling:                            {Default: true, PreRelease: utilfeature.GA, LockToDefault: true}, // remove in 1.16
 | 
				
			||||||
	CSIPersistentVolume:                         {Default: true, PreRelease: utilfeature.GA},
 | 
						CSIPersistentVolume:                         {Default: true, PreRelease: utilfeature.GA},
 | 
				
			||||||
	CSIDriverRegistry:                           {Default: false, PreRelease: utilfeature.Alpha},
 | 
						CSIDriverRegistry:                           {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
	CSINodeInfo:                                 {Default: false, PreRelease: utilfeature.Alpha},
 | 
						CSINodeInfo:                                 {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,6 @@ go_library(
 | 
				
			|||||||
    importpath = "k8s.io/kubernetes/pkg/scheduler",
 | 
					    importpath = "k8s.io/kubernetes/pkg/scheduler",
 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					    visibility = ["//visibility:public"],
 | 
				
			||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/scheduler/algorithm:go_default_library",
 | 
					        "//pkg/scheduler/algorithm:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/algorithm/predicates:go_default_library",
 | 
					        "//pkg/scheduler/algorithm/predicates:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/api:go_default_library",
 | 
					        "//pkg/scheduler/api:go_default_library",
 | 
				
			||||||
@@ -27,7 +26,6 @@ go_library(
 | 
				
			|||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/apps/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers/apps/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/policy/v1beta1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers/policy/v1beta1:go_default_library",
 | 
				
			||||||
@@ -46,7 +44,6 @@ go_test(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/api/legacyscheme:go_default_library",
 | 
					        "//pkg/api/legacyscheme:go_default_library",
 | 
				
			||||||
        "//pkg/controller/volume/persistentvolume:go_default_library",
 | 
					        "//pkg/controller/volume/persistentvolume:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/scheduler/algorithm:go_default_library",
 | 
					        "//pkg/scheduler/algorithm:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/algorithm/predicates:go_default_library",
 | 
					        "//pkg/scheduler/algorithm/predicates:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/api:go_default_library",
 | 
					        "//pkg/scheduler/api:go_default_library",
 | 
				
			||||||
@@ -66,8 +63,6 @@ go_test(
 | 
				
			|||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -635,7 +635,6 @@ func (c *VolumeZoneChecker) predicate(pod *v1.Pod, meta PredicateMetadata, nodeI
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			pvName := pvc.Spec.VolumeName
 | 
								pvName := pvc.Spec.VolumeName
 | 
				
			||||||
			if pvName == "" {
 | 
								if pvName == "" {
 | 
				
			||||||
				if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
				scName := v1helper.GetPersistentVolumeClaimClass(pvc)
 | 
									scName := v1helper.GetPersistentVolumeClaimClass(pvc)
 | 
				
			||||||
				if len(scName) > 0 {
 | 
									if len(scName) > 0 {
 | 
				
			||||||
					class, _ := c.classInfo.GetStorageClassInfo(scName)
 | 
										class, _ := c.classInfo.GetStorageClassInfo(scName)
 | 
				
			||||||
@@ -649,7 +648,6 @@ func (c *VolumeZoneChecker) predicate(pod *v1.Pod, meta PredicateMetadata, nodeI
 | 
				
			|||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return false, nil, fmt.Errorf("PersistentVolumeClaim is not bound: %q", pvcName)
 | 
									return false, nil, fmt.Errorf("PersistentVolumeClaim is not bound: %q", pvcName)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1618,10 +1616,6 @@ func NewVolumeBindingPredicate(binder *volumebinder.VolumeBinder) FitPredicate {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *VolumeBindingChecker) predicate(pod *v1.Pod, meta PredicateMetadata, nodeInfo *schedulernodeinfo.NodeInfo) (bool, []PredicateFailureReason, error) {
 | 
					func (c *VolumeBindingChecker) predicate(pod *v1.Pod, meta PredicateMetadata, nodeInfo *schedulernodeinfo.NodeInfo) (bool, []PredicateFailureReason, error) {
 | 
				
			||||||
	if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		return true, nil, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	node := nodeInfo.Node()
 | 
						node := nodeInfo.Node()
 | 
				
			||||||
	if node == nil {
 | 
						if node == nil {
 | 
				
			||||||
		return false, nil, fmt.Errorf("node not found")
 | 
							return false, nil, fmt.Errorf("node not found")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,10 +29,7 @@ import (
 | 
				
			|||||||
	"k8s.io/apimachinery/pkg/api/resource"
 | 
						"k8s.io/apimachinery/pkg/api/resource"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
 | 
						v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
						kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
				
			||||||
	schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
 | 
						schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
 | 
				
			||||||
	schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
 | 
						schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
 | 
				
			||||||
@@ -4884,8 +4881,6 @@ func TestVolumeZonePredicateWithVolumeBinding(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, test := range tests {
 | 
						for _, test := range tests {
 | 
				
			||||||
		t.Run(test.name, func(t *testing.T) {
 | 
							t.Run(test.name, func(t *testing.T) {
 | 
				
			||||||
			fit := NewVolumeZonePredicate(pvInfo, pvcInfo, classInfo)
 | 
								fit := NewVolumeZonePredicate(pvInfo, pvcInfo, classInfo)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,6 @@ go_library(
 | 
				
			|||||||
    visibility = ["//visibility:public"],
 | 
					    visibility = ["//visibility:public"],
 | 
				
			||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/api/v1/pod:go_default_library",
 | 
					        "//pkg/api/v1/pod:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/apis:go_default_library",
 | 
					        "//pkg/kubelet/apis:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/algorithm:go_default_library",
 | 
					        "//pkg/scheduler/algorithm:go_default_library",
 | 
				
			||||||
        "//pkg/scheduler/algorithm/predicates:go_default_library",
 | 
					        "//pkg/scheduler/algorithm/predicates:go_default_library",
 | 
				
			||||||
@@ -38,7 +37,6 @@ go_library(
 | 
				
			|||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/apps/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers/apps/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/informers/policy/v1beta1:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/informers/policy/v1beta1:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,7 +38,6 @@ import (
 | 
				
			|||||||
	"k8s.io/apimachinery/pkg/util/runtime"
 | 
						"k8s.io/apimachinery/pkg/util/runtime"
 | 
				
			||||||
	"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"
 | 
					 | 
				
			||||||
	appsinformers "k8s.io/client-go/informers/apps/v1"
 | 
						appsinformers "k8s.io/client-go/informers/apps/v1"
 | 
				
			||||||
	coreinformers "k8s.io/client-go/informers/core/v1"
 | 
						coreinformers "k8s.io/client-go/informers/core/v1"
 | 
				
			||||||
	policyinformers "k8s.io/client-go/informers/policy/v1beta1"
 | 
						policyinformers "k8s.io/client-go/informers/policy/v1beta1"
 | 
				
			||||||
@@ -51,7 +50,6 @@ import (
 | 
				
			|||||||
	"k8s.io/client-go/tools/cache"
 | 
						"k8s.io/client-go/tools/cache"
 | 
				
			||||||
	"k8s.io/client-go/tools/record"
 | 
						"k8s.io/client-go/tools/record"
 | 
				
			||||||
	podutil "k8s.io/kubernetes/pkg/api/v1/pod"
 | 
						podutil "k8s.io/kubernetes/pkg/api/v1/pod"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
						kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/algorithm"
 | 
						"k8s.io/kubernetes/pkg/scheduler/algorithm"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
 | 
						"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
 | 
				
			||||||
@@ -378,7 +376,6 @@ func NewConfigFactory(args *ConfigFactoryArgs) Configurator {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
	// Setup volume binder
 | 
						// Setup volume binder
 | 
				
			||||||
	c.volumeBinder = volumebinder.NewVolumeBinder(args.Client, args.PvcInformer, args.PvInformer, args.StorageClassInformer, time.Duration(args.BindTimeoutSeconds)*time.Second)
 | 
						c.volumeBinder = volumebinder.NewVolumeBinder(args.Client, args.PvcInformer, args.PvInformer, args.StorageClassInformer, time.Duration(args.BindTimeoutSeconds)*time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -387,7 +384,6 @@ func NewConfigFactory(args *ConfigFactoryArgs) Configurator {
 | 
				
			|||||||
			AddFunc: c.onStorageClassAdd,
 | 
								AddFunc: c.onStorageClassAdd,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Setup cache comparer
 | 
						// Setup cache comparer
 | 
				
			||||||
	debugger := cachedebugger.New(
 | 
						debugger := cachedebugger.New(
 | 
				
			||||||
@@ -491,9 +487,6 @@ func (c *configFactory) onPvcAdd(obj interface{}) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *configFactory) onPvcUpdate(old, new interface{}) {
 | 
					func (c *configFactory) onPvcUpdate(old, new interface{}) {
 | 
				
			||||||
	if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c.podQueue.MoveAllToActiveQueue()
 | 
						c.podQueue.MoveAllToActiveQueue()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,14 +29,12 @@ import (
 | 
				
			|||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	appsinformers "k8s.io/client-go/informers/apps/v1"
 | 
						appsinformers "k8s.io/client-go/informers/apps/v1"
 | 
				
			||||||
	coreinformers "k8s.io/client-go/informers/core/v1"
 | 
						coreinformers "k8s.io/client-go/informers/core/v1"
 | 
				
			||||||
	policyinformers "k8s.io/client-go/informers/policy/v1beta1"
 | 
						policyinformers "k8s.io/client-go/informers/policy/v1beta1"
 | 
				
			||||||
	storageinformers "k8s.io/client-go/informers/storage/v1"
 | 
						storageinformers "k8s.io/client-go/informers/storage/v1"
 | 
				
			||||||
	clientset "k8s.io/client-go/kubernetes"
 | 
						clientset "k8s.io/client-go/kubernetes"
 | 
				
			||||||
	"k8s.io/client-go/tools/record"
 | 
						"k8s.io/client-go/tools/record"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
 | 
						schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
 | 
				
			||||||
	latestschedulerapi "k8s.io/kubernetes/pkg/scheduler/api/latest"
 | 
						latestschedulerapi "k8s.io/kubernetes/pkg/scheduler/api/latest"
 | 
				
			||||||
	kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
 | 
						kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
 | 
				
			||||||
@@ -352,13 +350,11 @@ func (sched *Scheduler) preempt(preemptor *v1.Pod, scheduleErr error) (string, e
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// This function modifies assumed if volume binding is required.
 | 
					// This function modifies assumed if volume binding is required.
 | 
				
			||||||
func (sched *Scheduler) assumeVolumes(assumed *v1.Pod, host string) (allBound bool, err error) {
 | 
					func (sched *Scheduler) assumeVolumes(assumed *v1.Pod, host string) (allBound bool, err error) {
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
	allBound, err = sched.config.VolumeBinder.Binder.AssumePodVolumes(assumed, host)
 | 
						allBound, err = sched.config.VolumeBinder.Binder.AssumePodVolumes(assumed, host)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		sched.recordSchedulingFailure(assumed, err, SchedulerError,
 | 
							sched.recordSchedulingFailure(assumed, err, SchedulerError,
 | 
				
			||||||
			fmt.Sprintf("AssumePodVolumes failed: %v", err))
 | 
								fmt.Sprintf("AssumePodVolumes failed: %v", err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,8 +32,6 @@ import (
 | 
				
			|||||||
	"k8s.io/apimachinery/pkg/util/diff"
 | 
						"k8s.io/apimachinery/pkg/util/diff"
 | 
				
			||||||
	"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"
 | 
					 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	"k8s.io/client-go/informers"
 | 
						"k8s.io/client-go/informers"
 | 
				
			||||||
	clientsetfake "k8s.io/client-go/kubernetes/fake"
 | 
						clientsetfake "k8s.io/client-go/kubernetes/fake"
 | 
				
			||||||
	corelister "k8s.io/client-go/listers/core/v1"
 | 
						corelister "k8s.io/client-go/listers/core/v1"
 | 
				
			||||||
@@ -41,7 +39,6 @@ import (
 | 
				
			|||||||
	"k8s.io/client-go/tools/record"
 | 
						"k8s.io/client-go/tools/record"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
						"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
 | 
						"k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/algorithm"
 | 
						"k8s.io/kubernetes/pkg/scheduler/algorithm"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
 | 
						"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/api"
 | 
						"k8s.io/kubernetes/pkg/scheduler/api"
 | 
				
			||||||
@@ -779,8 +776,6 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
 | 
				
			|||||||
	// This can be small because we wait for pod to finish scheduling first
 | 
						// This can be small because we wait for pod to finish scheduling first
 | 
				
			||||||
	chanTimeout := 2 * time.Second
 | 
						chanTimeout := 2 * time.Second
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	table := []struct {
 | 
						table := []struct {
 | 
				
			||||||
		name               string
 | 
							name               string
 | 
				
			||||||
		expectError        error
 | 
							expectError        error
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -576,12 +576,10 @@ func (c *awsElasticBlockStoreProvisioner) Provision(selectedNode *v1.Node, allow
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
	pv.Spec.NodeAffinity = new(v1.VolumeNodeAffinity)
 | 
						pv.Spec.NodeAffinity = new(v1.VolumeNodeAffinity)
 | 
				
			||||||
	pv.Spec.NodeAffinity.Required = new(v1.NodeSelector)
 | 
						pv.Spec.NodeAffinity.Required = new(v1.NodeSelector)
 | 
				
			||||||
	pv.Spec.NodeAffinity.Required.NodeSelectorTerms = make([]v1.NodeSelectorTerm, 1)
 | 
						pv.Spec.NodeAffinity.Required.NodeSelectorTerms = make([]v1.NodeSelectorTerm, 1)
 | 
				
			||||||
	pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions = requirements
 | 
						pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions = requirements
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pv, nil
 | 
						return pv, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -311,7 +311,6 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
	nodeSelectorTerms := make([]v1.NodeSelectorTerm, 0)
 | 
						nodeSelectorTerms := make([]v1.NodeSelectorTerm, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if zoned {
 | 
						if zoned {
 | 
				
			||||||
@@ -357,7 +356,6 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pv, nil
 | 
						return pv, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -561,7 +561,6 @@ func (c *cinderVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopolo
 | 
				
			|||||||
		pv.Spec.AccessModes = c.plugin.GetAccessModes()
 | 
							pv.Spec.AccessModes = c.plugin.GetAccessModes()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
	requirements := make([]v1.NodeSelectorRequirement, 0)
 | 
						requirements := make([]v1.NodeSelectorRequirement, 0)
 | 
				
			||||||
	for k, v := range labels {
 | 
						for k, v := range labels {
 | 
				
			||||||
		if v != "" {
 | 
							if v != "" {
 | 
				
			||||||
@@ -574,7 +573,6 @@ func (c *cinderVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopolo
 | 
				
			|||||||
		pv.Spec.NodeAffinity.Required.NodeSelectorTerms = make([]v1.NodeSelectorTerm, 1)
 | 
							pv.Spec.NodeAffinity.Required.NodeSelectorTerms = make([]v1.NodeSelectorTerm, 1)
 | 
				
			||||||
		pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions = requirements
 | 
							pv.Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions = requirements
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pv, nil
 | 
						return pv, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -551,7 +551,7 @@ func (c *gcePersistentDiskProvisioner) Provision(selectedNode *v1.Node, allowedT
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) && len(requirements) > 0 {
 | 
						if len(requirements) > 0 {
 | 
				
			||||||
		pv.Spec.NodeAffinity = new(v1.VolumeNodeAffinity)
 | 
							pv.Spec.NodeAffinity = new(v1.VolumeNodeAffinity)
 | 
				
			||||||
		pv.Spec.NodeAffinity.Required = new(v1.NodeSelector)
 | 
							pv.Spec.NodeAffinity.Required = new(v1.NodeSelector)
 | 
				
			||||||
		pv.Spec.NodeAffinity.Required.NodeSelectorTerms = make([]v1.NodeSelectorTerm, 1)
 | 
							pv.Spec.NodeAffinity.Required.NodeSelectorTerms = make([]v1.NodeSelectorTerm, 1)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,7 +60,6 @@ go_test(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/apis/core/install:go_default_library",
 | 
					        "//pkg/apis/core/install:go_default_library",
 | 
				
			||||||
        "//pkg/apis/core/v1/helper:go_default_library",
 | 
					        "//pkg/apis/core/v1/helper:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/apis:go_default_library",
 | 
					        "//pkg/kubelet/apis:go_default_library",
 | 
				
			||||||
        "//pkg/util/mount:go_default_library",
 | 
					        "//pkg/util/mount:go_default_library",
 | 
				
			||||||
        "//pkg/util/slice:go_default_library",
 | 
					        "//pkg/util/slice:go_default_library",
 | 
				
			||||||
@@ -70,8 +69,6 @@ go_test(
 | 
				
			|||||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/client-go/util/testing:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/util/testing:go_default_library",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
						"k8s.io/api/core/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	utiltesting "k8s.io/client-go/util/testing"
 | 
						utiltesting "k8s.io/client-go/util/testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// util.go uses api.Codecs.LegacyCodec so import this package to do some
 | 
						// util.go uses api.Codecs.LegacyCodec so import this package to do some
 | 
				
			||||||
@@ -32,7 +31,6 @@ import (
 | 
				
			|||||||
	"hash/fnv"
 | 
						"hash/fnv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_ "k8s.io/kubernetes/pkg/apis/core/install"
 | 
						_ "k8s.io/kubernetes/pkg/apis/core/install"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/mount"
 | 
						"k8s.io/kubernetes/pkg/util/mount"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
@@ -40,7 +38,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/api/resource"
 | 
						"k8s.io/apimachinery/pkg/api/resource"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
						kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/slice"
 | 
						"k8s.io/kubernetes/pkg/util/slice"
 | 
				
			||||||
@@ -1065,7 +1062,6 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		ZonesWithNodes    string
 | 
							ZonesWithNodes    string
 | 
				
			||||||
		Node              *v1.Node
 | 
							Node              *v1.Node
 | 
				
			||||||
		AllowedTopologies []v1.TopologySelectorTerm
 | 
							AllowedTopologies []v1.TopologySelectorTerm
 | 
				
			||||||
		VolumeScheduling  bool
 | 
					 | 
				
			||||||
		// Expectations around returned zone from SelectZoneForVolume
 | 
							// Expectations around returned zone from SelectZoneForVolume
 | 
				
			||||||
		Reject             bool   // expect error due to validation failing
 | 
							Reject             bool   // expect error due to validation failing
 | 
				
			||||||
		ExpectSpecificZone bool   // expect returned zone to specifically match a single zone (rather than one from a set)
 | 
							ExpectSpecificZone bool   // expect returned zone to specifically match a single zone (rather than one from a set)
 | 
				
			||||||
@@ -1078,7 +1074,6 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] Node irrelevant
 | 
							// [1] Node irrelevant
 | 
				
			||||||
		// [2] Zone and Zones parameters presents
 | 
							// [2] Zone and Zones parameters presents
 | 
				
			||||||
		// [3] AllowedTopologies irrelevant
 | 
							// [3] AllowedTopologies irrelevant
 | 
				
			||||||
		// [4] VolumeScheduling irrelevant
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:         "Nil_Node_with_Zone_Zones_parameters_present",
 | 
								Name:         "Nil_Node_with_Zone_Zones_parameters_present",
 | 
				
			||||||
			ZonePresent:  true,
 | 
								ZonePresent:  true,
 | 
				
			||||||
@@ -1092,11 +1087,9 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] Node with no zone labels
 | 
							// [1] Node with no zone labels
 | 
				
			||||||
		// [2] Zone/Zones parameter irrelevant
 | 
							// [2] Zone/Zones parameter irrelevant
 | 
				
			||||||
		// [3] AllowedTopologies irrelevant
 | 
							// [3] AllowedTopologies irrelevant
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:   "Node_with_no_Zone_labels",
 | 
								Name:   "Node_with_no_Zone_labels",
 | 
				
			||||||
			Node:   nodeWithNoLabels,
 | 
								Node:   nodeWithNoLabels,
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			Reject: true,
 | 
								Reject: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1104,13 +1097,11 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] Node with zone labels
 | 
							// [1] Node with zone labels
 | 
				
			||||||
		// [2] Zone parameter specified
 | 
							// [2] Zone parameter specified
 | 
				
			||||||
		// [3] AllowedTopologies irrelevant
 | 
							// [3] AllowedTopologies irrelevant
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:        "Node_with_Zone_labels_and_Zone_parameter_present",
 | 
								Name:        "Node_with_Zone_labels_and_Zone_parameter_present",
 | 
				
			||||||
			Node:        nodeWithZoneLabels,
 | 
								Node:        nodeWithZoneLabels,
 | 
				
			||||||
			ZonePresent: true,
 | 
								ZonePresent: true,
 | 
				
			||||||
			Zone:        "zoneX",
 | 
								Zone:        "zoneX",
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			Reject:      true,
 | 
								Reject:      true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1118,13 +1109,11 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] Node with zone labels
 | 
							// [1] Node with zone labels
 | 
				
			||||||
		// [2] Zones parameter specified
 | 
							// [2] Zones parameter specified
 | 
				
			||||||
		// [3] AllowedTopologies irrelevant
 | 
							// [3] AllowedTopologies irrelevant
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:         "Node_with_Zone_labels_and_Zones_parameter_present",
 | 
								Name:         "Node_with_Zone_labels_and_Zones_parameter_present",
 | 
				
			||||||
			Node:         nodeWithZoneLabels,
 | 
								Node:         nodeWithZoneLabels,
 | 
				
			||||||
			ZonesPresent: true,
 | 
								ZonesPresent: true,
 | 
				
			||||||
			Zones:        "zoneX,zoneY",
 | 
								Zones:        "zoneX,zoneY",
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			Reject:       true,
 | 
								Reject:       true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1132,13 +1121,11 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] Zone parameter specified
 | 
							// [2] Zone parameter specified
 | 
				
			||||||
		// [3] AllowedTopologies specified
 | 
							// [3] AllowedTopologies specified
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:        "Nil_Node_and_Zone_parameter_and_Allowed_Topology_term",
 | 
								Name:        "Nil_Node_and_Zone_parameter_and_Allowed_Topology_term",
 | 
				
			||||||
			Node:        nil,
 | 
								Node:        nil,
 | 
				
			||||||
			ZonePresent: true,
 | 
								ZonePresent: true,
 | 
				
			||||||
			Zone:        "zoneX",
 | 
								Zone:        "zoneX",
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			AllowedTopologies: []v1.TopologySelectorTerm{
 | 
								AllowedTopologies: []v1.TopologySelectorTerm{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
										MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
				
			||||||
@@ -1156,13 +1143,11 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] Zones parameter specified
 | 
							// [2] Zones parameter specified
 | 
				
			||||||
		// [3] AllowedTopologies specified
 | 
							// [3] AllowedTopologies specified
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:         "Nil_Node_and_Zones_parameter_and_Allowed_Topology_term",
 | 
								Name:         "Nil_Node_and_Zones_parameter_and_Allowed_Topology_term",
 | 
				
			||||||
			Node:         nil,
 | 
								Node:         nil,
 | 
				
			||||||
			ZonesPresent: true,
 | 
								ZonesPresent: true,
 | 
				
			||||||
			Zones:        "zoneX,zoneY",
 | 
								Zones:        "zoneX,zoneY",
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			AllowedTopologies: []v1.TopologySelectorTerm{
 | 
								AllowedTopologies: []v1.TopologySelectorTerm{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
										MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
				
			||||||
@@ -1180,11 +1165,9 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] no Zone/Zones parameter
 | 
							// [2] no Zone/Zones parameter
 | 
				
			||||||
		// [3] AllowedTopologies with invalid key specified
 | 
							// [3] AllowedTopologies with invalid key specified
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name: "Nil_Node_and_Invalid_Allowed_Topology_Key",
 | 
								Name: "Nil_Node_and_Invalid_Allowed_Topology_Key",
 | 
				
			||||||
			Node: nil,
 | 
								Node: nil,
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			AllowedTopologies: []v1.TopologySelectorTerm{
 | 
								AllowedTopologies: []v1.TopologySelectorTerm{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
										MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
				
			||||||
@@ -1206,11 +1189,9 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] no Zone/Zones parameter
 | 
							// [2] no Zone/Zones parameter
 | 
				
			||||||
		// [3] Invalid AllowedTopologies
 | 
							// [3] Invalid AllowedTopologies
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name: "Nil_Node_and_Invalid_AllowedTopologies",
 | 
								Name: "Nil_Node_and_Invalid_AllowedTopologies",
 | 
				
			||||||
			Node: nil,
 | 
								Node: nil,
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			AllowedTopologies: []v1.TopologySelectorTerm{
 | 
								AllowedTopologies: []v1.TopologySelectorTerm{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{},
 | 
										MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{},
 | 
				
			||||||
@@ -1219,62 +1200,16 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
			Reject: true,
 | 
								Reject: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// POSITIVE TESTS WITH VolumeScheduling DISABLED
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Select zone from active zones [Pass]
 | 
					 | 
				
			||||||
		// [1] nil Node (Node irrelevant)
 | 
					 | 
				
			||||||
		// [2] no Zone parameter
 | 
					 | 
				
			||||||
		// [3] no AllowedTopologies
 | 
					 | 
				
			||||||
		// [4] VolumeScheduling disabled
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Name:             "No_Zone_Zones_parameter_and_VolumeScheduling_disabled",
 | 
					 | 
				
			||||||
			ZonesWithNodes:   "zoneX,zoneY",
 | 
					 | 
				
			||||||
			VolumeScheduling: false,
 | 
					 | 
				
			||||||
			Reject:           false,
 | 
					 | 
				
			||||||
			ExpectedZones:    "zoneX,zoneY",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Select zone from single zone parameter [Pass]
 | 
					 | 
				
			||||||
		// [1] nil Node (Node irrelevant)
 | 
					 | 
				
			||||||
		// [2] Zone parameter specified
 | 
					 | 
				
			||||||
		// [3] no AllowedTopologies
 | 
					 | 
				
			||||||
		// [4] VolumeScheduling disabled
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Name:               "Zone_parameter_present_and_VolumeScheduling_disabled",
 | 
					 | 
				
			||||||
			ZonePresent:        true,
 | 
					 | 
				
			||||||
			Zone:               "zoneX",
 | 
					 | 
				
			||||||
			VolumeScheduling:   false,
 | 
					 | 
				
			||||||
			Reject:             false,
 | 
					 | 
				
			||||||
			ExpectSpecificZone: true,
 | 
					 | 
				
			||||||
			ExpectedZone:       "zoneX",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Select zone from zones parameter [Pass]
 | 
					 | 
				
			||||||
		// [1] nil Node (Node irrelevant)
 | 
					 | 
				
			||||||
		// [2] Zones parameter specified
 | 
					 | 
				
			||||||
		// [3] no AllowedTopologies
 | 
					 | 
				
			||||||
		// [4] VolumeScheduling disabled
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Name:             "Zones_parameter_present_and_VolumeScheduling_disabled",
 | 
					 | 
				
			||||||
			ZonesPresent:     true,
 | 
					 | 
				
			||||||
			Zones:            "zoneX,zoneY",
 | 
					 | 
				
			||||||
			VolumeScheduling: false,
 | 
					 | 
				
			||||||
			Reject:           false,
 | 
					 | 
				
			||||||
			ExpectedZones:    "zoneX,zoneY",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// POSITIVE TESTS WITH VolumeScheduling ENABLED
 | 
							// POSITIVE TESTS WITH VolumeScheduling ENABLED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Select zone from active zones [Pass]
 | 
							// Select zone from active zones [Pass]
 | 
				
			||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] no Zone parameter specified
 | 
							// [2] no Zone parameter specified
 | 
				
			||||||
		// [3] no AllowedTopologies
 | 
							// [3] no AllowedTopologies
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:           "Nil_Node_and_No_Zone_Zones_parameter_and_no_Allowed_topologies_and_VolumeScheduling_enabled",
 | 
								Name:           "Nil_Node_and_No_Zone_Zones_parameter_and_no_Allowed_topologies_and_VolumeScheduling_enabled",
 | 
				
			||||||
			Node:           nil,
 | 
								Node:           nil,
 | 
				
			||||||
			ZonesWithNodes: "zoneX,zoneY",
 | 
								ZonesWithNodes: "zoneX,zoneY",
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			Reject:         false,
 | 
								Reject:         false,
 | 
				
			||||||
			ExpectedZones:  "zoneX,zoneY",
 | 
								ExpectedZones:  "zoneX,zoneY",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -1283,13 +1218,11 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] Zone parameter specified
 | 
							// [2] Zone parameter specified
 | 
				
			||||||
		// [3] no AllowedTopology specified
 | 
							// [3] no AllowedTopology specified
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:               "Nil_Node_and_Zone_parameter_present_and_VolumeScheduling_enabled",
 | 
								Name:               "Nil_Node_and_Zone_parameter_present_and_VolumeScheduling_enabled",
 | 
				
			||||||
			ZonePresent:        true,
 | 
								ZonePresent:        true,
 | 
				
			||||||
			Zone:               "zoneX",
 | 
								Zone:               "zoneX",
 | 
				
			||||||
			Node:               nil,
 | 
								Node:               nil,
 | 
				
			||||||
			VolumeScheduling:   true,
 | 
					 | 
				
			||||||
			Reject:             false,
 | 
								Reject:             false,
 | 
				
			||||||
			ExpectSpecificZone: true,
 | 
								ExpectSpecificZone: true,
 | 
				
			||||||
			ExpectedZone:       "zoneX",
 | 
								ExpectedZone:       "zoneX",
 | 
				
			||||||
@@ -1299,13 +1232,11 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] Zones parameter specified
 | 
							// [2] Zones parameter specified
 | 
				
			||||||
		// [3] no AllowedTopology
 | 
							// [3] no AllowedTopology
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:          "Nil_Node_and_Zones_parameter_present_and_VolumeScheduling_enabled",
 | 
								Name:          "Nil_Node_and_Zones_parameter_present_and_VolumeScheduling_enabled",
 | 
				
			||||||
			ZonesPresent:  true,
 | 
								ZonesPresent:  true,
 | 
				
			||||||
			Zones:         "zoneX,zoneY",
 | 
								Zones:         "zoneX,zoneY",
 | 
				
			||||||
			Node:          nil,
 | 
								Node:          nil,
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			Reject:        false,
 | 
								Reject:        false,
 | 
				
			||||||
			ExpectedZones: "zoneX,zoneY",
 | 
								ExpectedZones: "zoneX,zoneY",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -1314,11 +1245,9 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] Node with zone labels
 | 
							// [1] Node with zone labels
 | 
				
			||||||
		// [2] no zone/zones parameters
 | 
							// [2] no zone/zones parameters
 | 
				
			||||||
		// [3] no AllowedTopology
 | 
							// [3] no AllowedTopology
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:               "Node_with_Zone_labels_and_VolumeScheduling_enabled",
 | 
								Name:               "Node_with_Zone_labels_and_VolumeScheduling_enabled",
 | 
				
			||||||
			Node:               nodeWithZoneLabels,
 | 
								Node:               nodeWithZoneLabels,
 | 
				
			||||||
			VolumeScheduling:   true,
 | 
					 | 
				
			||||||
			Reject:             false,
 | 
								Reject:             false,
 | 
				
			||||||
			ExpectSpecificZone: true,
 | 
								ExpectSpecificZone: true,
 | 
				
			||||||
			ExpectedZone:       "zoneX",
 | 
								ExpectedZone:       "zoneX",
 | 
				
			||||||
@@ -1328,11 +1257,9 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] Node with zone labels
 | 
							// [1] Node with zone labels
 | 
				
			||||||
		// [2] no Zone/Zones parameters
 | 
							// [2] no Zone/Zones parameters
 | 
				
			||||||
		// [3] AllowedTopology with single term with multiple values specified (ignored)
 | 
							// [3] AllowedTopology with single term with multiple values specified (ignored)
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name: "Node_with_Zone_labels_and_Multiple_Allowed_Topology_values_and_VolumeScheduling_enabled",
 | 
								Name: "Node_with_Zone_labels_and_Multiple_Allowed_Topology_values_and_VolumeScheduling_enabled",
 | 
				
			||||||
			Node: nodeWithZoneLabels,
 | 
								Node: nodeWithZoneLabels,
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			AllowedTopologies: []v1.TopologySelectorTerm{
 | 
								AllowedTopologies: []v1.TopologySelectorTerm{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
										MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
				
			||||||
@@ -1352,11 +1279,9 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] no Zone/Zones parametes specified
 | 
							// [2] no Zone/Zones parametes specified
 | 
				
			||||||
		// [3] AllowedTopologies with single term with multiple values specified
 | 
							// [3] AllowedTopologies with single term with multiple values specified
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name: "Nil_Node_with_Multiple_Allowed_Topology_values_and_VolumeScheduling_enabled",
 | 
								Name: "Nil_Node_with_Multiple_Allowed_Topology_values_and_VolumeScheduling_enabled",
 | 
				
			||||||
			Node: nil,
 | 
								Node: nil,
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			AllowedTopologies: []v1.TopologySelectorTerm{
 | 
								AllowedTopologies: []v1.TopologySelectorTerm{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
										MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
				
			||||||
@@ -1375,11 +1300,9 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] no Zone/Zones parametes specified
 | 
							// [2] no Zone/Zones parametes specified
 | 
				
			||||||
		// [3] AllowedTopologies with multiple terms specified
 | 
							// [3] AllowedTopologies with multiple terms specified
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name: "Nil_Node_and_Multiple_Allowed_Topology_terms_and_VolumeScheduling_enabled",
 | 
								Name: "Nil_Node_and_Multiple_Allowed_Topology_terms_and_VolumeScheduling_enabled",
 | 
				
			||||||
			Node: nil,
 | 
								Node: nil,
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			AllowedTopologies: []v1.TopologySelectorTerm{
 | 
								AllowedTopologies: []v1.TopologySelectorTerm{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
										MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
				
			||||||
@@ -1407,11 +1330,9 @@ func TestSelectZoneForVolume(t *testing.T) {
 | 
				
			|||||||
		// [1] nil Node
 | 
							// [1] nil Node
 | 
				
			||||||
		// [2] no Zone/Zones parametes specified
 | 
							// [2] no Zone/Zones parametes specified
 | 
				
			||||||
		// [3] AllowedTopologies with single term and value specified
 | 
							// [3] AllowedTopologies with single term and value specified
 | 
				
			||||||
		// [4] VolumeScheduling enabled
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name: "Nil_Node_and_Single_Allowed_Topology_term_value_and_VolumeScheduling_enabled",
 | 
								Name: "Nil_Node_and_Single_Allowed_Topology_term_value_and_VolumeScheduling_enabled",
 | 
				
			||||||
			Node: nil,
 | 
								Node: nil,
 | 
				
			||||||
			VolumeScheduling: true,
 | 
					 | 
				
			||||||
			AllowedTopologies: []v1.TopologySelectorTerm{
 | 
								AllowedTopologies: []v1.TopologySelectorTerm{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
										MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
 | 
				
			||||||
@@ -1430,8 +1351,6 @@ func TestSelectZoneForVolume(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 utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, test.VolumeScheduling)()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var zonesParameter, zonesWithNodes sets.String
 | 
								var zonesParameter, zonesWithNodes sets.String
 | 
				
			||||||
			var err error
 | 
								var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,13 +18,11 @@ go_library(
 | 
				
			|||||||
        "//pkg/cloudprovider/providers/aws:go_default_library",
 | 
					        "//pkg/cloudprovider/providers/aws:go_default_library",
 | 
				
			||||||
        "//pkg/cloudprovider/providers/azure:go_default_library",
 | 
					        "//pkg/cloudprovider/providers/azure:go_default_library",
 | 
				
			||||||
        "//pkg/cloudprovider/providers/gce:go_default_library",
 | 
					        "//pkg/cloudprovider/providers/gce:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubeapiserver/admission:go_default_library",
 | 
					        "//pkg/kubeapiserver/admission:go_default_library",
 | 
				
			||||||
        "//pkg/kubelet/apis:go_default_library",
 | 
					        "//pkg/kubelet/apis:go_default_library",
 | 
				
			||||||
        "//pkg/volume:go_default_library",
 | 
					        "//pkg/volume:go_default_library",
 | 
				
			||||||
        "//pkg/volume/util:go_default_library",
 | 
					        "//pkg/volume/util:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/cloud-provider:go_default_library",
 | 
					        "//staging/src/k8s.io/cloud-provider:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/klog:go_default_library",
 | 
					        "//vendor/k8s.io/klog:go_default_library",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
@@ -37,15 +35,12 @@ go_test(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//pkg/apis/core:go_default_library",
 | 
					        "//pkg/apis/core:go_default_library",
 | 
				
			||||||
        "//pkg/cloudprovider/providers/aws:go_default_library",
 | 
					        "//pkg/cloudprovider/providers/aws:go_default_library",
 | 
				
			||||||
        "//pkg/features:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/apis:go_default_library",
 | 
					        "//pkg/kubelet/apis:go_default_library",
 | 
				
			||||||
        "//pkg/volume/util:go_default_library",
 | 
					        "//pkg/volume/util:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,14 +23,12 @@ import (
 | 
				
			|||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/apiserver/pkg/admission"
 | 
						"k8s.io/apiserver/pkg/admission"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	cloudprovider "k8s.io/cloud-provider"
 | 
						cloudprovider "k8s.io/cloud-provider"
 | 
				
			||||||
	"k8s.io/klog"
 | 
						"k8s.io/klog"
 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						api "k8s.io/kubernetes/pkg/apis/core"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
 | 
						"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/cloudprovider/providers/azure"
 | 
						"k8s.io/kubernetes/pkg/cloudprovider/providers/azure"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
 | 
						"k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
 | 
						kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
 | 
				
			||||||
	kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
						kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
				
			||||||
	vol "k8s.io/kubernetes/pkg/volume"
 | 
						vol "k8s.io/kubernetes/pkg/volume"
 | 
				
			||||||
@@ -158,7 +156,6 @@ func (l *persistentVolumeLabel) Admit(a admission.Attributes) (err error) {
 | 
				
			|||||||
			requirements = append(requirements, api.NodeSelectorRequirement{Key: k, Operator: api.NodeSelectorOpIn, Values: values})
 | 
								requirements = append(requirements, api.NodeSelectorRequirement{Key: k, Operator: api.NodeSelectorOpIn, Values: values})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		if volume.Spec.NodeAffinity == nil {
 | 
							if volume.Spec.NodeAffinity == nil {
 | 
				
			||||||
			volume.Spec.NodeAffinity = new(api.VolumeNodeAffinity)
 | 
								volume.Spec.NodeAffinity = new(api.VolumeNodeAffinity)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -180,7 +177,6 @@ func (l *persistentVolumeLabel) Admit(a admission.Attributes) (err error) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,11 +27,8 @@ import (
 | 
				
			|||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/types"
 | 
						"k8s.io/apimachinery/pkg/types"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/admission"
 | 
						"k8s.io/apiserver/pkg/admission"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
 | 
					 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						api "k8s.io/kubernetes/pkg/apis/core"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
 | 
						"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
						kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
 | 
				
			||||||
	volumeutil "k8s.io/kubernetes/pkg/volume/util"
 | 
						volumeutil "k8s.io/kubernetes/pkg/volume/util"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -125,8 +122,6 @@ func TestAdmission(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Non-cloud PVs are ignored
 | 
						// Non-cloud PVs are ignored
 | 
				
			||||||
	err := handler.Admit(admission.NewAttributesRecord(&ignoredPV, nil, api.Kind("PersistentVolume").WithVersion("version"), ignoredPV.Namespace, ignoredPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
 | 
						err := handler.Admit(admission.NewAttributesRecord(&ignoredPV, nil, api.Kind("PersistentVolume").WithVersion("version"), ignoredPV.Namespace, ignoredPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -489,17 +489,14 @@ func ClusterRoles() []rbacv1.ClusterRole {
 | 
				
			|||||||
				rbacv1helpers.NewRule("create").Groups(certificatesGroup).Resources("certificatesigningrequests/selfnodeclient").RuleOrDie(),
 | 
									rbacv1helpers.NewRule("create").Groups(certificatesGroup).Resources("certificatesigningrequests/selfnodeclient").RuleOrDie(),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
							{
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		roles = append(roles, rbacv1.ClusterRole{
 | 
					 | 
				
			||||||
			ObjectMeta: metav1.ObjectMeta{Name: "system:volume-scheduler"},
 | 
								ObjectMeta: metav1.ObjectMeta{Name: "system:volume-scheduler"},
 | 
				
			||||||
			Rules: []rbacv1.PolicyRule{
 | 
								Rules: []rbacv1.PolicyRule{
 | 
				
			||||||
				rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
 | 
									rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
 | 
				
			||||||
				rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
 | 
									rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
 | 
				
			||||||
				rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
 | 
									rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		})
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	externalProvisionerRules := []rbacv1.PolicyRule{
 | 
						externalProvisionerRules := []rbacv1.PolicyRule{
 | 
				
			||||||
@@ -535,6 +532,7 @@ func ClusterRoleBindings() []rbacv1.ClusterRoleBinding {
 | 
				
			|||||||
		rbacv1helpers.NewClusterBinding("system:kube-dns").SAs("kube-system", "kube-dns").BindingOrDie(),
 | 
							rbacv1helpers.NewClusterBinding("system:kube-dns").SAs("kube-system", "kube-dns").BindingOrDie(),
 | 
				
			||||||
		rbacv1helpers.NewClusterBinding("system:kube-scheduler").Users(user.KubeScheduler).BindingOrDie(),
 | 
							rbacv1helpers.NewClusterBinding("system:kube-scheduler").Users(user.KubeScheduler).BindingOrDie(),
 | 
				
			||||||
		rbacv1helpers.NewClusterBinding("system:aws-cloud-provider").SAs("kube-system", "aws-cloud-provider").BindingOrDie(),
 | 
							rbacv1helpers.NewClusterBinding("system:aws-cloud-provider").SAs("kube-system", "aws-cloud-provider").BindingOrDie(),
 | 
				
			||||||
 | 
							rbacv1helpers.NewClusterBinding("system:volume-scheduler").Users(user.KubeScheduler).BindingOrDie(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// This default binding of the system:node role to the system:nodes group is deprecated in 1.7 with the availability of the Node authorizer.
 | 
							// This default binding of the system:node role to the system:nodes group is deprecated in 1.7 with the availability of the Node authorizer.
 | 
				
			||||||
		// This leaves the binding, but with an empty set of subjects, so that tightening reconciliation can remove the subject.
 | 
							// This leaves the binding, but with an empty set of subjects, so that tightening reconciliation can remove the subject.
 | 
				
			||||||
@@ -544,10 +542,6 @@ func ClusterRoleBindings() []rbacv1.ClusterRoleBinding {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
 | 
					 | 
				
			||||||
		rolebindings = append(rolebindings, rbacv1helpers.NewClusterBinding("system:volume-scheduler").Users(user.KubeScheduler).BindingOrDie())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	addClusterRoleBindingLabel(rolebindings)
 | 
						addClusterRoleBindingLabel(rolebindings)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rolebindings
 | 
						return rolebindings
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,7 +63,11 @@ var (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type FeatureSpec struct {
 | 
					type FeatureSpec struct {
 | 
				
			||||||
 | 
						// Default is the default enablement state for the feature
 | 
				
			||||||
	Default bool
 | 
						Default bool
 | 
				
			||||||
 | 
						// LockToDefault indicates that the feature is locked to its default and cannot be changed
 | 
				
			||||||
 | 
						LockToDefault bool
 | 
				
			||||||
 | 
						// PreRelease indicates the maturity level of the feature
 | 
				
			||||||
	PreRelease prerelease
 | 
						PreRelease prerelease
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -199,6 +203,9 @@ func (f *featureGate) SetFromMap(m map[string]bool) error {
 | 
				
			|||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			return fmt.Errorf("unrecognized feature gate: %s", k)
 | 
								return fmt.Errorf("unrecognized feature gate: %s", k)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if featureSpec.LockToDefault && featureSpec.Default != v {
 | 
				
			||||||
 | 
								return fmt.Errorf("cannot set feature gate %v to %v, feature is locked to %v", k, v, featureSpec.Default)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		enabled[k] = v
 | 
							enabled[k] = v
 | 
				
			||||||
		// Handle "special" features like "all alpha gates"
 | 
							// Handle "special" features like "all alpha gates"
 | 
				
			||||||
		if fn, found := f.special[k]; found {
 | 
							if fn, found := f.special[k]; found {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -221,6 +221,8 @@ func TestFeatureGateSetFromMap(t *testing.T) {
 | 
				
			|||||||
	// gates for testing
 | 
						// gates for testing
 | 
				
			||||||
	const testAlphaGate Feature = "TestAlpha"
 | 
						const testAlphaGate Feature = "TestAlpha"
 | 
				
			||||||
	const testBetaGate Feature = "TestBeta"
 | 
						const testBetaGate Feature = "TestBeta"
 | 
				
			||||||
 | 
						const testLockedTrueGate Feature = "TestLockedTrue"
 | 
				
			||||||
 | 
						const testLockedFalseGate Feature = "TestLockedFalse"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		name        string
 | 
							name        string
 | 
				
			||||||
@@ -270,6 +272,39 @@ func TestFeatureGateSetFromMap(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			setmapError: "unrecognized feature gate:",
 | 
								setmapError: "unrecognized feature gate:",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "set locked gates",
 | 
				
			||||||
 | 
								setmap: map[string]bool{
 | 
				
			||||||
 | 
									"TestLockedTrue":  true,
 | 
				
			||||||
 | 
									"TestLockedFalse": false,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: map[Feature]bool{
 | 
				
			||||||
 | 
									testAlphaGate: false,
 | 
				
			||||||
 | 
									testBetaGate:  false,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "set locked gates",
 | 
				
			||||||
 | 
								setmap: map[string]bool{
 | 
				
			||||||
 | 
									"TestLockedTrue": false,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: map[Feature]bool{
 | 
				
			||||||
 | 
									testAlphaGate: false,
 | 
				
			||||||
 | 
									testBetaGate:  false,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								setmapError: "cannot set feature gate TestLockedTrue to false, feature is locked to true",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "set locked gates",
 | 
				
			||||||
 | 
								setmap: map[string]bool{
 | 
				
			||||||
 | 
									"TestLockedFalse": true,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: map[Feature]bool{
 | 
				
			||||||
 | 
									testAlphaGate: false,
 | 
				
			||||||
 | 
									testBetaGate:  false,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								setmapError: "cannot set feature gate TestLockedFalse to true, feature is locked to false",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for i, test := range tests {
 | 
						for i, test := range tests {
 | 
				
			||||||
		t.Run(fmt.Sprintf("SetFromMap %s", test.name), func(t *testing.T) {
 | 
							t.Run(fmt.Sprintf("SetFromMap %s", test.name), func(t *testing.T) {
 | 
				
			||||||
@@ -277,10 +312,14 @@ func TestFeatureGateSetFromMap(t *testing.T) {
 | 
				
			|||||||
			f.Add(map[Feature]FeatureSpec{
 | 
								f.Add(map[Feature]FeatureSpec{
 | 
				
			||||||
				testAlphaGate:       {Default: false, PreRelease: Alpha},
 | 
									testAlphaGate:       {Default: false, PreRelease: Alpha},
 | 
				
			||||||
				testBetaGate:        {Default: false, PreRelease: Beta},
 | 
									testBetaGate:        {Default: false, PreRelease: Beta},
 | 
				
			||||||
 | 
									testLockedTrueGate:  {Default: true, PreRelease: GA, LockToDefault: true},
 | 
				
			||||||
 | 
									testLockedFalseGate: {Default: false, PreRelease: GA, LockToDefault: true},
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
			err := f.SetFromMap(test.setmap)
 | 
								err := f.SetFromMap(test.setmap)
 | 
				
			||||||
			if test.setmapError != "" {
 | 
								if test.setmapError != "" {
 | 
				
			||||||
				if !strings.Contains(err.Error(), test.setmapError) {
 | 
									if err == nil {
 | 
				
			||||||
 | 
										t.Errorf("expected error, got none")
 | 
				
			||||||
 | 
									} else if !strings.Contains(err.Error(), test.setmapError) {
 | 
				
			||||||
					t.Errorf("%d: SetFromMap(%#v) Expected err:%v, Got err:%v", i, test.setmap, test.setmapError, err)
 | 
										t.Errorf("%d: SetFromMap(%#v) Expected err:%v, Got err:%v", i, test.setmap, test.setmapError, err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else if err != nil {
 | 
								} else if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,7 +97,6 @@ type testPVC struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestVolumeBinding(t *testing.T) {
 | 
					func TestVolumeBinding(t *testing.T) {
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
						defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
				
			||||||
	config := setupCluster(t, "volume-scheduling-", 2, 0, 0)
 | 
						config := setupCluster(t, "volume-scheduling-", 2, 0, 0)
 | 
				
			||||||
	defer config.teardown()
 | 
						defer config.teardown()
 | 
				
			||||||
@@ -268,7 +267,6 @@ func TestVolumeBinding(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// TestVolumeBindingRescheduling tests scheduler will retry scheduling when needed.
 | 
					// TestVolumeBindingRescheduling tests scheduler will retry scheduling when needed.
 | 
				
			||||||
func TestVolumeBindingRescheduling(t *testing.T) {
 | 
					func TestVolumeBindingRescheduling(t *testing.T) {
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
						defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
				
			||||||
	config := setupCluster(t, "volume-scheduling-", 2, 0, 0)
 | 
						config := setupCluster(t, "volume-scheduling-", 2, 0, 0)
 | 
				
			||||||
	defer config.teardown()
 | 
						defer config.teardown()
 | 
				
			||||||
@@ -412,7 +410,6 @@ func TestVolumeBindingDynamicStressSlow(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func testVolumeBindingStress(t *testing.T, schedulerResyncPeriod time.Duration, dynamic bool, provisionDelaySeconds int) {
 | 
					func testVolumeBindingStress(t *testing.T, schedulerResyncPeriod time.Duration, dynamic bool, provisionDelaySeconds int) {
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
						defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
				
			||||||
	config := setupCluster(t, "volume-binding-stress-", 1, schedulerResyncPeriod, provisionDelaySeconds)
 | 
						config := setupCluster(t, "volume-binding-stress-", 1, schedulerResyncPeriod, provisionDelaySeconds)
 | 
				
			||||||
	defer config.teardown()
 | 
						defer config.teardown()
 | 
				
			||||||
@@ -502,7 +499,6 @@ func testVolumeBindingStress(t *testing.T, schedulerResyncPeriod time.Duration,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func testVolumeBindingWithAffinity(t *testing.T, anti bool, numNodes, numPods, numPVsFirstNode int) {
 | 
					func testVolumeBindingWithAffinity(t *testing.T, anti bool, numNodes, numPods, numPVsFirstNode int) {
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
						defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
				
			||||||
	config := setupCluster(t, "volume-pod-affinity-", numNodes, 0, 0)
 | 
						config := setupCluster(t, "volume-pod-affinity-", numNodes, 0, 0)
 | 
				
			||||||
	defer config.teardown()
 | 
						defer config.teardown()
 | 
				
			||||||
@@ -629,7 +625,6 @@ func TestVolumeBindingWithAffinity(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestPVAffinityConflict(t *testing.T) {
 | 
					func TestPVAffinityConflict(t *testing.T) {
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
						defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
				
			||||||
	config := setupCluster(t, "volume-scheduling-", 3, 0, 0)
 | 
						config := setupCluster(t, "volume-scheduling-", 3, 0, 0)
 | 
				
			||||||
	defer config.teardown()
 | 
						defer config.teardown()
 | 
				
			||||||
@@ -690,7 +685,6 @@ func TestPVAffinityConflict(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestVolumeProvision(t *testing.T) {
 | 
					func TestVolumeProvision(t *testing.T) {
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
						defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, true)()
 | 
				
			||||||
	config := setupCluster(t, "volume-scheduling", 1, 0, 0)
 | 
						config := setupCluster(t, "volume-scheduling", 1, 0, 0)
 | 
				
			||||||
	defer config.teardown()
 | 
						defer config.teardown()
 | 
				
			||||||
@@ -830,7 +824,6 @@ func TestVolumeProvision(t *testing.T) {
 | 
				
			|||||||
// on provision failure.
 | 
					// on provision failure.
 | 
				
			||||||
func TestRescheduleProvisioning(t *testing.T) {
 | 
					func TestRescheduleProvisioning(t *testing.T) {
 | 
				
			||||||
	// Set feature gates
 | 
						// Set feature gates
 | 
				
			||||||
	defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
 | 
					 | 
				
			||||||
	controllerCh := make(chan struct{})
 | 
						controllerCh := make(chan struct{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	context := initTestMaster(t, "reschedule-volume-provision", nil)
 | 
						context := initTestMaster(t, "reschedule-volume-provision", nil)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user