Skip to content

Commit de9ac9f

Browse files
shmuelkkfswain
authored andcommitted
Add a set of configuration defaults (kubernetes-sigs#1223)
* If a picker wasn't specified, add one Signed-off-by: Shmuel Kallner <[email protected]> * If there is only one profile and a profile handler wasn't specified, add one Signed-off-by: Shmuel Kallner <[email protected]> * If there aren't any ScehdulingProfiles, add one Signed-off-by: Shmuel Kallner <[email protected]> * Updated and fixed tests Signed-off-by: Shmuel Kallner <[email protected]> * Updated the configuration guide Signed-off-by: Shmuel Kallner <[email protected]> * Don't hard code the default scorer weight Signed-off-by: Shmuel Kallner <[email protected]> * If a picker is missing, always add a MaxScorePicker Signed-off-by: Shmuel Kallner <[email protected]> --------- Signed-off-by: Shmuel Kallner <[email protected]>
1 parent e6617bf commit de9ac9f

File tree

5 files changed

+149
-95
lines changed

5 files changed

+149
-95
lines changed

apix/config/v1alpha1/defaults.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,27 @@ package v1alpha1
2121
//
2222
// This naming convension is required by the defalter-gen code.
2323
func SetDefaults_EndpointPickerConfig(cfg *EndpointPickerConfig) {
24+
// If no name was given for the plugin, use it's type as the name
2425
for idx, pluginConfig := range cfg.Plugins {
2526
if pluginConfig.Name == "" {
2627
cfg.Plugins[idx].Name = pluginConfig.Type
2728
}
2829
}
30+
31+
// If No SchedulerProfiles were specified in the confguration,
32+
// create one named default with references to all of the
33+
// plugins mentioned in the Plugins section of the configuration.
34+
if len(cfg.SchedulingProfiles) == 0 {
35+
cfg.SchedulingProfiles = make([]SchedulingProfile, 1)
36+
37+
thePlugins := []SchedulingPlugin{}
38+
for _, pluginConfig := range cfg.Plugins {
39+
thePlugins = append(thePlugins, SchedulingPlugin{PluginRef: pluginConfig.Name})
40+
}
41+
42+
cfg.SchedulingProfiles[0] = SchedulingProfile{
43+
Name: "default",
44+
Plugins: thePlugins,
45+
}
46+
}
2947
}

pkg/epp/common/config/defaults.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@ const (
2525
// DefaultQueueThresholdCritical is the default backend waiting queue size
2626
// threshold.
2727
DefaultQueueThresholdCritical = 5
28+
29+
// DefaultScorerWeight is the weight used for scorers referenced in the
30+
// configuration without explicit weights.
31+
DefaultScorerWeight = 1
2832
)

pkg/epp/common/config/loader/configloader.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ import (
2626
"k8s.io/apimachinery/pkg/util/sets"
2727

2828
configapi "sigs.k8s.io/gateway-api-inference-extension/apix/config/v1alpha1"
29+
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/common/config"
2930
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/plugins"
3031
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling"
3132
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework"
33+
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/picker"
34+
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/profile"
3235
)
3336

3437
var scheme = runtime.NewScheme()
@@ -64,18 +67,31 @@ func LoadSchedulerConfig(configProfiles []configapi.SchedulingProfile, handle pl
6467
profiles := map[string]*framework.SchedulerProfile{}
6568
for _, namedProfile := range configProfiles {
6669
profile := framework.NewSchedulerProfile()
70+
pickerAdded := false
6771
for _, plugin := range namedProfile.Plugins {
6872
referencedPlugin := handle.Plugin(plugin.PluginRef)
6973
if scorer, ok := referencedPlugin.(framework.Scorer); ok {
70-
if plugin.Weight == nil {
71-
return nil, fmt.Errorf("scorer '%s' is missing a weight", plugin.PluginRef)
74+
// Set default weight if one wasn't set in the configuration
75+
weight := config.DefaultScorerWeight
76+
if plugin.Weight != nil {
77+
weight = *plugin.Weight
7278
}
73-
referencedPlugin = framework.NewWeightedScorer(scorer, *plugin.Weight)
79+
referencedPlugin = framework.NewWeightedScorer(scorer, weight)
80+
}
81+
if _, ok := referencedPlugin.(framework.Picker); ok {
82+
pickerAdded = true
7483
}
7584
if err := profile.AddPlugins(referencedPlugin); err != nil {
7685
return nil, fmt.Errorf("failed to load scheduler config - %w", err)
7786
}
7887
}
88+
if !pickerAdded {
89+
// There isn't a picker in this profile, add one
90+
thePicker := picker.NewMaxScorePicker(picker.DefaultMaxNumOfEndpoints)
91+
if err := profile.AddPlugins(thePicker); err != nil {
92+
return nil, fmt.Errorf("failed to load scheduler config - %w", err)
93+
}
94+
}
7995
profiles[namedProfile.Name] = profile
8096
}
8197

@@ -89,7 +105,10 @@ func LoadSchedulerConfig(configProfiles []configapi.SchedulingProfile, handle pl
89105
}
90106
}
91107
if profileHandler == nil {
92-
return nil, errors.New("no profile handler was specified")
108+
if len(profiles) != 1 {
109+
return nil, errors.New("no profile handler was specified")
110+
}
111+
profileHandler = profile.NewSingleProfileHandler()
93112
}
94113

95114
return scheduling.NewSchedulerConfig(profileHandler, profiles), nil
@@ -125,10 +144,6 @@ func instantiatePlugins(configuredPlugins []configapi.PluginSpec, handle plugins
125144
}
126145

127146
func validateSchedulingProfiles(config *configapi.EndpointPickerConfig) error {
128-
if len(config.SchedulingProfiles) == 0 {
129-
return errors.New("there must be at least one scheduling profile in the configuration")
130-
}
131-
132147
profileNames := sets.New[string]()
133148
for _, profile := range config.SchedulingProfiles {
134149
if profile.Name == "" {

0 commit comments

Comments
 (0)