mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #88870 from alculquicondor/disallow_dup_plugin_config
Disallow duplicate PluginConfig in framework creation
This commit is contained in:
commit
b0f793a94c
@ -46,6 +46,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/listers/policy/v1beta1:go_default_library",
|
"//staging/src/k8s.io/client-go/listers/policy/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||||
|
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
|
||||||
"//vendor/k8s.io/klog:go_default_library",
|
"//vendor/k8s.io/klog:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -23,10 +23,12 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/fields"
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
@ -312,9 +314,10 @@ func (c *Configurator) createFromConfig(policy schedulerapi.Policy) (*Scheduler,
|
|||||||
})
|
})
|
||||||
defPlugins.Append(pluginsForPredicates)
|
defPlugins.Append(pluginsForPredicates)
|
||||||
defPlugins.Append(pluginsForPriorities)
|
defPlugins.Append(pluginsForPriorities)
|
||||||
var defPluginConfig []schedulerapi.PluginConfig
|
defPluginConfig, err := mergePluginConfigsFromPolicy(pluginConfigForPredicates, pluginConfigForPriorities)
|
||||||
defPluginConfig = append(defPluginConfig, pluginConfigForPredicates...)
|
if err != nil {
|
||||||
defPluginConfig = append(defPluginConfig, pluginConfigForPriorities...)
|
return nil, err
|
||||||
|
}
|
||||||
for i := range c.profiles {
|
for i := range c.profiles {
|
||||||
prof := &c.profiles[i]
|
prof := &c.profiles[i]
|
||||||
if prof.Plugins != nil {
|
if prof.Plugins != nil {
|
||||||
@ -332,6 +335,30 @@ func (c *Configurator) createFromConfig(policy schedulerapi.Policy) (*Scheduler,
|
|||||||
return c.create()
|
return c.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mergePluginConfigsFromPolicy merges the giving plugin configs ensuring that,
|
||||||
|
// if a plugin name is repeated, the arguments are the same.
|
||||||
|
func mergePluginConfigsFromPolicy(pc1, pc2 []schedulerapi.PluginConfig) ([]schedulerapi.PluginConfig, error) {
|
||||||
|
args := make(map[string]runtime.Unknown)
|
||||||
|
for _, c := range pc1 {
|
||||||
|
args[c.Name] = c.Args
|
||||||
|
}
|
||||||
|
for _, c := range pc2 {
|
||||||
|
if v, ok := args[c.Name]; ok && !cmp.Equal(v, c.Args) {
|
||||||
|
// This should be unreachable.
|
||||||
|
return nil, fmt.Errorf("inconsistent configuration produced for plugin %s", c.Name)
|
||||||
|
}
|
||||||
|
args[c.Name] = c.Args
|
||||||
|
}
|
||||||
|
pc := make([]schedulerapi.PluginConfig, 0, len(args))
|
||||||
|
for k, v := range args {
|
||||||
|
pc = append(pc, schedulerapi.PluginConfig{
|
||||||
|
Name: k,
|
||||||
|
Args: v,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return pc, nil
|
||||||
|
}
|
||||||
|
|
||||||
// getPriorityConfigs returns priorities configuration: ones that will run as priorities and ones that will run
|
// getPriorityConfigs returns priorities configuration: ones that will run as priorities and ones that will run
|
||||||
// as framework plugins. Specifically, a priority will run as a framework plugin if a plugin config producer was
|
// as framework plugins. Specifically, a priority will run as a framework plugin if a plugin config producer was
|
||||||
// registered for that priority.
|
// registered for that priority.
|
||||||
|
@ -202,7 +202,11 @@ func NewFramework(r Registry, plugins *config.Plugins, args []config.PluginConfi
|
|||||||
|
|
||||||
pluginConfig := make(map[string]*runtime.Unknown, 0)
|
pluginConfig := make(map[string]*runtime.Unknown, 0)
|
||||||
for i := range args {
|
for i := range args {
|
||||||
pluginConfig[args[i].Name] = &args[i].Args
|
name := args[i].Name
|
||||||
|
if _, ok := pluginConfig[name]; ok {
|
||||||
|
return nil, fmt.Errorf("repeated config for plugin %s", name)
|
||||||
|
}
|
||||||
|
pluginConfig[name] = &args[i].Args
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginsMap := make(map[string]Plugin)
|
pluginsMap := make(map[string]Plugin)
|
||||||
|
@ -410,25 +410,52 @@ func TestInitFrameworkWithScorePlugins(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRegisterDuplicatePluginWouldFail(t *testing.T) {
|
func TestNewFrameworkErrors(t *testing.T) {
|
||||||
plugin := config.Plugin{Name: duplicatePluginName, Weight: 1}
|
tests := []struct {
|
||||||
|
name string
|
||||||
pluginSet := config.PluginSet{
|
plugins *config.Plugins
|
||||||
Enabled: []config.Plugin{
|
pluginCfg []config.PluginConfig
|
||||||
plugin,
|
wantErr string
|
||||||
plugin,
|
}{
|
||||||
|
{
|
||||||
|
name: "duplicate plugin name",
|
||||||
|
plugins: &config.Plugins{
|
||||||
|
PreFilter: &config.PluginSet{
|
||||||
|
Enabled: []config.Plugin{
|
||||||
|
{Name: duplicatePluginName, Weight: 1},
|
||||||
|
{Name: duplicatePluginName, Weight: 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pluginCfg: []config.PluginConfig{
|
||||||
|
{Name: duplicatePluginName},
|
||||||
|
},
|
||||||
|
wantErr: "already registered",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "duplicate plugin config",
|
||||||
|
plugins: &config.Plugins{
|
||||||
|
PreFilter: &config.PluginSet{
|
||||||
|
Enabled: []config.Plugin{
|
||||||
|
{Name: duplicatePluginName, Weight: 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pluginCfg: []config.PluginConfig{
|
||||||
|
{Name: duplicatePluginName},
|
||||||
|
{Name: duplicatePluginName},
|
||||||
|
},
|
||||||
|
wantErr: "repeated config for plugin",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
plugins := config.Plugins{}
|
|
||||||
plugins.PreFilter = &pluginSet
|
|
||||||
|
|
||||||
_, err := NewFramework(registry, &plugins, emptyArgs)
|
for _, tc := range tests {
|
||||||
if err == nil {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Fatal("Framework initialization should fail")
|
_, err := NewFramework(registry, tc.plugins, tc.pluginCfg)
|
||||||
}
|
if err == nil || !strings.Contains(err.Error(), tc.wantErr) {
|
||||||
|
t.Errorf("Unexpected error, got %v, expect: %s", err, tc.wantErr)
|
||||||
if err != nil && !strings.Contains(err.Error(), "already registered") {
|
}
|
||||||
t.Fatalf("Unexpected error, got %s, expect: plugin already registered", err.Error())
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user