From 9e71741d06697a64909142c080d7213e50559c18 Mon Sep 17 00:00:00 2001 From: Aldo Culquicondor Date: Wed, 12 Feb 2020 13:17:44 -0500 Subject: [PATCH] Add Profiles to kubescheduler.config.k8s.io/v1alpha2 Signed-off-by: Aldo Culquicondor --- cmd/kube-scheduler/app/options/deprecated.go | 13 +- cmd/kube-scheduler/app/options/options.go | 10 +- .../app/options/options_test.go | 231 ++++++++++++------ cmd/kube-scheduler/app/server.go | 16 +- pkg/scheduler/apis/config/types.go | 33 ++- .../apis/config/v1alpha1/conversion.go | 29 ++- .../apis/config/v1alpha1/conversion_test.go | 89 +++++-- .../v1alpha1/zz_generated.conversion.go | 45 +--- pkg/scheduler/apis/config/v1alpha2/BUILD | 2 + .../apis/config/v1alpha2/defaults.go | 11 +- .../apis/config/v1alpha2/defaults_test.go | 140 ++++++++++- .../v1alpha2/zz_generated.conversion.go | 90 +++++-- pkg/scheduler/apis/config/validation/BUILD | 1 + .../apis/config/validation/validation.go | 53 +++- .../apis/config/validation/validation_test.go | 69 +++++- .../apis/config/zz_generated.deepcopy.go | 39 ++- .../kube-scheduler/config/v1alpha2/types.go | 35 ++- .../config/v1alpha2/zz_generated.deepcopy.go | 49 +++- 18 files changed, 721 insertions(+), 234 deletions(-) diff --git a/cmd/kube-scheduler/app/options/deprecated.go b/cmd/kube-scheduler/app/options/deprecated.go index 086819ab2cd..badb7063194 100644 --- a/cmd/kube-scheduler/app/options/deprecated.go +++ b/cmd/kube-scheduler/app/options/deprecated.go @@ -38,6 +38,7 @@ type DeprecatedOptions struct { UseLegacyPolicyConfig bool AlgorithmProvider string HardPodAffinitySymmetricWeight int32 + SchedulerName string } // AddFlags adds flags for the deprecated options. @@ -59,14 +60,14 @@ func (o *DeprecatedOptions) AddFlags(fs *pflag.FlagSet, cfg *kubeschedulerconfig fs.StringVar(&cfg.ClientConnection.ContentType, "kube-api-content-type", cfg.ClientConnection.ContentType, "DEPRECATED: content type of requests sent to apiserver.") fs.Float32Var(&cfg.ClientConnection.QPS, "kube-api-qps", cfg.ClientConnection.QPS, "DEPRECATED: QPS to use while talking with kubernetes apiserver") fs.Int32Var(&cfg.ClientConnection.Burst, "kube-api-burst", cfg.ClientConnection.Burst, "DEPRECATED: burst to use while talking with kubernetes apiserver") - fs.StringVar(&cfg.SchedulerName, "scheduler-name", cfg.SchedulerName, "DEPRECATED: name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's \"spec.schedulerName\".") fs.StringVar(&cfg.LeaderElection.ResourceNamespace, "lock-object-namespace", cfg.LeaderElection.ResourceNamespace, "DEPRECATED: define the namespace of the lock object. Will be removed in favor of leader-elect-resource-namespace.") fs.StringVar(&cfg.LeaderElection.ResourceName, "lock-object-name", cfg.LeaderElection.ResourceName, "DEPRECATED: define the name of the lock object. Will be removed in favor of leader-elect-resource-name") - fs.Int32Var(&o.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", interpodaffinity.DefaultHardPodAffinityWeight, + fs.Int32Var(&o.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", o.HardPodAffinitySymmetricWeight, "DEPRECATED: RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding "+ "to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule. Must be in the range 0-100."+ "This option was moved to the policy configuration file") + fs.StringVar(&o.SchedulerName, "scheduler-name", o.SchedulerName, "DEPRECATED: name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's \"spec.schedulerName\".") // MarkDeprecated hides the flag from the help. We don't want that: // fs.MarkDeprecated("hard-pod-affinity-symmetric-weight", "This option was moved to the policy configuration file") } @@ -120,11 +121,17 @@ func (o *DeprecatedOptions) ApplyTo(cfg *kubeschedulerconfig.KubeSchedulerConfig } } + // The following deprecated options affect the only existing profile that is + // added by default. + profile := &cfg.Profiles[0] + if len(o.SchedulerName) > 0 { + profile.SchedulerName = o.SchedulerName + } if o.HardPodAffinitySymmetricWeight != interpodaffinity.DefaultHardPodAffinityWeight { args := interpodaffinity.Args{ HardPodAffinityWeight: &o.HardPodAffinitySymmetricWeight, } - cfg.PluginConfig = append(cfg.PluginConfig, plugins.NewPluginConfig(interpodaffinity.Name, args)) + profile.PluginConfig = append(profile.PluginConfig, plugins.NewPluginConfig(interpodaffinity.Name, args)) } return nil diff --git a/cmd/kube-scheduler/app/options/options.go b/cmd/kube-scheduler/app/options/options.go index 91f0cbd1864..d15bcaede3e 100644 --- a/cmd/kube-scheduler/app/options/options.go +++ b/cmd/kube-scheduler/app/options/options.go @@ -48,6 +48,7 @@ import ( kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config" kubeschedulerscheme "k8s.io/kubernetes/pkg/scheduler/apis/config/scheme" "k8s.io/kubernetes/pkg/scheduler/apis/config/validation" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity" ) // Options has all the params needed to run a Scheduler @@ -98,8 +99,10 @@ func NewOptions() (*Options, error) { Authentication: apiserveroptions.NewDelegatingAuthenticationOptions(), Authorization: apiserveroptions.NewDelegatingAuthorizationOptions(), Deprecated: &DeprecatedOptions{ - UseLegacyPolicyConfig: false, - PolicyConfigMapNamespace: metav1.NamespaceSystem, + UseLegacyPolicyConfig: false, + PolicyConfigMapNamespace: metav1.NamespaceSystem, + SchedulerName: corev1.DefaultSchedulerName, + HardPodAffinitySymmetricWeight: interpodaffinity.DefaultHardPodAffinityWeight, }, } @@ -239,11 +242,12 @@ func (o *Options) Config() (*schedulerappconfig.Config, error) { } coreBroadcaster := record.NewBroadcaster() - coreRecorder := coreBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: c.ComponentConfig.SchedulerName}) // Set up leader election if enabled. var leaderElectionConfig *leaderelection.LeaderElectionConfig if c.ComponentConfig.LeaderElection.LeaderElect { + // Use the scheduler name in the first profile to record leader election. + coreRecorder := coreBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: c.ComponentConfig.Profiles[0].SchedulerName}) leaderElectionConfig, err = makeLeaderElectionConfig(c.ComponentConfig.LeaderElection, leaderElectionClient, coreRecorder) if err != nil { return nil, err diff --git a/cmd/kube-scheduler/app/options/options_test.go b/cmd/kube-scheduler/app/options/options_test.go index de134c38c82..0d35e25bd05 100644 --- a/cmd/kube-scheduler/app/options/options_test.go +++ b/cmd/kube-scheduler/app/options/options_test.go @@ -138,6 +138,7 @@ leaderElection: if err := ioutil.WriteFile(v1alpha1Config, []byte(fmt.Sprintf(` apiVersion: kubescheduler.config.k8s.io/v1alpha1 kind: KubeSchedulerConfiguration +schedulerName: "my-old-scheduler" clientConnection: kubeconfig: "%s" leaderElection: @@ -225,20 +226,21 @@ apiVersion: kubescheduler.config.k8s.io/v1alpha2 kind: KubeSchedulerConfiguration clientConnection: kubeconfig: "%s" -plugins: - reserve: - enabled: - - name: foo - - name: bar - disabled: - - name: baz - preBind: - enabled: - - name: foo - disabled: - - name: baz -pluginConfig: -- name: foo +profiles: +- plugins: + reserve: + enabled: + - name: foo + - name: bar + disabled: + - name: baz + preBind: + enabled: + - name: foo + disabled: + - name: baz + pluginConfig: + - name: foo `, configKubeconfig)), os.FileMode(0600)); err != nil { t.Fatal(err) } @@ -319,7 +321,6 @@ plugins: }, expectedUsername: "config", expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, HealthzBindAddress: "0.0.0.0:10251", MetricsBindAddress: "0.0.0.0:10251", @@ -348,7 +349,9 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, - Plugins: nil, + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ + {SchedulerName: "default-scheduler"}, + }, }, }, { @@ -410,7 +413,6 @@ plugins: }, expectedUsername: "flag", expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, HealthzBindAddress: "", // defaults empty when not running from config file MetricsBindAddress: "", // defaults empty when not running from config file @@ -439,6 +441,9 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ + {SchedulerName: "default-scheduler"}, + }, }, }, { @@ -474,7 +479,6 @@ plugins: }, }, expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, HealthzBindAddress: "", // defaults empty when not running from config file MetricsBindAddress: "", // defaults empty when not running from config file @@ -503,6 +507,9 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ + {SchedulerName: "default-scheduler"}, + }, }, expectedUsername: "none, http", }, @@ -513,7 +520,6 @@ plugins: }, expectedUsername: "config", expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, HealthzBindAddress: "0.0.0.0:10251", MetricsBindAddress: "0.0.0.0:10251", @@ -542,39 +548,44 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, - Plugins: &kubeschedulerconfig.Plugins{ - Reserve: &kubeschedulerconfig.PluginSet{ - Enabled: []kubeschedulerconfig.Plugin{ - { - Name: "foo", - }, - { - Name: "bar", - }, - }, - Disabled: []kubeschedulerconfig.Plugin{ - { - Name: "baz", - }, - }, - }, - PreBind: &kubeschedulerconfig.PluginSet{ - Enabled: []kubeschedulerconfig.Plugin{ - { - Name: "foo", - }, - }, - Disabled: []kubeschedulerconfig.Plugin{ - { - Name: "baz", - }, - }, - }, - }, - PluginConfig: []kubeschedulerconfig.PluginConfig{ + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ { - Name: "foo", - Args: runtime.Unknown{}, + SchedulerName: "default-scheduler", + Plugins: &kubeschedulerconfig.Plugins{ + Reserve: &kubeschedulerconfig.PluginSet{ + Enabled: []kubeschedulerconfig.Plugin{ + { + Name: "foo", + }, + { + Name: "bar", + }, + }, + Disabled: []kubeschedulerconfig.Plugin{ + { + Name: "baz", + }, + }, + }, + PreBind: &kubeschedulerconfig.PluginSet{ + Enabled: []kubeschedulerconfig.Plugin{ + { + Name: "foo", + }, + }, + Disabled: []kubeschedulerconfig.Plugin{ + { + Name: "baz", + }, + }, + }, + }, + PluginConfig: []kubeschedulerconfig.PluginConfig{ + { + Name: "foo", + Args: runtime.Unknown{}, + }, + }, }, }, }, @@ -586,7 +597,6 @@ plugins: }, expectedUsername: "config", expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, HealthzBindAddress: "0.0.0.0:10251", MetricsBindAddress: "0.0.0.0:10251", @@ -615,19 +625,24 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, - Plugins: &kubeschedulerconfig.Plugins{ - PreScore: &kubeschedulerconfig.PluginSet{ - Enabled: []kubeschedulerconfig.Plugin{ - { - Name: "foo", - }, - { - Name: "bar", - }, - }, - Disabled: []kubeschedulerconfig.Plugin{ - { - Name: "baz", + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ + { + SchedulerName: "default-scheduler", + Plugins: &kubeschedulerconfig.Plugins{ + PreScore: &kubeschedulerconfig.PluginSet{ + Enabled: []kubeschedulerconfig.Plugin{ + { + Name: "foo", + }, + { + Name: "bar", + }, + }, + Disabled: []kubeschedulerconfig.Plugin{ + { + Name: "baz", + }, + }, }, }, }, @@ -653,7 +668,6 @@ plugins: }, expectedUsername: "flag", expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{ EnableProfiling: true, @@ -680,24 +694,74 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, - PluginConfig: []kubeschedulerconfig.PluginConfig{ + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ { - Name: "InterPodAffinity", - Args: runtime.Unknown{ - Raw: []byte(`{"hardPodAffinityWeight":5}`), + SchedulerName: "default-scheduler", + PluginConfig: []kubeschedulerconfig.PluginConfig{ + { + Name: "InterPodAffinity", + Args: runtime.Unknown{ + Raw: []byte(`{"hardPodAffinityWeight":5}`), + }, + }, }, }, }, }, }, { - name: "v1alpha1 config with HardPodAffinitySymmetricWeight", + name: "Deprecated SchedulerName flag", + options: &Options{ + ComponentConfig: func() kubeschedulerconfig.KubeSchedulerConfiguration { + cfg, _ := newDefaultComponentConfig() + cfg.ClientConnection.Kubeconfig = flagKubeconfig + return *cfg + }(), + Deprecated: &DeprecatedOptions{ + SchedulerName: "my-nice-scheduler", + HardPodAffinitySymmetricWeight: 1, + }, + }, + expectedUsername: "flag", + expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ + AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, + DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{ + EnableProfiling: true, + EnableContentionProfiling: true, + }, + LeaderElection: kubeschedulerconfig.KubeSchedulerLeaderElectionConfiguration{ + LeaderElectionConfiguration: componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: true, + LeaseDuration: metav1.Duration{Duration: 15 * time.Second}, + RenewDeadline: metav1.Duration{Duration: 10 * time.Second}, + RetryPeriod: metav1.Duration{Duration: 2 * time.Second}, + ResourceLock: "endpointsleases", + ResourceNamespace: "kube-system", + ResourceName: "kube-scheduler", + }, + }, + ClientConnection: componentbaseconfig.ClientConnectionConfiguration{ + Kubeconfig: flagKubeconfig, + QPS: 50, + Burst: 100, + ContentType: "application/vnd.kubernetes.protobuf", + }, + PercentageOfNodesToScore: defaultPercentageOfNodesToScore, + BindTimeoutSeconds: defaultBindTimeoutSeconds, + PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, + PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ + {SchedulerName: "my-nice-scheduler"}, + }, + }, + }, + { + name: "v1alpha1 config with SchedulerName and HardPodAffinitySymmetricWeight", options: &Options{ ConfigFile: v1alpha1Config, }, expectedUsername: "config", expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, HealthzBindAddress: "0.0.0.0:10251", MetricsBindAddress: "0.0.0.0:10251", @@ -726,11 +790,16 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, - PluginConfig: []kubeschedulerconfig.PluginConfig{ + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ { - Name: "InterPodAffinity", - Args: runtime.Unknown{ - Raw: []byte(`{"hardPodAffinityWeight":3}`), + SchedulerName: "my-old-scheduler", + PluginConfig: []kubeschedulerconfig.PluginConfig{ + { + Name: "InterPodAffinity", + Args: runtime.Unknown{ + Raw: []byte(`{"hardPodAffinityWeight":3}`), + }, + }, }, }, }, @@ -743,7 +812,6 @@ plugins: }, expectedUsername: "config", expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, HealthzBindAddress: "0.0.0.0:10251", MetricsBindAddress: "0.0.0.0:10251", @@ -772,7 +840,9 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, - Plugins: nil, + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ + {SchedulerName: "default-scheduler"}, + }, }, }, { @@ -790,7 +860,6 @@ plugins: }, expectedUsername: "config", expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{ - SchedulerName: "default-scheduler", AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource}, HealthzBindAddress: "0.0.0.0:10251", MetricsBindAddress: "0.0.0.0:10251", @@ -819,7 +888,9 @@ plugins: BindTimeoutSeconds: defaultBindTimeoutSeconds, PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds, PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds, - Plugins: nil, + Profiles: []kubeschedulerconfig.KubeSchedulerProfile{ + {SchedulerName: "default-scheduler"}, + }, }, }, { diff --git a/cmd/kube-scheduler/app/server.go b/cmd/kube-scheduler/app/server.go index 5c5f0bf6ddb..207fec0aadd 100644 --- a/cmd/kube-scheduler/app/server.go +++ b/cmd/kube-scheduler/app/server.go @@ -19,6 +19,7 @@ package app import ( "context" + "errors" "fmt" "io" "net/http" @@ -171,12 +172,17 @@ func Run(ctx context.Context, cc schedulerserverconfig.CompletedConfig, outOfTre } } + if len(cc.ComponentConfig.Profiles) != 1 { + // TODO(#85737): Support more than one profile. + return errors.New("multiple scheduling profiles are unsupported") + } + profile := cc.ComponentConfig.Profiles[0] // Prepare event clients. if _, err := cc.Client.Discovery().ServerResourcesForGroupVersion(eventsv1beta1.SchemeGroupVersion.String()); err == nil { cc.Broadcaster = events.NewBroadcaster(&events.EventSinkImpl{Interface: cc.EventClient.Events("")}) - cc.Recorder = cc.Broadcaster.NewRecorder(scheme.Scheme, cc.ComponentConfig.SchedulerName) + cc.Recorder = cc.Broadcaster.NewRecorder(scheme.Scheme, profile.SchedulerName) } else { - recorder := cc.CoreBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: cc.ComponentConfig.SchedulerName}) + recorder := cc.CoreBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: profile.SchedulerName}) cc.Recorder = record.NewEventRecorderAdapter(recorder) } @@ -186,14 +192,14 @@ func Run(ctx context.Context, cc schedulerserverconfig.CompletedConfig, outOfTre cc.PodInformer, cc.Recorder, ctx.Done(), - scheduler.WithName(cc.ComponentConfig.SchedulerName), + scheduler.WithName(profile.SchedulerName), scheduler.WithAlgorithmSource(cc.ComponentConfig.AlgorithmSource), scheduler.WithPreemptionDisabled(cc.ComponentConfig.DisablePreemption), scheduler.WithPercentageOfNodesToScore(cc.ComponentConfig.PercentageOfNodesToScore), scheduler.WithBindTimeoutSeconds(cc.ComponentConfig.BindTimeoutSeconds), scheduler.WithFrameworkOutOfTreeRegistry(outOfTreeRegistry), - scheduler.WithFrameworkPlugins(cc.ComponentConfig.Plugins), - scheduler.WithFrameworkPluginConfig(cc.ComponentConfig.PluginConfig), + scheduler.WithFrameworkPlugins(profile.Plugins), + scheduler.WithFrameworkPluginConfig(profile.PluginConfig), scheduler.WithPodMaxBackoffSeconds(cc.ComponentConfig.PodMaxBackoffSeconds), scheduler.WithPodInitialBackoffSeconds(cc.ComponentConfig.PodInitialBackoffSeconds), ) diff --git a/pkg/scheduler/apis/config/types.go b/pkg/scheduler/apis/config/types.go index de6d7a47908..56abe88a2a4 100644 --- a/pkg/scheduler/apis/config/types.go +++ b/pkg/scheduler/apis/config/types.go @@ -46,9 +46,6 @@ const ( type KubeSchedulerConfiguration struct { metav1.TypeMeta - // SchedulerName is name of the scheduler, used to select which pods - // will be processed by this scheduler, based on pod's "spec.SchedulerName". - SchedulerName string // AlgorithmSource specifies the scheduler algorithm source. AlgorithmSource SchedulerAlgorithmSource @@ -97,15 +94,33 @@ type KubeSchedulerConfiguration struct { // the default value (10s) will be used. PodMaxBackoffSeconds int64 - // Plugins specify the set of plugins that should be enabled or disabled. Enabled plugins are the - // ones that should be enabled in addition to the default plugins. Disabled plugins are any of the - // default plugins that should be disabled. - // When no enabled or disabled plugin is specified for an extension point, default plugins for - // that extension point will be used if there is any. + // Profiles are scheduling profiles that kube-scheduler supports. Pods can + // choose to be scheduled under a particular profile by setting its associated + // scheduler name. Pods that don't specify any scheduler name are scheduled + // with the "default-scheduler" profile, if present here. + Profiles []KubeSchedulerProfile +} + +// KubeSchedulerProfile is a scheduling profile. +type KubeSchedulerProfile struct { + // SchedulerName is the name of the scheduler associated to this profile. + // If SchedulerName matches with the pod's "spec.schedulerName", then the pod + // is scheduled with this profile. + SchedulerName string + + // Plugins specify the set of plugins that should be enabled or disabled. + // Enabled plugins are the ones that should be enabled in addition to the + // default plugins. Disabled plugins are any of the default plugins that + // should be disabled. + // When no enabled or disabled plugin is specified for an extension point, + // default plugins for that extension point will be used if there is any. + // If a QueueSort plugin is specified, the same QueueSort Plugin and + // PluginConfig must be specified for all profiles. Plugins *Plugins // PluginConfig is an optional set of custom plugin arguments for each plugin. - // Omitting config args for a plugin is equivalent to using the default config for that plugin. + // Omitting config args for a plugin is equivalent to using the default config + // for that plugin. PluginConfig []PluginConfig } diff --git a/pkg/scheduler/apis/config/v1alpha1/conversion.go b/pkg/scheduler/apis/config/v1alpha1/conversion.go index 60f6e4e3047..55ae5ed7ba2 100644 --- a/pkg/scheduler/apis/config/v1alpha1/conversion.go +++ b/pkg/scheduler/apis/config/v1alpha1/conversion.go @@ -19,6 +19,7 @@ package v1alpha1 import ( "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" "k8s.io/kube-scheduler/config/v1alpha1" "k8s.io/kubernetes/pkg/scheduler/apis/config" @@ -31,14 +32,40 @@ func Convert_v1alpha1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfigur if err := autoConvert_v1alpha1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(in, out, s); err != nil { return err } + var profile config.KubeSchedulerProfile + if err := metav1.Convert_Pointer_string_To_string(&in.SchedulerName, &profile.SchedulerName, s); err != nil { + return err + } + if in.Plugins != nil { + profile.Plugins = &config.Plugins{} + if err := Convert_v1alpha1_Plugins_To_config_Plugins(in.Plugins, profile.Plugins, s); err != nil { + return err + } + } else { + profile.Plugins = nil + } + if in.PluginConfig != nil { + profile.PluginConfig = make([]config.PluginConfig, len(in.PluginConfig)) + for i := range in.PluginConfig { + if err := Convert_v1alpha1_PluginConfig_To_config_PluginConfig(&in.PluginConfig[i], &profile.PluginConfig[i], s); err != nil { + return err + } + } + } if in.HardPodAffinitySymmetricWeight != nil { args := interpodaffinity.Args{HardPodAffinityWeight: in.HardPodAffinitySymmetricWeight} plCfg := plugins.NewPluginConfig(interpodaffinity.Name, args) - out.PluginConfig = append(out.PluginConfig, plCfg) + profile.PluginConfig = append(profile.PluginConfig, plCfg) } + out.Profiles = []config.KubeSchedulerProfile{profile} return nil } +func Convert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration(in *config.KubeSchedulerConfiguration, out *v1alpha1.KubeSchedulerConfiguration, s conversion.Scope) error { + // Conversion from internal to v1alpha1 is not relevant for kube-scheduler. + return autoConvert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration(in, out, s) +} + // Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration handles deprecated parameters for leader election. func Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(in *v1alpha1.KubeSchedulerLeaderElectionConfiguration, out *config.KubeSchedulerLeaderElectionConfiguration, s conversion.Scope) error { if err := autoConvert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(in, out, s); err != nil { diff --git a/pkg/scheduler/apis/config/v1alpha1/conversion_test.go b/pkg/scheduler/apis/config/v1alpha1/conversion_test.go index 331c6770dc6..15c4c49eacd 100644 --- a/pkg/scheduler/apis/config/v1alpha1/conversion_test.go +++ b/pkg/scheduler/apis/config/v1alpha1/conversion_test.go @@ -30,33 +30,76 @@ import ( "k8s.io/utils/pointer" ) -func TestConvertHardPodAffinitySymmetricWeight(t *testing.T) { +func TestConvertKubeSchedulerConfiguration(t *testing.T) { cases := []struct { name string cfg v1alpha1.KubeSchedulerConfiguration want config.KubeSchedulerConfiguration }{ { - name: "no weight", - }, - { - name: "custom weight", + name: "scheduler name", cfg: v1alpha1.KubeSchedulerConfiguration{ - HardPodAffinitySymmetricWeight: pointer.Int32Ptr(3), + SchedulerName: pointer.StringPtr("custom-name"), }, want: config.KubeSchedulerConfiguration{ - PluginConfig: []config.PluginConfig{ + Profiles: []config.KubeSchedulerProfile{ + {SchedulerName: "custom-name"}, + }, + }, + }, + { + name: "plugins and plugin config", + cfg: v1alpha1.KubeSchedulerConfiguration{ + Plugins: &v1alpha1.Plugins{ + QueueSort: &v1alpha1.PluginSet{ + Enabled: []v1alpha1.Plugin{ + {Name: "FooPlugin"}, + }, + }, + }, + PluginConfig: []v1alpha1.PluginConfig{ + {Name: "FooPlugin"}, + }, + }, + want: config.KubeSchedulerConfiguration{ + Profiles: []config.KubeSchedulerProfile{ { - Name: "InterPodAffinity", - Args: runtime.Unknown{ - Raw: []byte(`{"hardPodAffinityWeight":3}`), + Plugins: &config.Plugins{ + QueueSort: &config.PluginSet{ + Enabled: []config.Plugin{ + {Name: "FooPlugin"}, + }, + }, + }, + PluginConfig: []config.PluginConfig{ + {Name: "FooPlugin"}, }, }, }, }, }, { - name: "custom weight and existing PluginConfig", + name: "custom hard pod affinity weight", + cfg: v1alpha1.KubeSchedulerConfiguration{ + HardPodAffinitySymmetricWeight: pointer.Int32Ptr(3), + }, + want: config.KubeSchedulerConfiguration{ + Profiles: []config.KubeSchedulerProfile{ + { + PluginConfig: []config.PluginConfig{ + { + Name: "InterPodAffinity", + Args: runtime.Unknown{ + Raw: []byte(`{"hardPodAffinityWeight":3}`), + }, + }, + }, + }, + }, + }, + }, + { + name: "custom hard pod affinity weight and existing PluginConfig", cfg: v1alpha1.KubeSchedulerConfiguration{ HardPodAffinitySymmetricWeight: pointer.Int32Ptr(3), PluginConfig: []v1alpha1.PluginConfig{ @@ -69,17 +112,21 @@ func TestConvertHardPodAffinitySymmetricWeight(t *testing.T) { }, }, want: config.KubeSchedulerConfiguration{ - PluginConfig: []config.PluginConfig{ + Profiles: []config.KubeSchedulerProfile{ { - Name: "InterPodAffinity", - Args: runtime.Unknown{ - Raw: []byte(`{"hardPodAffinityWeight":5}`), - }, - }, - { - Name: "InterPodAffinity", - Args: runtime.Unknown{ - Raw: []byte(`{"hardPodAffinityWeight":3}`), + PluginConfig: []config.PluginConfig{ + { + Name: "InterPodAffinity", + Args: runtime.Unknown{ + Raw: []byte(`{"hardPodAffinityWeight":5}`), + }, + }, + { + Name: "InterPodAffinity", + Args: runtime.Unknown{ + Raw: []byte(`{"hardPodAffinityWeight":3}`), + }, + }, }, }, }, diff --git a/pkg/scheduler/apis/config/v1alpha1/zz_generated.conversion.go b/pkg/scheduler/apis/config/v1alpha1/zz_generated.conversion.go index 4caef540c94..fe1595e11ae 100644 --- a/pkg/scheduler/apis/config/v1alpha1/zz_generated.conversion.go +++ b/pkg/scheduler/apis/config/v1alpha1/zz_generated.conversion.go @@ -38,11 +38,6 @@ func init() { // RegisterConversions adds conversion functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterConversions(s *runtime.Scheme) error { - if err := s.AddGeneratedConversionFunc((*config.KubeSchedulerConfiguration)(nil), (*v1alpha1.KubeSchedulerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration(a.(*config.KubeSchedulerConfiguration), b.(*v1alpha1.KubeSchedulerConfiguration), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*v1alpha1.Plugin)(nil), (*config.Plugin)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_Plugin_To_config_Plugin(a.(*v1alpha1.Plugin), b.(*config.Plugin), scope) }); err != nil { @@ -113,6 +108,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*config.KubeSchedulerConfiguration)(nil), (*v1alpha1.KubeSchedulerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration(a.(*config.KubeSchedulerConfiguration), b.(*v1alpha1.KubeSchedulerConfiguration), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*config.KubeSchedulerLeaderElectionConfiguration)(nil), (*v1alpha1.KubeSchedulerLeaderElectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(a.(*config.KubeSchedulerLeaderElectionConfiguration), b.(*v1alpha1.KubeSchedulerLeaderElectionConfiguration), scope) }); err != nil { @@ -142,9 +142,7 @@ func RegisterConversions(s *runtime.Scheme) error { } func autoConvert_v1alpha1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(in *v1alpha1.KubeSchedulerConfiguration, out *config.KubeSchedulerConfiguration, s conversion.Scope) error { - if err := v1.Convert_Pointer_string_To_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { - return err - } + // WARNING: in.SchedulerName requires manual conversion: does not exist in peer-type if err := Convert_v1alpha1_SchedulerAlgorithmSource_To_config_SchedulerAlgorithmSource(&in.AlgorithmSource, &out.AlgorithmSource, s); err != nil { return err } @@ -179,23 +177,12 @@ func autoConvert_v1alpha1_KubeSchedulerConfiguration_To_config_KubeSchedulerConf if err := v1.Convert_Pointer_int64_To_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { return err } - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(config.Plugins) - if err := Convert_v1alpha1_Plugins_To_config_Plugins(*in, *out, s); err != nil { - return err - } - } else { - out.Plugins = nil - } - out.PluginConfig = *(*[]config.PluginConfig)(unsafe.Pointer(&in.PluginConfig)) + // WARNING: in.Plugins requires manual conversion: does not exist in peer-type + // WARNING: in.PluginConfig requires manual conversion: does not exist in peer-type return nil } func autoConvert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration(in *config.KubeSchedulerConfiguration, out *v1alpha1.KubeSchedulerConfiguration, s conversion.Scope) error { - if err := v1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { - return err - } if err := Convert_config_SchedulerAlgorithmSource_To_v1alpha1_SchedulerAlgorithmSource(&in.AlgorithmSource, &out.AlgorithmSource, s); err != nil { return err } @@ -229,24 +216,10 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConf if err := v1.Convert_int64_To_Pointer_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { return err } - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(v1alpha1.Plugins) - if err := Convert_config_Plugins_To_v1alpha1_Plugins(*in, *out, s); err != nil { - return err - } - } else { - out.Plugins = nil - } - out.PluginConfig = *(*[]v1alpha1.PluginConfig)(unsafe.Pointer(&in.PluginConfig)) + // WARNING: in.Profiles requires manual conversion: does not exist in peer-type return nil } -// Convert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration is an autogenerated conversion function. -func Convert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration(in *config.KubeSchedulerConfiguration, out *v1alpha1.KubeSchedulerConfiguration, s conversion.Scope) error { - return autoConvert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration(in, out, s) -} - func autoConvert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(in *v1alpha1.KubeSchedulerLeaderElectionConfiguration, out *config.KubeSchedulerLeaderElectionConfiguration, s conversion.Scope) error { if err := componentbaseconfigv1alpha1.Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(&in.LeaderElectionConfiguration, &out.LeaderElectionConfiguration, s); err != nil { return err diff --git a/pkg/scheduler/apis/config/v1alpha2/BUILD b/pkg/scheduler/apis/config/v1alpha2/BUILD index 310bb455145..a6b472697a0 100644 --- a/pkg/scheduler/apis/config/v1alpha2/BUILD +++ b/pkg/scheduler/apis/config/v1alpha2/BUILD @@ -21,6 +21,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library", "//staging/src/k8s.io/kube-scheduler/config/v1alpha2:go_default_library", + "//vendor/k8s.io/utils/pointer:go_default_library", ], ) @@ -32,6 +33,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library", "//staging/src/k8s.io/kube-scheduler/config/v1alpha2:go_default_library", + "//vendor/github.com/google/go-cmp/cmp:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library", ], ) diff --git a/pkg/scheduler/apis/config/v1alpha2/defaults.go b/pkg/scheduler/apis/config/v1alpha2/defaults.go index 1b1479cfaf4..ba37f730256 100644 --- a/pkg/scheduler/apis/config/v1alpha2/defaults.go +++ b/pkg/scheduler/apis/config/v1alpha2/defaults.go @@ -24,6 +24,7 @@ import ( componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1" "k8s.io/kube-scheduler/config/v1alpha2" "k8s.io/kubernetes/pkg/scheduler/apis/config" + "k8s.io/utils/pointer" // this package shouldn't really depend on other k8s.io/kubernetes code api "k8s.io/kubernetes/pkg/apis/core" @@ -36,9 +37,13 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error { // SetDefaults_KubeSchedulerConfiguration sets additional defaults func SetDefaults_KubeSchedulerConfiguration(obj *v1alpha2.KubeSchedulerConfiguration) { - if obj.SchedulerName == nil { - val := api.DefaultSchedulerName - obj.SchedulerName = &val + if len(obj.Profiles) == 0 { + obj.Profiles = append(obj.Profiles, v1alpha2.KubeSchedulerProfile{}) + } + // Only apply a default scheduler name when there is a single profile. + // Validation will ensure that every profile has a non-empty unique name. + if len(obj.Profiles) == 1 && obj.Profiles[0].SchedulerName == nil { + obj.Profiles[0].SchedulerName = pointer.StringPtr(api.DefaultSchedulerName) } if obj.AlgorithmSource.Policy == nil && diff --git a/pkg/scheduler/apis/config/v1alpha2/defaults_test.go b/pkg/scheduler/apis/config/v1alpha2/defaults_test.go index ea4bd68cd28..5a12decfae8 100644 --- a/pkg/scheduler/apis/config/v1alpha2/defaults_test.go +++ b/pkg/scheduler/apis/config/v1alpha2/defaults_test.go @@ -17,10 +17,10 @@ limitations under the License. package v1alpha2 import ( - "reflect" "testing" "time" + "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" componentbaseconfig "k8s.io/component-base/config/v1alpha1" "k8s.io/kube-scheduler/config/v1alpha2" @@ -38,7 +38,6 @@ func TestSchedulerDefaults(t *testing.T) { name: "empty config", config: &v1alpha2.KubeSchedulerConfiguration{}, expected: &v1alpha2.KubeSchedulerConfiguration{ - SchedulerName: pointer.StringPtr("default-scheduler"), AlgorithmSource: v1alpha2.SchedulerAlgorithmSource{Provider: pointer.StringPtr("DefaultProvider")}, HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"), MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"), @@ -67,7 +66,128 @@ func TestSchedulerDefaults(t *testing.T) { BindTimeoutSeconds: pointer.Int64Ptr(600), PodInitialBackoffSeconds: pointer.Int64Ptr(1), PodMaxBackoffSeconds: pointer.Int64Ptr(10), - Plugins: nil, + Profiles: []v1alpha2.KubeSchedulerProfile{ + {SchedulerName: pointer.StringPtr("default-scheduler")}, + }, + }, + }, + { + name: "no scheduler name", + config: &v1alpha2.KubeSchedulerConfiguration{ + Profiles: []v1alpha2.KubeSchedulerProfile{ + { + PluginConfig: []v1alpha2.PluginConfig{ + {Name: "FooPlugin"}, + }, + }, + }, + }, + expected: &v1alpha2.KubeSchedulerConfiguration{ + AlgorithmSource: v1alpha2.SchedulerAlgorithmSource{Provider: pointer.StringPtr("DefaultProvider")}, + HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"), + MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"), + DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{ + EnableProfiling: &enable, + EnableContentionProfiling: &enable, + }, + LeaderElection: v1alpha2.KubeSchedulerLeaderElectionConfiguration{ + LeaderElectionConfiguration: componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: pointer.BoolPtr(true), + LeaseDuration: metav1.Duration{Duration: 15 * time.Second}, + RenewDeadline: metav1.Duration{Duration: 10 * time.Second}, + RetryPeriod: metav1.Duration{Duration: 2 * time.Second}, + ResourceLock: "endpointsleases", + ResourceNamespace: "kube-system", + ResourceName: "kube-scheduler", + }, + }, + ClientConnection: componentbaseconfig.ClientConnectionConfiguration{ + QPS: 50, + Burst: 100, + ContentType: "application/vnd.kubernetes.protobuf", + }, + DisablePreemption: pointer.BoolPtr(false), + PercentageOfNodesToScore: pointer.Int32Ptr(0), + BindTimeoutSeconds: pointer.Int64Ptr(600), + PodInitialBackoffSeconds: pointer.Int64Ptr(1), + PodMaxBackoffSeconds: pointer.Int64Ptr(10), + Profiles: []v1alpha2.KubeSchedulerProfile{ + { + SchedulerName: pointer.StringPtr("default-scheduler"), + PluginConfig: []v1alpha2.PluginConfig{ + {Name: "FooPlugin"}, + }, + }, + }, + }, + }, + { + name: "two profiles", + config: &v1alpha2.KubeSchedulerConfiguration{ + Profiles: []v1alpha2.KubeSchedulerProfile{ + { + PluginConfig: []v1alpha2.PluginConfig{ + {Name: "FooPlugin"}, + }, + }, + { + SchedulerName: pointer.StringPtr("custom-scheduler"), + Plugins: &v1alpha2.Plugins{ + Bind: &v1alpha2.PluginSet{ + Enabled: []v1alpha2.Plugin{ + {Name: "BarPlugin"}, + }, + }, + }, + }, + }, + }, + expected: &v1alpha2.KubeSchedulerConfiguration{ + AlgorithmSource: v1alpha2.SchedulerAlgorithmSource{Provider: pointer.StringPtr("DefaultProvider")}, + HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"), + MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"), + DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{ + EnableProfiling: &enable, + EnableContentionProfiling: &enable, + }, + LeaderElection: v1alpha2.KubeSchedulerLeaderElectionConfiguration{ + LeaderElectionConfiguration: componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: pointer.BoolPtr(true), + LeaseDuration: metav1.Duration{Duration: 15 * time.Second}, + RenewDeadline: metav1.Duration{Duration: 10 * time.Second}, + RetryPeriod: metav1.Duration{Duration: 2 * time.Second}, + ResourceLock: "endpointsleases", + ResourceNamespace: "kube-system", + ResourceName: "kube-scheduler", + }, + }, + ClientConnection: componentbaseconfig.ClientConnectionConfiguration{ + QPS: 50, + Burst: 100, + ContentType: "application/vnd.kubernetes.protobuf", + }, + DisablePreemption: pointer.BoolPtr(false), + PercentageOfNodesToScore: pointer.Int32Ptr(0), + BindTimeoutSeconds: pointer.Int64Ptr(600), + PodInitialBackoffSeconds: pointer.Int64Ptr(1), + PodMaxBackoffSeconds: pointer.Int64Ptr(10), + Profiles: []v1alpha2.KubeSchedulerProfile{ + { + PluginConfig: []v1alpha2.PluginConfig{ + {Name: "FooPlugin"}, + }, + }, + { + SchedulerName: pointer.StringPtr("custom-scheduler"), + Plugins: &v1alpha2.Plugins{ + Bind: &v1alpha2.PluginSet{ + Enabled: []v1alpha2.Plugin{ + {Name: "BarPlugin"}, + }, + }, + }, + }, + }, }, }, { @@ -77,7 +197,6 @@ func TestSchedulerDefaults(t *testing.T) { HealthzBindAddress: pointer.StringPtr("1.2.3.4"), }, expected: &v1alpha2.KubeSchedulerConfiguration{ - SchedulerName: pointer.StringPtr("default-scheduler"), AlgorithmSource: v1alpha2.SchedulerAlgorithmSource{Provider: pointer.StringPtr("DefaultProvider")}, HealthzBindAddress: pointer.StringPtr("1.2.3.4:10251"), MetricsBindAddress: pointer.StringPtr("1.2.3.4:10251"), @@ -106,7 +225,9 @@ func TestSchedulerDefaults(t *testing.T) { BindTimeoutSeconds: pointer.Int64Ptr(600), PodInitialBackoffSeconds: pointer.Int64Ptr(1), PodMaxBackoffSeconds: pointer.Int64Ptr(10), - Plugins: nil, + Profiles: []v1alpha2.KubeSchedulerProfile{ + {SchedulerName: pointer.StringPtr("default-scheduler")}, + }, }, }, { @@ -116,7 +237,6 @@ func TestSchedulerDefaults(t *testing.T) { HealthzBindAddress: pointer.StringPtr(":12345"), }, expected: &v1alpha2.KubeSchedulerConfiguration{ - SchedulerName: pointer.StringPtr("default-scheduler"), AlgorithmSource: v1alpha2.SchedulerAlgorithmSource{Provider: pointer.StringPtr("DefaultProvider")}, HealthzBindAddress: pointer.StringPtr("0.0.0.0:12345"), MetricsBindAddress: pointer.StringPtr("0.0.0.0:12345"), @@ -145,15 +265,17 @@ func TestSchedulerDefaults(t *testing.T) { BindTimeoutSeconds: pointer.Int64Ptr(600), PodInitialBackoffSeconds: pointer.Int64Ptr(1), PodMaxBackoffSeconds: pointer.Int64Ptr(10), - Plugins: nil, + Profiles: []v1alpha2.KubeSchedulerProfile{ + {SchedulerName: pointer.StringPtr("default-scheduler")}, + }, }, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { SetDefaults_KubeSchedulerConfiguration(tc.config) - if !reflect.DeepEqual(tc.expected, tc.config) { - t.Errorf("Expected:\n%#v\n\nGot:\n%#v", tc.expected, tc.config) + if diff := cmp.Diff(tc.expected, tc.config); diff != "" { + t.Errorf("Got unexpected defaults (-want, +got):\n%s", diff) } }) } diff --git a/pkg/scheduler/apis/config/v1alpha2/zz_generated.conversion.go b/pkg/scheduler/apis/config/v1alpha2/zz_generated.conversion.go index 8706d563eed..3dc2a412137 100644 --- a/pkg/scheduler/apis/config/v1alpha2/zz_generated.conversion.go +++ b/pkg/scheduler/apis/config/v1alpha2/zz_generated.conversion.go @@ -58,6 +58,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha2.KubeSchedulerProfile)(nil), (*config.KubeSchedulerProfile)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_KubeSchedulerProfile_To_config_KubeSchedulerProfile(a.(*v1alpha2.KubeSchedulerProfile), b.(*config.KubeSchedulerProfile), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.KubeSchedulerProfile)(nil), (*v1alpha2.KubeSchedulerProfile)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_KubeSchedulerProfile_To_v1alpha2_KubeSchedulerProfile(a.(*config.KubeSchedulerProfile), b.(*v1alpha2.KubeSchedulerProfile), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1alpha2.Plugin)(nil), (*config.Plugin)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_Plugin_To_config_Plugin(a.(*v1alpha2.Plugin), b.(*config.Plugin), scope) }); err != nil { @@ -142,9 +152,6 @@ func RegisterConversions(s *runtime.Scheme) error { } func autoConvert_v1alpha2_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(in *v1alpha2.KubeSchedulerConfiguration, out *config.KubeSchedulerConfiguration, s conversion.Scope) error { - if err := v1.Convert_Pointer_string_To_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { - return err - } if err := Convert_v1alpha2_SchedulerAlgorithmSource_To_config_SchedulerAlgorithmSource(&in.AlgorithmSource, &out.AlgorithmSource, s); err != nil { return err } @@ -178,16 +185,17 @@ func autoConvert_v1alpha2_KubeSchedulerConfiguration_To_config_KubeSchedulerConf if err := v1.Convert_Pointer_int64_To_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { return err } - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(config.Plugins) - if err := Convert_v1alpha2_Plugins_To_config_Plugins(*in, *out, s); err != nil { - return err + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]config.KubeSchedulerProfile, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_KubeSchedulerProfile_To_config_KubeSchedulerProfile(&(*in)[i], &(*out)[i], s); err != nil { + return err + } } } else { - out.Plugins = nil + out.Profiles = nil } - out.PluginConfig = *(*[]config.PluginConfig)(unsafe.Pointer(&in.PluginConfig)) return nil } @@ -197,9 +205,6 @@ func Convert_v1alpha2_KubeSchedulerConfiguration_To_config_KubeSchedulerConfigur } func autoConvert_config_KubeSchedulerConfiguration_To_v1alpha2_KubeSchedulerConfiguration(in *config.KubeSchedulerConfiguration, out *v1alpha2.KubeSchedulerConfiguration, s conversion.Scope) error { - if err := v1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { - return err - } if err := Convert_config_SchedulerAlgorithmSource_To_v1alpha2_SchedulerAlgorithmSource(&in.AlgorithmSource, &out.AlgorithmSource, s); err != nil { return err } @@ -233,16 +238,17 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1alpha2_KubeSchedulerConf if err := v1.Convert_int64_To_Pointer_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { return err } - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(v1alpha2.Plugins) - if err := Convert_config_Plugins_To_v1alpha2_Plugins(*in, *out, s); err != nil { - return err + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]v1alpha2.KubeSchedulerProfile, len(*in)) + for i := range *in { + if err := Convert_config_KubeSchedulerProfile_To_v1alpha2_KubeSchedulerProfile(&(*in)[i], &(*out)[i], s); err != nil { + return err + } } } else { - out.Plugins = nil + out.Profiles = nil } - out.PluginConfig = *(*[]v1alpha2.PluginConfig)(unsafe.Pointer(&in.PluginConfig)) return nil } @@ -275,6 +281,50 @@ func Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha2_KubeSch return autoConvert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha2_KubeSchedulerLeaderElectionConfiguration(in, out, s) } +func autoConvert_v1alpha2_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in *v1alpha2.KubeSchedulerProfile, out *config.KubeSchedulerProfile, s conversion.Scope) error { + if err := v1.Convert_Pointer_string_To_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { + return err + } + if in.Plugins != nil { + in, out := &in.Plugins, &out.Plugins + *out = new(config.Plugins) + if err := Convert_v1alpha2_Plugins_To_config_Plugins(*in, *out, s); err != nil { + return err + } + } else { + out.Plugins = nil + } + out.PluginConfig = *(*[]config.PluginConfig)(unsafe.Pointer(&in.PluginConfig)) + return nil +} + +// Convert_v1alpha2_KubeSchedulerProfile_To_config_KubeSchedulerProfile is an autogenerated conversion function. +func Convert_v1alpha2_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in *v1alpha2.KubeSchedulerProfile, out *config.KubeSchedulerProfile, s conversion.Scope) error { + return autoConvert_v1alpha2_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in, out, s) +} + +func autoConvert_config_KubeSchedulerProfile_To_v1alpha2_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *v1alpha2.KubeSchedulerProfile, s conversion.Scope) error { + if err := v1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { + return err + } + if in.Plugins != nil { + in, out := &in.Plugins, &out.Plugins + *out = new(v1alpha2.Plugins) + if err := Convert_config_Plugins_To_v1alpha2_Plugins(*in, *out, s); err != nil { + return err + } + } else { + out.Plugins = nil + } + out.PluginConfig = *(*[]v1alpha2.PluginConfig)(unsafe.Pointer(&in.PluginConfig)) + return nil +} + +// Convert_config_KubeSchedulerProfile_To_v1alpha2_KubeSchedulerProfile is an autogenerated conversion function. +func Convert_config_KubeSchedulerProfile_To_v1alpha2_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *v1alpha2.KubeSchedulerProfile, s conversion.Scope) error { + return autoConvert_config_KubeSchedulerProfile_To_v1alpha2_KubeSchedulerProfile(in, out, s) +} + func autoConvert_v1alpha2_Plugin_To_config_Plugin(in *v1alpha2.Plugin, out *config.Plugin, s conversion.Scope) error { out.Name = in.Name if err := v1.Convert_Pointer_int32_To_int32(&in.Weight, &out.Weight, s); err != nil { diff --git a/pkg/scheduler/apis/config/validation/BUILD b/pkg/scheduler/apis/config/validation/BUILD index b2c8d728093..edea5e2bba6 100644 --- a/pkg/scheduler/apis/config/validation/BUILD +++ b/pkg/scheduler/apis/config/validation/BUILD @@ -14,6 +14,7 @@ go_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/component-base/config/validation:go_default_library", + "//vendor/github.com/google/go-cmp/cmp:go_default_library", ], ) diff --git a/pkg/scheduler/apis/config/validation/validation.go b/pkg/scheduler/apis/config/validation/validation.go index 0f90013600f..c5f4f224a0b 100644 --- a/pkg/scheduler/apis/config/validation/validation.go +++ b/pkg/scheduler/apis/config/validation/validation.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" + "github.com/google/go-cmp/cmp" v1 "k8s.io/api/core/v1" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/sets" @@ -34,9 +35,23 @@ import ( func ValidateKubeSchedulerConfiguration(cc *config.KubeSchedulerConfiguration) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, componentbasevalidation.ValidateClientConnectionConfiguration(&cc.ClientConnection, field.NewPath("clientConnection"))...) - allErrs = append(allErrs, ValidateKubeSchedulerLeaderElectionConfiguration(&cc.LeaderElection, field.NewPath("leaderElection"))...) - if len(cc.SchedulerName) == 0 { - allErrs = append(allErrs, field.Required(field.NewPath("schedulerName"), "")) + allErrs = append(allErrs, validateKubeSchedulerLeaderElectionConfiguration(field.NewPath("leaderElection"), &cc.LeaderElection)...) + + profilesPath := field.NewPath("profiles") + if len(cc.Profiles) == 0 { + allErrs = append(allErrs, field.Required(profilesPath, "")) + } else { + existingProfiles := make(map[string]int, len(cc.Profiles)) + for i := range cc.Profiles { + profile := &cc.Profiles[i] + path := profilesPath.Index(i) + allErrs = append(allErrs, validateKubeSchedulerProfile(path, profile)...) + if idx, ok := existingProfiles[profile.SchedulerName]; ok { + allErrs = append(allErrs, field.Duplicate(path.Child("schedulerName"), profilesPath.Index(idx).Child("schedulerName"))) + } + existingProfiles[profile.SchedulerName] = i + } + allErrs = append(allErrs, validateCommonQueueSort(profilesPath, cc.Profiles)...) } for _, msg := range validation.IsValidSocketAddr(cc.HealthzBindAddress) { allErrs = append(allErrs, field.Invalid(field.NewPath("healthzBindAddress"), cc.HealthzBindAddress, msg)) @@ -59,13 +74,39 @@ func ValidateKubeSchedulerConfiguration(cc *config.KubeSchedulerConfiguration) f return allErrs } -// ValidateKubeSchedulerLeaderElectionConfiguration ensures validation of the KubeSchedulerLeaderElectionConfiguration struct -func ValidateKubeSchedulerLeaderElectionConfiguration(cc *config.KubeSchedulerLeaderElectionConfiguration, fldPath *field.Path) field.ErrorList { +func validateKubeSchedulerProfile(path *field.Path, profile *config.KubeSchedulerProfile) field.ErrorList { + allErrs := field.ErrorList{} + if len(profile.SchedulerName) == 0 { + allErrs = append(allErrs, field.Required(path.Child("schedulerName"), "")) + } + return allErrs +} + +func validateCommonQueueSort(path *field.Path, profiles []config.KubeSchedulerProfile) field.ErrorList { + allErrs := field.ErrorList{} + var canon *config.PluginSet + if profiles[0].Plugins != nil { + canon = profiles[0].Plugins.QueueSort + } + for i := 1; i < len(profiles); i++ { + var curr *config.PluginSet + if profiles[i].Plugins != nil { + curr = profiles[i].Plugins.QueueSort + } + if !cmp.Equal(canon, curr) { + allErrs = append(allErrs, field.Invalid(path.Index(i).Child("plugins", "queueSort"), curr, "has to match for all profiles")) + } + } + // TODO(#88093): Validate that all plugin configs for the queue sort extension match. + return allErrs +} + +func validateKubeSchedulerLeaderElectionConfiguration(fldPath *field.Path, cc *config.KubeSchedulerLeaderElectionConfiguration) field.ErrorList { allErrs := field.ErrorList{} if !cc.LeaderElectionConfiguration.LeaderElect { return allErrs } - allErrs = append(allErrs, componentbasevalidation.ValidateLeaderElectionConfiguration(&cc.LeaderElectionConfiguration, field.NewPath("leaderElectionConfiguration"))...) + allErrs = append(allErrs, componentbasevalidation.ValidateLeaderElectionConfiguration(&cc.LeaderElectionConfiguration, fldPath)...) return allErrs } diff --git a/pkg/scheduler/apis/config/validation/validation_test.go b/pkg/scheduler/apis/config/validation/validation_test.go index 006aeb3f14a..fff4c98891a 100644 --- a/pkg/scheduler/apis/config/validation/validation_test.go +++ b/pkg/scheduler/apis/config/validation/validation_test.go @@ -32,7 +32,6 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) { podInitialBackoffSeconds := int64(1) podMaxBackoffSeconds := int64(1) validConfig := &config.KubeSchedulerConfiguration{ - SchedulerName: "me", HealthzBindAddress: "0.0.0.0:10254", MetricsBindAddress: "0.0.0.0:10254", ClientConnection: componentbaseconfig.ClientConnectionConfiguration{ @@ -64,6 +63,30 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) { PodMaxBackoffSeconds: podMaxBackoffSeconds, BindTimeoutSeconds: testTimeout, PercentageOfNodesToScore: 35, + Profiles: []config.KubeSchedulerProfile{ + { + SchedulerName: "me", + Plugins: &config.Plugins{ + QueueSort: &config.PluginSet{ + Enabled: []config.Plugin{{Name: "CustomSort"}}, + }, + Score: &config.PluginSet{ + Disabled: []config.Plugin{{Name: "*"}}, + }, + }, + }, + { + SchedulerName: "other", + Plugins: &config.Plugins{ + QueueSort: &config.PluginSet{ + Enabled: []config.Plugin{{Name: "CustomSort"}}, + }, + Bind: &config.PluginSet{ + Enabled: []config.Plugin{{Name: "CustomBind"}}, + }, + }, + }, + }, } resourceNameNotSet := validConfig.DeepCopy() @@ -91,6 +114,18 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) { percentageOfNodesToScore101 := validConfig.DeepCopy() percentageOfNodesToScore101.PercentageOfNodesToScore = int32(101) + schedulerNameNotSet := validConfig.DeepCopy() + schedulerNameNotSet.Profiles[1].SchedulerName = "" + + repeatedSchedulerName := validConfig.DeepCopy() + repeatedSchedulerName.Profiles[0].SchedulerName = "other" + + differentQueueSort := validConfig.DeepCopy() + differentQueueSort.Profiles[1].Plugins.QueueSort.Enabled[0].Name = "AnotherSort" + + oneEmptyQueueSort := validConfig.DeepCopy() + oneEmptyQueueSort.Profiles[0].Plugins = nil + scenarios := map[string]struct { expectedToFail bool config *config.KubeSchedulerConfiguration @@ -127,16 +162,34 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) { expectedToFail: true, config: percentageOfNodesToScore101, }, + "scheduler-name-not-set": { + expectedToFail: true, + config: schedulerNameNotSet, + }, + "repeated-scheduler-name": { + expectedToFail: true, + config: repeatedSchedulerName, + }, + "different-queue-sort": { + expectedToFail: true, + config: differentQueueSort, + }, + "one-empty-queue-sort": { + expectedToFail: true, + config: oneEmptyQueueSort, + }, } for name, scenario := range scenarios { - errs := ValidateKubeSchedulerConfiguration(scenario.config) - if len(errs) == 0 && scenario.expectedToFail { - t.Errorf("Unexpected success for scenario: %s", name) - } - if len(errs) > 0 && !scenario.expectedToFail { - t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) - } + t.Run(name, func(t *testing.T) { + errs := ValidateKubeSchedulerConfiguration(scenario.config) + if len(errs) == 0 && scenario.expectedToFail { + t.Error("Unexpected success") + } + if len(errs) > 0 && !scenario.expectedToFail { + t.Errorf("Unexpected failure: %+v", errs) + } + }) } } diff --git a/pkg/scheduler/apis/config/zz_generated.deepcopy.go b/pkg/scheduler/apis/config/zz_generated.deepcopy.go index ce121d258cc..e6d8e104e71 100644 --- a/pkg/scheduler/apis/config/zz_generated.deepcopy.go +++ b/pkg/scheduler/apis/config/zz_generated.deepcopy.go @@ -105,14 +105,9 @@ func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfigurati out.LeaderElection = in.LeaderElection out.ClientConnection = in.ClientConnection out.DebuggingConfiguration = in.DebuggingConfiguration - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(Plugins) - (*in).DeepCopyInto(*out) - } - if in.PluginConfig != nil { - in, out := &in.PluginConfig, &out.PluginConfig - *out = make([]PluginConfig, len(*in)) + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]KubeSchedulerProfile, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -155,6 +150,34 @@ func (in *KubeSchedulerLeaderElectionConfiguration) DeepCopy() *KubeSchedulerLea return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeSchedulerProfile) DeepCopyInto(out *KubeSchedulerProfile) { + *out = *in + if in.Plugins != nil { + in, out := &in.Plugins, &out.Plugins + *out = new(Plugins) + (*in).DeepCopyInto(*out) + } + if in.PluginConfig != nil { + in, out := &in.PluginConfig, &out.PluginConfig + *out = make([]PluginConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeSchedulerProfile. +func (in *KubeSchedulerProfile) DeepCopy() *KubeSchedulerProfile { + if in == nil { + return nil + } + out := new(KubeSchedulerProfile) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LabelPreference) DeepCopyInto(out *LabelPreference) { *out = *in diff --git a/staging/src/k8s.io/kube-scheduler/config/v1alpha2/types.go b/staging/src/k8s.io/kube-scheduler/config/v1alpha2/types.go index c4e49170263..d6290eaa8f7 100644 --- a/staging/src/k8s.io/kube-scheduler/config/v1alpha2/types.go +++ b/staging/src/k8s.io/kube-scheduler/config/v1alpha2/types.go @@ -39,9 +39,6 @@ const ( type KubeSchedulerConfiguration struct { metav1.TypeMeta `json:",inline"` - // SchedulerName is name of the scheduler, used to select which pods - // will be processed by this scheduler, based on pod's "spec.SchedulerName". - SchedulerName *string `json:"schedulerName,omitempty"` // AlgorithmSource specifies the scheduler algorithm source. AlgorithmSource SchedulerAlgorithmSource `json:"algorithmSource"` @@ -90,15 +87,35 @@ type KubeSchedulerConfiguration struct { // the default value (10s) will be used. PodMaxBackoffSeconds *int64 `json:"podMaxBackoffSeconds"` - // Plugins specify the set of plugins that should be enabled or disabled. Enabled plugins are the - // ones that should be enabled in addition to the default plugins. Disabled plugins are any of the - // default plugins that should be disabled. - // When no enabled or disabled plugin is specified for an extension point, default plugins for - // that extension point will be used if there is any. + // Profiles are scheduling profiles that kube-scheduler supports. Pods can + // choose to be scheduled under a particular profile by setting its associated + // scheduler name. Pods that don't specify any scheduler name are scheduled + // with the "default-scheduler" profile, if present here. + // +listType=map + // +listMapKey=schedulerName + Profiles []KubeSchedulerProfile `json:"profiles"` +} + +// KubeSchedulerProfile is a scheduling profile. +type KubeSchedulerProfile struct { + // SchedulerName is the name of the scheduler associated to this profile. + // If SchedulerName matches with the pod's "spec.schedulerName", then the pod + // is scheduled with this profile. + SchedulerName *string `json:"schedulerName,omitempty"` + + // Plugins specify the set of plugins that should be enabled or disabled. + // Enabled plugins are the ones that should be enabled in addition to the + // default plugins. Disabled plugins are any of the default plugins that + // should be disabled. + // When no enabled or disabled plugin is specified for an extension point, + // default plugins for that extension point will be used if there is any. + // If a QueueSort plugin is specified, the same QueueSort Plugin and + // PluginConfig must be specified for all profiles. Plugins *Plugins `json:"plugins,omitempty"` // PluginConfig is an optional set of custom plugin arguments for each plugin. - // Omitting config args for a plugin is equivalent to using the default config for that plugin. + // Omitting config args for a plugin is equivalent to using the default config + // for that plugin. // +listType=map // +listMapKey=name PluginConfig []PluginConfig `json:"pluginConfig,omitempty"` diff --git a/staging/src/k8s.io/kube-scheduler/config/v1alpha2/zz_generated.deepcopy.go b/staging/src/k8s.io/kube-scheduler/config/v1alpha2/zz_generated.deepcopy.go index 4d2a5c27cac..54279359279 100644 --- a/staging/src/k8s.io/kube-scheduler/config/v1alpha2/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/kube-scheduler/config/v1alpha2/zz_generated.deepcopy.go @@ -28,11 +28,6 @@ import ( func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfiguration) { *out = *in out.TypeMeta = in.TypeMeta - if in.SchedulerName != nil { - in, out := &in.SchedulerName, &out.SchedulerName - *out = new(string) - **out = **in - } in.AlgorithmSource.DeepCopyInto(&out.AlgorithmSource) in.LeaderElection.DeepCopyInto(&out.LeaderElection) out.ClientConnection = in.ClientConnection @@ -72,14 +67,9 @@ func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfigurati *out = new(int64) **out = **in } - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(Plugins) - (*in).DeepCopyInto(*out) - } - if in.PluginConfig != nil { - in, out := &in.PluginConfig, &out.PluginConfig - *out = make([]PluginConfig, len(*in)) + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]KubeSchedulerProfile, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -122,6 +112,39 @@ func (in *KubeSchedulerLeaderElectionConfiguration) DeepCopy() *KubeSchedulerLea return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeSchedulerProfile) DeepCopyInto(out *KubeSchedulerProfile) { + *out = *in + if in.SchedulerName != nil { + in, out := &in.SchedulerName, &out.SchedulerName + *out = new(string) + **out = **in + } + if in.Plugins != nil { + in, out := &in.Plugins, &out.Plugins + *out = new(Plugins) + (*in).DeepCopyInto(*out) + } + if in.PluginConfig != nil { + in, out := &in.PluginConfig, &out.PluginConfig + *out = make([]PluginConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeSchedulerProfile. +func (in *KubeSchedulerProfile) DeepCopy() *KubeSchedulerProfile { + if in == nil { + return nil + } + out := new(KubeSchedulerProfile) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Plugin) DeepCopyInto(out *Plugin) { *out = *in