k8s.io/kubernetes@v1.29.3/pkg/kubelet/kubeletconfig/configfiles/configfiles.go (about) 1 /* 2 Copyright 2017 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 configfiles 18 19 import ( 20 "fmt" 21 "path/filepath" 22 23 "k8s.io/apimachinery/pkg/runtime/serializer" 24 kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" 25 kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/config/scheme" 26 utilcodec "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/codec" 27 utilfs "k8s.io/kubernetes/pkg/util/filesystem" 28 ) 29 30 // Loader loads configuration from a storage layer 31 type Loader interface { 32 // Load loads and returns the KubeletConfiguration from the storage layer, or an error if a configuration could not be loaded 33 Load() (*kubeletconfig.KubeletConfiguration, error) 34 // LoadIntoJSON loads and returns the KubeletConfiguration from the storage layer, or an error if a configuration could not be 35 // loaded. It returns the configuration as a JSON byte slice 36 LoadIntoJSON() ([]byte, error) 37 } 38 39 // fsLoader loads configuration from `configDir` 40 type fsLoader struct { 41 // fs is the filesystem where the config files exist; can be mocked for testing 42 fs utilfs.Filesystem 43 // kubeletCodecs is the scheme used to decode config files 44 kubeletCodecs *serializer.CodecFactory 45 // kubeletFile is an absolute path to the file containing a serialized KubeletConfiguration 46 kubeletFile string 47 } 48 49 // NewFsLoader returns a Loader that loads a KubeletConfiguration from the `kubeletFile` 50 func NewFsLoader(fs utilfs.Filesystem, kubeletFile string) (Loader, error) { 51 _, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs(serializer.EnableStrict) 52 if err != nil { 53 return nil, err 54 } 55 56 return &fsLoader{ 57 fs: fs, 58 kubeletCodecs: kubeletCodecs, 59 kubeletFile: kubeletFile, 60 }, nil 61 } 62 63 func (loader *fsLoader) Load() (*kubeletconfig.KubeletConfiguration, error) { 64 data, err := loader.fs.ReadFile(loader.kubeletFile) 65 if err != nil { 66 return nil, fmt.Errorf("failed to read kubelet config file %q, error: %v", loader.kubeletFile, err) 67 } 68 69 // no configuration is an error, some parameters are required 70 if len(data) == 0 { 71 return nil, fmt.Errorf("kubelet config file %q was empty", loader.kubeletFile) 72 } 73 74 kc, err := utilcodec.DecodeKubeletConfiguration(loader.kubeletCodecs, data) 75 if err != nil { 76 return nil, err 77 } 78 79 // make all paths absolute 80 resolveRelativePaths(kubeletconfig.KubeletConfigurationPathRefs(kc), filepath.Dir(loader.kubeletFile)) 81 return kc, nil 82 } 83 84 func (loader *fsLoader) LoadIntoJSON() ([]byte, error) { 85 data, err := loader.fs.ReadFile(loader.kubeletFile) 86 if err != nil { 87 return nil, fmt.Errorf("failed to read drop-in kubelet config file %q, error: %v", loader.kubeletFile, err) 88 } 89 90 // no configuration is an error, some parameters are required 91 if len(data) == 0 { 92 return nil, fmt.Errorf("kubelet config file %q was empty", loader.kubeletFile) 93 } 94 95 return utilcodec.DecodeKubeletConfigurationIntoJSON(loader.kubeletCodecs, data) 96 } 97 98 // resolveRelativePaths makes relative paths absolute by resolving them against `root` 99 func resolveRelativePaths(paths []*string, root string) { 100 for _, path := range paths { 101 // leave empty paths alone, "no path" is a valid input 102 // do not attempt to resolve paths that are already absolute 103 if len(*path) > 0 && !filepath.IsAbs(*path) { 104 *path = filepath.Join(root, *path) 105 } 106 } 107 }