mirror of
https://github.com/kubernetes-sigs/descheduler.git
synced 2026-01-28 06:29:29 +01:00
use plugin registry and prepare for conversion (#1003)
* use plugin registry and prepare for conersion * Register plugins explicitly to a registry * check interface impl instead of struc var * setup plugins at top level * treat plugin type combinations * pass registry as arg of V1alpha1ToInternal * move registry yet another level up * check interface type separately
This commit is contained in:
committed by
GitHub
parent
6e953b2ff3
commit
da8b145980
@@ -20,6 +20,7 @@ package app
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
@@ -112,3 +113,8 @@ func NewDeschedulerCommand(out io.Writer) *cobra.Command {
|
|||||||
func Run(ctx context.Context, rs *options.DeschedulerServer) error {
|
func Run(ctx context.Context, rs *options.DeschedulerServer) error {
|
||||||
return descheduler.Run(ctx, rs)
|
return descheduler.Run(ctx, rs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetupLogs() {
|
||||||
|
klog.SetOutput(os.Stdout)
|
||||||
|
klog.InitFlags(nil)
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"k8s.io/component-base/cli"
|
"k8s.io/component-base/cli"
|
||||||
"k8s.io/klog/v2"
|
|
||||||
"sigs.k8s.io/descheduler/cmd/descheduler/app"
|
"sigs.k8s.io/descheduler/cmd/descheduler/app"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/descheduler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
klog.SetOutput(os.Stdout)
|
app.SetupLogs()
|
||||||
klog.InitFlags(nil)
|
descheduler.SetupPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import (
|
|||||||
podutil "sigs.k8s.io/descheduler/pkg/descheduler/pod"
|
podutil "sigs.k8s.io/descheduler/pkg/descheduler/pod"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework"
|
"sigs.k8s.io/descheduler/pkg/framework"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/pluginbuilder"
|
||||||
"sigs.k8s.io/descheduler/pkg/utils"
|
"sigs.k8s.io/descheduler/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ func Run(ctx context.Context, rs *options.DeschedulerServer) error {
|
|||||||
rs.Client = rsclient
|
rs.Client = rsclient
|
||||||
rs.EventClient = eventClient
|
rs.EventClient = eventClient
|
||||||
|
|
||||||
deschedulerPolicy, err := LoadPolicyConfig(rs.PolicyConfigFile, rs.Client)
|
deschedulerPolicy, err := LoadPolicyConfig(rs.PolicyConfigFile, rs.Client, pluginbuilder.PluginRegistry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -357,11 +358,15 @@ func RunDeschedulerStrategies(ctx context.Context, rs *options.DeschedulerServer
|
|||||||
klog.ErrorS(fmt.Errorf("unable to get plugin config"), "skipping plugin", "plugin", plugin)
|
klog.ErrorS(fmt.Errorf("unable to get plugin config"), "skipping plugin", "plugin", plugin)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pgFnc, ok := pluginsMap[plugin]
|
registryPlugin, ok := pluginbuilder.PluginRegistry[plugin]
|
||||||
|
pgFnc := registryPlugin.PluginBuilder
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.ErrorS(fmt.Errorf("unable to find plugin in the pluginsMap"), "skipping plugin", "plugin", plugin)
|
klog.ErrorS(fmt.Errorf("unable to find plugin in the pluginsMap"), "skipping plugin", "plugin", plugin)
|
||||||
}
|
}
|
||||||
pg := pgFnc(pc.Args, handle)
|
pg, err := pgFnc(pc.Args, handle)
|
||||||
|
if err != nil {
|
||||||
|
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", plugin)
|
||||||
|
}
|
||||||
if pg != nil {
|
if pg != nil {
|
||||||
switch v := pg.(type) {
|
switch v := pg.(type) {
|
||||||
case framework.DeschedulePlugin:
|
case framework.DeschedulePlugin:
|
||||||
|
|||||||
@@ -15,10 +15,15 @@ import (
|
|||||||
"sigs.k8s.io/descheduler/cmd/descheduler/app/options"
|
"sigs.k8s.io/descheduler/cmd/descheduler/app/options"
|
||||||
"sigs.k8s.io/descheduler/pkg/api"
|
"sigs.k8s.io/descheduler/pkg/api"
|
||||||
"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
|
"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/pluginbuilder"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removeduplicates"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodsviolatingnodetaints"
|
||||||
"sigs.k8s.io/descheduler/test"
|
"sigs.k8s.io/descheduler/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTaintsUpdated(t *testing.T) {
|
func TestTaintsUpdated(t *testing.T) {
|
||||||
|
pluginbuilder.PluginRegistry = pluginbuilder.NewRegistry()
|
||||||
|
pluginbuilder.Register(removepodsviolatingnodetaints.PluginName, removepodsviolatingnodetaints.New, &removepodsviolatingnodetaints.RemovePodsViolatingNodeTaintsArgs{}, pluginbuilder.PluginRegistry)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n1 := test.BuildTestNode("n1", 2000, 3000, 10, nil)
|
n1 := test.BuildTestNode("n1", 2000, 3000, 10, nil)
|
||||||
n2 := test.BuildTestNode("n2", 2000, 3000, 10, nil)
|
n2 := test.BuildTestNode("n2", 2000, 3000, 10, nil)
|
||||||
@@ -69,7 +74,7 @@ func TestTaintsUpdated(t *testing.T) {
|
|||||||
var evictedPods []string
|
var evictedPods []string
|
||||||
client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods))
|
client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods))
|
||||||
|
|
||||||
internalDeschedulerPolicy, err := V1alpha1ToInternal(client, dp)
|
internalDeschedulerPolicy, err := V1alpha1ToInternal(client, dp, pluginbuilder.PluginRegistry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to convert v1alpha1 to v1alpha2: %v", err)
|
t.Fatalf("Unable to convert v1alpha1 to v1alpha2: %v", err)
|
||||||
}
|
}
|
||||||
@@ -84,6 +89,8 @@ func TestTaintsUpdated(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDuplicate(t *testing.T) {
|
func TestDuplicate(t *testing.T) {
|
||||||
|
pluginbuilder.PluginRegistry = pluginbuilder.NewRegistry()
|
||||||
|
pluginbuilder.Register(removeduplicates.PluginName, removeduplicates.New, &removeduplicates.RemoveDuplicatesArgs{}, pluginbuilder.PluginRegistry)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
node1 := test.BuildTestNode("n1", 2000, 3000, 10, nil)
|
node1 := test.BuildTestNode("n1", 2000, 3000, 10, nil)
|
||||||
node2 := test.BuildTestNode("n2", 2000, 3000, 10, nil)
|
node2 := test.BuildTestNode("n2", 2000, 3000, 10, nil)
|
||||||
@@ -129,7 +136,7 @@ func TestDuplicate(t *testing.T) {
|
|||||||
var evictedPods []string
|
var evictedPods []string
|
||||||
client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods))
|
client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods))
|
||||||
|
|
||||||
internalDeschedulerPolicy, err := V1alpha1ToInternal(client, dp)
|
internalDeschedulerPolicy, err := V1alpha1ToInternal(client, dp, pluginbuilder.PluginRegistry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to convert v1alpha1 to v1alpha2: %v", err)
|
t.Fatalf("Unable to convert v1alpha1 to v1alpha2: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,11 +28,13 @@ import (
|
|||||||
"sigs.k8s.io/descheduler/pkg/api"
|
"sigs.k8s.io/descheduler/pkg/api"
|
||||||
"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
|
"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
|
||||||
"sigs.k8s.io/descheduler/pkg/descheduler/scheme"
|
"sigs.k8s.io/descheduler/pkg/descheduler/scheme"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/pluginbuilder"
|
||||||
"sigs.k8s.io/descheduler/pkg/utils"
|
"sigs.k8s.io/descheduler/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadPolicyConfig(policyConfigFile string, client clientset.Interface) (*api.DeschedulerPolicy, error) {
|
func LoadPolicyConfig(policyConfigFile string, client clientset.Interface, registry pluginbuilder.Registry) (*api.DeschedulerPolicy, error) {
|
||||||
if policyConfigFile == "" {
|
if policyConfigFile == "" {
|
||||||
klog.V(1).InfoS("Policy config file not specified")
|
klog.V(1).InfoS("Policy config file not specified")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -51,8 +53,7 @@ func LoadPolicyConfig(policyConfigFile string, client clientset.Interface) (*api
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build profiles
|
// Build profiles
|
||||||
// TODO(jchaloup): replace this with v1alpha1 -> v1alpha2 conversion
|
internalPolicy, err := V1alpha1ToInternal(client, versionedPolicy, registry)
|
||||||
internalPolicy, err := V1alpha1ToInternal(client, versionedPolicy)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed converting versioned policy to internal policy version: %v", err)
|
return nil, fmt.Errorf("failed converting versioned policy to internal policy version: %v", err)
|
||||||
}
|
}
|
||||||
@@ -63,20 +64,8 @@ func LoadPolicyConfig(policyConfigFile string, client clientset.Interface) (*api
|
|||||||
func V1alpha1ToInternal(
|
func V1alpha1ToInternal(
|
||||||
client clientset.Interface,
|
client clientset.Interface,
|
||||||
deschedulerPolicy *v1alpha1.DeschedulerPolicy,
|
deschedulerPolicy *v1alpha1.DeschedulerPolicy,
|
||||||
|
registry pluginbuilder.Registry,
|
||||||
) (*api.DeschedulerPolicy, error) {
|
) (*api.DeschedulerPolicy, error) {
|
||||||
validStrategyNames := map[v1alpha1.StrategyName]interface{}{
|
|
||||||
"RemoveDuplicates": nil,
|
|
||||||
"LowNodeUtilization": nil,
|
|
||||||
"HighNodeUtilization": nil,
|
|
||||||
"RemovePodsViolatingInterPodAntiAffinity": nil,
|
|
||||||
"RemovePodsViolatingNodeAffinity": nil,
|
|
||||||
"RemovePodsViolatingNodeTaints": nil,
|
|
||||||
"RemovePodsHavingTooManyRestarts": nil,
|
|
||||||
"PodLifeTime": nil,
|
|
||||||
"RemovePodsViolatingTopologySpreadConstraint": nil,
|
|
||||||
"RemoveFailedPods": nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
var evictLocalStoragePods bool
|
var evictLocalStoragePods bool
|
||||||
if deschedulerPolicy.EvictLocalStoragePods != nil {
|
if deschedulerPolicy.EvictLocalStoragePods != nil {
|
||||||
evictLocalStoragePods = *deschedulerPolicy.EvictLocalStoragePods
|
evictLocalStoragePods = *deschedulerPolicy.EvictLocalStoragePods
|
||||||
@@ -107,7 +96,7 @@ func V1alpha1ToInternal(
|
|||||||
|
|
||||||
// Build profiles
|
// Build profiles
|
||||||
for name, strategy := range deschedulerPolicy.Strategies {
|
for name, strategy := range deschedulerPolicy.Strategies {
|
||||||
if _, ok := validStrategyNames[name]; ok {
|
if _, ok := pluginbuilder.PluginRegistry[string(name)]; ok {
|
||||||
if strategy.Enabled {
|
if strategy.Enabled {
|
||||||
params := strategy.Params
|
params := strategy.Params
|
||||||
if params == nil {
|
if params == nil {
|
||||||
@@ -175,13 +164,16 @@ func V1alpha1ToInternal(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugins have either of the two extension points
|
pluginArgs := registry[string(name)].PluginArgInstance
|
||||||
switch pluginToExtensionPoint[pluginConfig.Name] {
|
pluginInstance, err := registry[string(name)].PluginBuilder(pluginArgs, &handleImpl{})
|
||||||
case descheduleEP:
|
if err != nil {
|
||||||
profile.Plugins.Deschedule.Enabled = []string{pluginConfig.Name}
|
klog.ErrorS(fmt.Errorf("could not build plugin"), "plugin build error", "plugin", name)
|
||||||
case balanceEP:
|
return nil, fmt.Errorf("could not build plugin: %v", name)
|
||||||
profile.Plugins.Balance.Enabled = []string{pluginConfig.Name}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pluginInstance can be of any of each type, or both
|
||||||
|
profilePlugins := profile.Plugins
|
||||||
|
profile.Plugins = enableProfilePluginsByType(profilePlugins, pluginInstance, pluginConfig)
|
||||||
profiles = append(profiles, profile)
|
profiles = append(profiles, profile)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -197,3 +189,27 @@ func V1alpha1ToInternal(
|
|||||||
MaxNoOfPodsToEvictPerNamespace: deschedulerPolicy.MaxNoOfPodsToEvictPerNamespace,
|
MaxNoOfPodsToEvictPerNamespace: deschedulerPolicy.MaxNoOfPodsToEvictPerNamespace,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enableProfilePluginsByType(profilePlugins api.Plugins, pluginInstance framework.Plugin, pluginConfig *api.PluginConfig) api.Plugins {
|
||||||
|
profilePlugins = checkBalance(profilePlugins, pluginInstance, pluginConfig)
|
||||||
|
profilePlugins = checkDeschedule(profilePlugins, pluginInstance, pluginConfig)
|
||||||
|
return profilePlugins
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkBalance(profilePlugins api.Plugins, pluginInstance framework.Plugin, pluginConfig *api.PluginConfig) api.Plugins {
|
||||||
|
switch p := pluginInstance.(type) {
|
||||||
|
case framework.BalancePlugin:
|
||||||
|
klog.V(3).Info("converting Balance plugin: %s", p.Name())
|
||||||
|
profilePlugins.Balance.Enabled = []string{pluginConfig.Name}
|
||||||
|
}
|
||||||
|
return profilePlugins
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDeschedule(profilePlugins api.Plugins, pluginInstance framework.Plugin, pluginConfig *api.PluginConfig) api.Plugins {
|
||||||
|
switch p := pluginInstance.(type) {
|
||||||
|
case framework.DeschedulePlugin:
|
||||||
|
klog.V(3).Info("converting Deschedule plugin: %s", p.Name())
|
||||||
|
profilePlugins.Deschedule.Enabled = []string{pluginConfig.Name}
|
||||||
|
}
|
||||||
|
return profilePlugins
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
|
"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/pluginbuilder"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/removeduplicates"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removeduplicates"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/removefailedpods"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removefailedpods"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodshavingtoomanyrestarts"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodshavingtoomanyrestarts"
|
||||||
@@ -38,6 +39,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestV1alpha1ToV1alpha2(t *testing.T) {
|
func TestV1alpha1ToV1alpha2(t *testing.T) {
|
||||||
|
SetupPlugins()
|
||||||
defaultEvictorPluginConfig := api.PluginConfig{
|
defaultEvictorPluginConfig := api.PluginConfig{
|
||||||
Name: defaultevictor.PluginName,
|
Name: defaultevictor.PluginName,
|
||||||
Args: &defaultevictor.DefaultEvictorArgs{
|
Args: &defaultevictor.DefaultEvictorArgs{
|
||||||
@@ -680,7 +682,7 @@ func TestV1alpha1ToV1alpha2(t *testing.T) {
|
|||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
client := fakeclientset.NewSimpleClientset()
|
client := fakeclientset.NewSimpleClientset()
|
||||||
result, err := V1alpha1ToInternal(client, tc.policy)
|
result, err := V1alpha1ToInternal(client, tc.policy, pluginbuilder.PluginRegistry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err.Error() != tc.err.Error() {
|
if err.Error() != tc.err.Error() {
|
||||||
t.Errorf("unexpected error: %s", err.Error())
|
t.Errorf("unexpected error: %s", err.Error())
|
||||||
|
|||||||
50
pkg/descheduler/setupplugins.go
Normal file
50
pkg/descheduler/setupplugins.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package descheduler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/pluginbuilder"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/podlifetime"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removeduplicates"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removefailedpods"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodshavingtoomanyrestarts"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodsviolatingnodeaffinity"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodsviolatingnodetaints"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupPlugins() {
|
||||||
|
pluginbuilder.PluginRegistry = pluginbuilder.NewRegistry()
|
||||||
|
RegisterDefaultPlugins(pluginbuilder.PluginRegistry)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterDefaultPlugins(registry pluginbuilder.Registry) {
|
||||||
|
pluginbuilder.Register(defaultevictor.PluginName, defaultevictor.New, &defaultevictor.DefaultEvictorArgs{}, registry)
|
||||||
|
pluginbuilder.Register(nodeutilization.LowNodeUtilizationPluginName, nodeutilization.NewLowNodeUtilization, &nodeutilization.LowNodeUtilizationArgs{}, registry)
|
||||||
|
pluginbuilder.Register(nodeutilization.HighNodeUtilizationPluginName, nodeutilization.NewHighNodeUtilization, &nodeutilization.HighNodeUtilizationArgs{}, registry)
|
||||||
|
pluginbuilder.Register(podlifetime.PluginName, podlifetime.New, &podlifetime.PodLifeTimeArgs{}, registry)
|
||||||
|
pluginbuilder.Register(removeduplicates.PluginName, removeduplicates.New, &removeduplicates.RemoveDuplicatesArgs{}, registry)
|
||||||
|
pluginbuilder.Register(removefailedpods.PluginName, removefailedpods.New, &removefailedpods.RemoveFailedPodsArgs{}, registry)
|
||||||
|
pluginbuilder.Register(removepodshavingtoomanyrestarts.PluginName, removepodshavingtoomanyrestarts.New, &removepodshavingtoomanyrestarts.RemovePodsHavingTooManyRestartsArgs{}, registry)
|
||||||
|
pluginbuilder.Register(removepodsviolatinginterpodantiaffinity.PluginName, removepodsviolatinginterpodantiaffinity.New, &removepodsviolatinginterpodantiaffinity.RemovePodsViolatingInterPodAntiAffinityArgs{}, registry)
|
||||||
|
pluginbuilder.Register(removepodsviolatingnodeaffinity.PluginName, removepodsviolatingnodeaffinity.New, &removepodsviolatingnodeaffinity.RemovePodsViolatingNodeAffinityArgs{}, registry)
|
||||||
|
pluginbuilder.Register(removepodsviolatingnodetaints.PluginName, removepodsviolatingnodetaints.New, &removepodsviolatingnodetaints.RemovePodsViolatingNodeTaintsArgs{}, registry)
|
||||||
|
pluginbuilder.Register(removepodsviolatingtopologyspreadconstraint.PluginName, removepodsviolatingtopologyspreadconstraint.New, &removepodsviolatingtopologyspreadconstraint.RemovePodsViolatingTopologySpreadConstraintArgs{}, registry)
|
||||||
|
}
|
||||||
@@ -19,11 +19,9 @@ package descheduler
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"sigs.k8s.io/descheduler/pkg/api"
|
"sigs.k8s.io/descheduler/pkg/api"
|
||||||
"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
|
"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework"
|
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/podlifetime"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/podlifetime"
|
||||||
"sigs.k8s.io/descheduler/pkg/framework/plugins/removeduplicates"
|
"sigs.k8s.io/descheduler/pkg/framework/plugins/removeduplicates"
|
||||||
@@ -250,106 +248,3 @@ func v1alpha1ThresholdToInternal(thresholds v1alpha1.ResourceThresholds) api.Res
|
|||||||
}
|
}
|
||||||
return internal
|
return internal
|
||||||
}
|
}
|
||||||
|
|
||||||
type extensionPoint string
|
|
||||||
|
|
||||||
const (
|
|
||||||
descheduleEP extensionPoint = "deschedule"
|
|
||||||
balanceEP extensionPoint = "balance"
|
|
||||||
)
|
|
||||||
|
|
||||||
var pluginToExtensionPoint = map[string]extensionPoint{
|
|
||||||
removepodsviolatingnodetaints.PluginName: descheduleEP,
|
|
||||||
removefailedpods.PluginName: descheduleEP,
|
|
||||||
removepodsviolatingnodeaffinity.PluginName: descheduleEP,
|
|
||||||
removepodsviolatinginterpodantiaffinity.PluginName: descheduleEP,
|
|
||||||
removepodshavingtoomanyrestarts.PluginName: descheduleEP,
|
|
||||||
podlifetime.PluginName: descheduleEP,
|
|
||||||
removeduplicates.PluginName: balanceEP,
|
|
||||||
removepodsviolatingtopologyspreadconstraint.PluginName: balanceEP,
|
|
||||||
nodeutilization.HighNodeUtilizationPluginName: balanceEP,
|
|
||||||
nodeutilization.LowNodeUtilizationPluginName: balanceEP,
|
|
||||||
}
|
|
||||||
|
|
||||||
var pluginsMap = map[string]func(args runtime.Object, handle *handleImpl) framework.Plugin{
|
|
||||||
removepodsviolatingnodetaints.PluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := removepodsviolatingnodetaints.New(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", removepodsviolatingnodetaints.PluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
removefailedpods.PluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := removefailedpods.New(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", removefailedpods.PluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
removepodsviolatingnodeaffinity.PluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := removepodsviolatingnodeaffinity.New(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", removepodsviolatingnodeaffinity.PluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
removepodsviolatinginterpodantiaffinity.PluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := removepodsviolatinginterpodantiaffinity.New(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", removepodsviolatinginterpodantiaffinity.PluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
removepodshavingtoomanyrestarts.PluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := removepodshavingtoomanyrestarts.New(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", removepodshavingtoomanyrestarts.PluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
podlifetime.PluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := podlifetime.New(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", podlifetime.PluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
removeduplicates.PluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := removeduplicates.New(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", removeduplicates.PluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
removepodsviolatingtopologyspreadconstraint.PluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := removepodsviolatingtopologyspreadconstraint.New(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", removepodsviolatingtopologyspreadconstraint.PluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
nodeutilization.HighNodeUtilizationPluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := nodeutilization.NewHighNodeUtilization(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", nodeutilization.HighNodeUtilizationPluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
nodeutilization.LowNodeUtilizationPluginName: func(args runtime.Object, handle *handleImpl) framework.Plugin {
|
|
||||||
pg, err := nodeutilization.NewLowNodeUtilization(args, handle)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "unable to initialize a plugin", "pluginName", nodeutilization.LowNodeUtilizationPluginName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pg
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/errors"
|
"k8s.io/apimachinery/pkg/util/errors"
|
||||||
@@ -129,9 +130,13 @@ func New(args runtime.Object, handle framework.Handle) (framework.Plugin, error)
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if defaultEvictorArgs.LabelSelector != nil && !defaultEvictorArgs.LabelSelector.Empty() {
|
selector, err := metav1.LabelSelectorAsSelector(defaultEvictorArgs.LabelSelector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not get selector from label selector")
|
||||||
|
}
|
||||||
|
if defaultEvictorArgs.LabelSelector != nil && !selector.Empty() {
|
||||||
ev.constraints = append(ev.constraints, func(pod *v1.Pod) error {
|
ev.constraints = append(ev.constraints, func(pod *v1.Pod) error {
|
||||||
if !defaultEvictorArgs.LabelSelector.Matches(labels.Set(pod.Labels)) {
|
if !selector.Matches(labels.Set(pod.Labels)) {
|
||||||
return fmt.Errorf("pod labels do not match the labelSelector filter in the policy parameter")
|
return fmt.Errorf("pod labels do not match the labelSelector filter in the policy parameter")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ package defaultevictor
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
"sigs.k8s.io/descheduler/pkg/api"
|
"sigs.k8s.io/descheduler/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,14 +23,14 @@ import (
|
|||||||
|
|
||||||
// DefaultEvictorArgs holds arguments used to configure DefaultEvictor plugin.
|
// DefaultEvictorArgs holds arguments used to configure DefaultEvictor plugin.
|
||||||
type DefaultEvictorArgs struct {
|
type DefaultEvictorArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
NodeSelector string
|
NodeSelector string `json:"nodeSelector"`
|
||||||
EvictLocalStoragePods bool
|
EvictLocalStoragePods bool `json:"evictLocalStoragePods"`
|
||||||
EvictSystemCriticalPods bool
|
EvictSystemCriticalPods bool `json:"evictSystemCriticalPods"`
|
||||||
IgnorePvcPods bool
|
IgnorePvcPods bool `json:"ignorePvcPods"`
|
||||||
EvictFailedBarePods bool
|
EvictFailedBarePods bool `json:"evictFailedBarePods"`
|
||||||
LabelSelector labels.Selector
|
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||||
PriorityThreshold *api.PriorityThreshold
|
PriorityThreshold *api.PriorityThreshold `json:"priorityThreshold"`
|
||||||
NodeFit bool
|
NodeFit bool `json:"nodeFit"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ limitations under the License.
|
|||||||
package defaultevictor
|
package defaultevictor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
api "sigs.k8s.io/descheduler/pkg/api"
|
api "sigs.k8s.io/descheduler/pkg/api"
|
||||||
)
|
)
|
||||||
@@ -31,7 +32,9 @@ func (in *DefaultEvictorArgs) DeepCopyInto(out *DefaultEvictorArgs) {
|
|||||||
*out = *in
|
*out = *in
|
||||||
out.TypeMeta = in.TypeMeta
|
out.TypeMeta = in.TypeMeta
|
||||||
if in.LabelSelector != nil {
|
if in.LabelSelector != nil {
|
||||||
out.LabelSelector = in.LabelSelector.DeepCopySelector()
|
in, out := &in.LabelSelector, &out.LabelSelector
|
||||||
|
*out = new(v1.LabelSelector)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.PriorityThreshold != nil {
|
if in.PriorityThreshold != nil {
|
||||||
in, out := &in.PriorityThreshold, &out.PriorityThreshold
|
in, out := &in.PriorityThreshold, &out.PriorityThreshold
|
||||||
|
|||||||
@@ -22,28 +22,29 @@ import (
|
|||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
type LowNodeUtilizationArgs struct {
|
type LowNodeUtilizationArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
|
UseDeviationThresholds bool `json:"useDeviationThresholds"`
|
||||||
|
Thresholds api.ResourceThresholds `json:"thresholds"`
|
||||||
|
TargetThresholds api.ResourceThresholds `json:"targetThresholds"`
|
||||||
|
NumberOfNodes int `json:"numberOfNodes"`
|
||||||
|
|
||||||
UseDeviationThresholds bool
|
|
||||||
Thresholds api.ResourceThresholds
|
|
||||||
TargetThresholds api.ResourceThresholds
|
|
||||||
NumberOfNodes int
|
|
||||||
// Naming this one differently since namespaces are still
|
// Naming this one differently since namespaces are still
|
||||||
// considered while considering resoures used by pods
|
// considered while considering resoures used by pods
|
||||||
// but then filtered out before eviction
|
// but then filtered out before eviction
|
||||||
EvictableNamespaces *api.Namespaces
|
EvictableNamespaces *api.Namespaces `json:"evictableNamespaces"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
type HighNodeUtilizationArgs struct {
|
type HighNodeUtilizationArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Thresholds api.ResourceThresholds
|
Thresholds api.ResourceThresholds `json:"thresholds"`
|
||||||
NumberOfNodes int
|
NumberOfNodes int `json:"numberOfNodes"`
|
||||||
// Naming this one differently since namespaces are still
|
// Naming this one differently since namespaces are still
|
||||||
// considered while considering resoures used by pods
|
// considered while considering resoures used by pods
|
||||||
// but then filtered out before eviction
|
// but then filtered out before eviction
|
||||||
EvictableNamespaces *api.Namespaces
|
EvictableNamespaces *api.Namespaces `json:"evictableNamespaces"`
|
||||||
}
|
}
|
||||||
|
|||||||
48
pkg/framework/plugins/pluginbuilder/pluginbuilder.go
Normal file
48
pkg/framework/plugins/pluginbuilder/pluginbuilder.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 The Kubernetes Authors.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pluginbuilder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
"sigs.k8s.io/descheduler/pkg/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var PluginRegistry Registry
|
||||||
|
|
||||||
|
type PluginBuilderAndArgsInstance struct {
|
||||||
|
PluginBuilder PluginBuilder
|
||||||
|
// Just an example instance of this PluginArg so we can avoid having
|
||||||
|
// to deal with reflect Types
|
||||||
|
PluginArgInstance runtime.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginBuilder = func(args runtime.Object, handle framework.Handle) (framework.Plugin, error)
|
||||||
|
|
||||||
|
type Registry = map[string]PluginBuilderAndArgsInstance
|
||||||
|
|
||||||
|
func NewRegistry() Registry {
|
||||||
|
return Registry{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Register(name string, builderFunc PluginBuilder, exampleArg runtime.Object, registry Registry) {
|
||||||
|
if _, ok := registry[name]; ok {
|
||||||
|
klog.V(10).InfoS("Plugin already registered", "plugin", name)
|
||||||
|
} else {
|
||||||
|
registry[name] = PluginBuilderAndArgsInstance{
|
||||||
|
PluginBuilder: builderFunc,
|
||||||
|
PluginArgInstance: exampleArg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,10 +23,10 @@ import (
|
|||||||
|
|
||||||
// PodLifeTimeArgs holds arguments used to configure PodLifeTime plugin.
|
// PodLifeTimeArgs holds arguments used to configure PodLifeTime plugin.
|
||||||
type PodLifeTimeArgs struct {
|
type PodLifeTimeArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Namespaces *api.Namespaces
|
Namespaces *api.Namespaces `json:"namespaces"`
|
||||||
LabelSelector *metav1.LabelSelector
|
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||||
MaxPodLifeTimeSeconds *uint
|
MaxPodLifeTimeSeconds *uint `json:"maxPodLifeTimeSeconds"`
|
||||||
States []string
|
States []string `json:"states"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import (
|
|||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
type RemoveDuplicatesArgs struct {
|
type RemoveDuplicatesArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Namespaces *api.Namespaces
|
Namespaces *api.Namespaces `json:"namespaces"`
|
||||||
ExcludeOwnerKinds []string
|
ExcludeOwnerKinds []string `json:"excludeOwnerKinds"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ import (
|
|||||||
|
|
||||||
// RemoveFailedPodsArgs holds arguments used to configure RemoveFailedPods plugin.
|
// RemoveFailedPodsArgs holds arguments used to configure RemoveFailedPods plugin.
|
||||||
type RemoveFailedPodsArgs struct {
|
type RemoveFailedPodsArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Namespaces *api.Namespaces
|
Namespaces *api.Namespaces `json:"namespaces"`
|
||||||
LabelSelector *metav1.LabelSelector
|
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||||
ExcludeOwnerKinds []string
|
ExcludeOwnerKinds []string `json:"excludeOwnerKinds"`
|
||||||
MinPodLifetimeSeconds *uint
|
MinPodLifetimeSeconds *uint `json:"minPodLifetimeSeconds"`
|
||||||
Reasons []string
|
Reasons []string `json:"reasons"`
|
||||||
IncludingInitContainers bool
|
IncludingInitContainers bool `json:"includingInitContainers"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ import (
|
|||||||
|
|
||||||
// RemovePodsHavingTooManyRestartsArgs holds arguments used to configure RemovePodsHavingTooManyRestarts plugin.
|
// RemovePodsHavingTooManyRestartsArgs holds arguments used to configure RemovePodsHavingTooManyRestarts plugin.
|
||||||
type RemovePodsHavingTooManyRestartsArgs struct {
|
type RemovePodsHavingTooManyRestartsArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Namespaces *api.Namespaces
|
Namespaces *api.Namespaces `json:"namespaces"`
|
||||||
LabelSelector *metav1.LabelSelector
|
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||||
PodRestartThreshold int32
|
PodRestartThreshold int32 `json:"podRestartThreshold"`
|
||||||
IncludingInitContainers bool
|
IncludingInitContainers bool `json:"includingInitContainers"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ import (
|
|||||||
|
|
||||||
// RemovePodsViolatingInterPodAntiAffinity holds arguments used to configure RemovePodsViolatingInterPodAntiAffinity plugin.
|
// RemovePodsViolatingInterPodAntiAffinity holds arguments used to configure RemovePodsViolatingInterPodAntiAffinity plugin.
|
||||||
type RemovePodsViolatingInterPodAntiAffinityArgs struct {
|
type RemovePodsViolatingInterPodAntiAffinityArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Namespaces *api.Namespaces
|
Namespaces *api.Namespaces `json:"namespaces"`
|
||||||
LabelSelector *metav1.LabelSelector
|
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ import (
|
|||||||
|
|
||||||
// RemovePodsViolatingNodeAffinityArgs holds arguments used to configure RemovePodsViolatingNodeAffinity plugin.
|
// RemovePodsViolatingNodeAffinityArgs holds arguments used to configure RemovePodsViolatingNodeAffinity plugin.
|
||||||
type RemovePodsViolatingNodeAffinityArgs struct {
|
type RemovePodsViolatingNodeAffinityArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Namespaces *api.Namespaces
|
Namespaces *api.Namespaces `json:"namespaces"`
|
||||||
LabelSelector *metav1.LabelSelector
|
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||||
NodeAffinityType []string
|
NodeAffinityType []string `json:"nodeAffinityType"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ import (
|
|||||||
|
|
||||||
// RemovePodsViolatingNodeTaintsArgs holds arguments used to configure the RemovePodsViolatingNodeTaints plugin.
|
// RemovePodsViolatingNodeTaintsArgs holds arguments used to configure the RemovePodsViolatingNodeTaints plugin.
|
||||||
type RemovePodsViolatingNodeTaintsArgs struct {
|
type RemovePodsViolatingNodeTaintsArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Namespaces *api.Namespaces
|
Namespaces *api.Namespaces `json:"namespaces"`
|
||||||
LabelSelector *metav1.LabelSelector
|
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||||
IncludePreferNoSchedule bool
|
IncludePreferNoSchedule bool `json:"includePreferNoSchedule"`
|
||||||
ExcludedTaints []string
|
ExcludedTaints []string `json:"excludedTaints"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ import (
|
|||||||
|
|
||||||
// RemovePodsViolatingTopologySpreadConstraintArgs holds arguments used to configure RemovePodsViolatingTopologySpreadConstraint plugin.
|
// RemovePodsViolatingTopologySpreadConstraintArgs holds arguments used to configure RemovePodsViolatingTopologySpreadConstraint plugin.
|
||||||
type RemovePodsViolatingTopologySpreadConstraintArgs struct {
|
type RemovePodsViolatingTopologySpreadConstraintArgs struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
Namespaces *api.Namespaces
|
Namespaces *api.Namespaces `json:"namespaces"`
|
||||||
LabelSelector *metav1.LabelSelector
|
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||||
IncludeSoftConstraints bool
|
IncludeSoftConstraints bool `json:"includeSoftConstraints"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestLeaderElection(t *testing.T) {
|
func TestLeaderElection(t *testing.T) {
|
||||||
|
descheduler.SetupPlugins()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
clientSet, _, _, _, stopCh := initializeClient(t)
|
clientSet, _, _, _, stopCh := initializeClient(t)
|
||||||
|
|||||||
Reference in New Issue
Block a user