k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kube-scheduler/app/options/configfile.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package options 18 19 import ( 20 "bytes" 21 "fmt" 22 "io" 23 "os" 24 25 "k8s.io/apimachinery/pkg/runtime" 26 "k8s.io/klog/v2" 27 "k8s.io/kubernetes/pkg/scheduler/apis/config" 28 "k8s.io/kubernetes/pkg/scheduler/apis/config/scheme" 29 configv1 "k8s.io/kubernetes/pkg/scheduler/apis/config/v1" 30 ) 31 32 // LoadConfigFromFile loads scheduler config from the specified file path 33 func LoadConfigFromFile(logger klog.Logger, file string) (*config.KubeSchedulerConfiguration, error) { 34 data, err := os.ReadFile(file) 35 if err != nil { 36 return nil, err 37 } 38 39 return loadConfig(logger, data) 40 } 41 42 func loadConfig(logger klog.Logger, data []byte) (*config.KubeSchedulerConfiguration, error) { 43 // The UniversalDecoder runs defaulting and returns the internal type by default. 44 obj, gvk, err := scheme.Codecs.UniversalDecoder().Decode(data, nil, nil) 45 if err != nil { 46 return nil, err 47 } 48 if cfgObj, ok := obj.(*config.KubeSchedulerConfiguration); ok { 49 // We don't set this field in pkg/scheduler/apis/config/{version}/conversion.go 50 // because the field will be cleared later by API machinery during 51 // conversion. See KubeSchedulerConfiguration internal type definition for 52 // more details. 53 cfgObj.TypeMeta.APIVersion = gvk.GroupVersion().String() 54 return cfgObj, nil 55 } 56 return nil, fmt.Errorf("couldn't decode as KubeSchedulerConfiguration, got %s: ", gvk) 57 } 58 59 func encodeConfig(cfg *config.KubeSchedulerConfiguration) (*bytes.Buffer, error) { 60 buf := new(bytes.Buffer) 61 const mediaType = runtime.ContentTypeYAML 62 info, ok := runtime.SerializerInfoForMediaType(scheme.Codecs.SupportedMediaTypes(), mediaType) 63 if !ok { 64 return buf, fmt.Errorf("unable to locate encoder -- %q is not a supported media type", mediaType) 65 } 66 67 var encoder runtime.Encoder 68 switch cfg.TypeMeta.APIVersion { 69 case configv1.SchemeGroupVersion.String(): 70 encoder = scheme.Codecs.EncoderForVersion(info.Serializer, configv1.SchemeGroupVersion) 71 default: 72 encoder = scheme.Codecs.EncoderForVersion(info.Serializer, configv1.SchemeGroupVersion) 73 } 74 if err := encoder.Encode(cfg, buf); err != nil { 75 return buf, err 76 } 77 return buf, nil 78 } 79 80 // LogOrWriteConfig logs the completed component config and writes it into the given file name as YAML, if either is enabled 81 func LogOrWriteConfig(logger klog.Logger, fileName string, cfg *config.KubeSchedulerConfiguration, completedProfiles []config.KubeSchedulerProfile) error { 82 loggerV := logger.V(2) 83 if !loggerV.Enabled() && len(fileName) == 0 { 84 return nil 85 } 86 cfg.Profiles = completedProfiles 87 88 buf, err := encodeConfig(cfg) 89 if err != nil { 90 return err 91 } 92 93 if loggerV.Enabled() { 94 loggerV.Info("Using component config", "config", buf.String()) 95 } 96 97 if len(fileName) > 0 { 98 configFile, err := os.Create(fileName) 99 if err != nil { 100 return err 101 } 102 defer configFile.Close() 103 if _, err := io.Copy(configFile, buf); err != nil { 104 return err 105 } 106 logger.Info("Wrote configuration", "file", fileName) 107 os.Exit(0) 108 } 109 return nil 110 }