Change:
Kubernetes scheduler enables you to overwrite default Predicates/Priorities as well as configuring extenders in a "scheduler policy". In latest scheduler componentconfig API (v1alpha1), it can be a file or a configmap: However, if you defines a scheduler config file and specify a YAML policy file: It doesn't work. It's because only JSON is supported: It'd nice to enhance it with an UniversalSerilizer so as to support both JSON and YAML. /sig scheduling /help /priority important-longterm
This request has been marked as needing help from a contributor. Please ensure the request meets the requirements listed . If this request no longer meets these requirements, the label can be removed by commenting with the command. <detailsIn response to : Kubernetes scheduler enables you to overwrite default Predicates/Priorities as well as configuring extenders in a "scheduler policy". /help /priority important-longterm </details
/assign

Discussion:
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning:go_default_library", <ins> "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/yaml:go_default_library", </ins> ], )

"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer/json" "k8s.io/apimachinery/pkg/runtime/serializer/versioning" <ins> "k8s.io/apimachinery/pkg/runtime/serializer/yaml" </ins> schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" // Init the api v1 package _ "k8s.io/kubernetes/pkg/scheduler/api/v1"

func init() { jsonSerializer := json.NewSerializer(json.DefaultMetaFactory, schedulerapi.Scheme, schedulerapi.Scheme, true) <ins> serializer := yaml.NewDecodingSerializer(jsonSerializer) </ins> Codec = versioning.NewDefaultingCodecForScheme( schedulerapi.Scheme, <del> jsonSerializer, jsonSerializer, </del> <ins> serializer, serializer, </ins> schema.GroupVersion{Version: Version}, runtime.InternalGroupVersioner, )

import ( "errors" "fmt" <ins> "io/ioutil" "os" "path" </ins> "reflect" "testing" "time"

"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates" "k8s.io/kubernetes/pkg/scheduler/algorithm/priorities" "k8s.io/kubernetes/pkg/scheduler/api" <ins> schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" </ins> kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/core" "k8s.io/kubernetes/pkg/scheduler/factory"

}) } } <ins> func TestInitPolicyFromFile(t *testing.T) { dir, err := ioutil.TempDir(os.TempDir(), "policy") if err != nil { t.Errorf("unexpected error: %v", err) } defer os.RemoveAll(dir) for i, test := range []struct { policy               string expectedPredicates   sets.String expectedPrioritizers sets.String }{ // Test json format policy file { policy: `{ "kind" : "Policy", "apiVersion" : "v1", "predicates" : [ {"name" : "PredicateOne"}, {"name" : "PredicateTwo"} ], "priorities" : [ {"name" : "PriorityOne", "weight" : 1}, {"name" : "PriorityTwo", "weight" : 5} ] }`, expectedPredicates: sets.NewString( "PredicateOne", "PredicateTwo", ), expectedPrioritizers: sets.NewString( "PriorityOne", "PriorityTwo", ), }, // Test yaml format policy file { policy: `apiVersion: v1 kind: Policy predicates: - name: PredicateOne - name: PredicateTwo priorities: - name: PriorityOne weight: 1 - name: PriorityTwo weight: 5 `, expectedPredicates: sets.NewString( "PredicateOne", "PredicateTwo", ), expectedPrioritizers: sets.NewString( "PriorityOne", "PriorityTwo", ), }, } { file := fmt.Sprintf("scheduler-policy-config-file-%d", i) fullPath := path.Join(dir, file) if err := ioutil.WriteFile(fullPath, []byte(test.policy), 0644); err != nil { t.Fatalf("Failed writing a policy config file: %v", err) } policy := &schedulerapi.Policy{} if err := initPolicyFromFile(fullPath, policy); err != nil { t.Fatalf("Failed writing a policy config file: %v", err) } // Verify that the policy is initialized correctly. schedPredicates := sets.NewString() for _, p := range policy.Predicates { schedPredicates.Insert(p.Name) } schedPrioritizers := sets.NewString() for _, p := range policy.Priorities { schedPrioritizers.Insert(p.Name) } if !schedPredicates.Equal(test.expectedPredicates) { t.Errorf("Expected predicates %v, got %v", test.expectedPredicates, schedPredicates) } if !schedPrioritizers.Equal(test.expectedPrioritizers) { t.Errorf("Expected priority functions %v, got %v", test.expectedPrioritizers, schedPrioritizers) } } } </ins>

), expectedPrioritizers: sets.NewString(), }, <ins> { policy: `apiVersion: v1 kind: Policy predicates: - name: PredicateOne - name: PredicateTwo priorities: - name: PriorityOne weight: 1 - name: PriorityTwo weight: 5 `, expectedPredicates: sets.NewString( "CheckNodeCondition", // mandatory predicate "PredicateOne", "PredicateTwo", ), expectedPrioritizers: sets.NewString( "PriorityOne", "PriorityTwo", ), }, { policy: `apiVersion: v1 kind: Policy `, expectedPredicates: sets.NewString( "CheckNodeCondition", // mandatory predicate "CheckNodeDiskPressure", "CheckNodeMemoryPressure", "CheckNodePIDPressure", "CheckVolumeBinding", "GeneralPredicates", "MatchInterPodAffinity", "MaxAzureDiskVolumeCount", "MaxCSIVolumeCountPred", "MaxEBSVolumeCount", "MaxGCEPDVolumeCount", "NoDiskConflict", "NoVolumeZoneConflict", "PodToleratesNodeTaints", ), expectedPrioritizers: sets.NewString( "BalancedResourceAllocation", "InterPodAffinityPriority", "LeastRequestedPriority", "NodeAffinityPriority", "NodePreferAvoidPodsPriority", "SelectorSpreadPriority", "TaintTolerationPriority", "ImageLocalityPriority", ), }, { policy: `apiVersion: v1 kind: Policy predicates: [] priorities: [] `, expectedPredicates: sets.NewString( "CheckNodeCondition", // mandatory predicate ), expectedPrioritizers: sets.NewString(), }, </ins> } { // Add a ConfigMap object. configPolicyName := fmt.Sprintf("scheduler-custom-policy-config-%d", i)