Replace --init-config-dir with --config

pull/6/head
Michael Taufen 2017-12-25 20:39:10 -06:00
parent 980a5e80b1
commit 96f30d49dc
7 changed files with 33 additions and 36 deletions

View File

@ -101,11 +101,11 @@ type KubeletFlags struct {
// To use this flag, the DynamicKubeletConfig feature gate must be enabled.
DynamicConfigDir flag.StringFlag
// The Kubelet will look in this directory for an init configuration.
// The Kubelet will load its initial configuration from this file.
// The path may be absolute or relative; relative paths are under the Kubelet's current working directory.
// Omit this flag to use the combination of built-in default configuration values and flags.
// To use this flag, the KubeletConfigFile feature gate must be enabled.
InitConfigDir flag.StringFlag
KubeletConfigFile flag.StringFlag
// registerNode enables automatic registration with the apiserver.
RegisterNode bool
@ -229,9 +229,9 @@ func ValidateKubeletFlags(f *KubeletFlags) error {
if f.DynamicConfigDir.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) {
return fmt.Errorf("the DynamicKubeletConfig feature gate must be enabled in order to use the --dynamic-config-dir flag")
}
// ensure that nobody sets InitConfigDir if the KubeletConfigFile feature gate is turned off
if f.InitConfigDir.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.KubeletConfigFile) {
return fmt.Errorf("the KubeletConfigFile feature gate must be enabled in order to use the --init-config-dir flag")
// ensure that nobody sets KubeletConfigFile if the KubeletConfigFile feature gate is turned off
if f.KubeletConfigFile.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.KubeletConfigFile) {
return fmt.Errorf("the KubeletConfigFile feature gate must be enabled in order to use the --config flag")
}
return nil
}
@ -325,7 +325,7 @@ func (f *KubeletFlags) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&f.RootDirectory, "root-dir", f.RootDirectory, "Directory path for managing kubelet files (volume mounts,etc).")
fs.Var(&f.DynamicConfigDir, "dynamic-config-dir", "The Kubelet will use this directory for checkpointing downloaded configurations and tracking configuration health. The Kubelet will create this directory if it does not already exist. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Providing this flag enables dynamic Kubelet configuration. Presently, you must also enable the DynamicKubeletConfig feature gate to pass this flag.")
fs.Var(&f.InitConfigDir, "init-config-dir", "The Kubelet will look in this directory for the init configuration. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Omit this argument to use the built-in default configuration values. Presently, you must also enable the KubeletConfigFile feature gate to pass this flag.")
fs.Var(&f.KubeletConfigFile, "config", "The Kubelet will load its initial configuration from this file. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Omit this flag to use the built-in default configuration values. You must also enable the KubeletConfigFile feature gate to pass this flag.")
fs.BoolVar(&f.RegisterNode, "register-node", f.RegisterNode, "Register the node with the apiserver. If --kubeconfig is not provided, this flag is irrelevant, as the Kubelet won't have an apiserver to register with. Default=true.")
fs.Var(utiltaints.NewTaintsVar(&f.RegisterWithTaints), "register-with-taints", "Register the node with the given list of taints (comma separated \"<key>=<value>:<effect>\"). No-op if register-node is false.")

View File

@ -38,7 +38,7 @@ func newKubeletServerOrDie() *KubeletServer {
func cleanFlags(s *KubeletServer) {
s.KubeConfig = utilflag.NewStringFlag(s.KubeConfig.Value())
s.DynamicConfigDir = utilflag.NewStringFlag(s.DynamicConfigDir.Value())
s.InitConfigDir = utilflag.NewStringFlag(s.InitConfigDir.Value())
s.KubeletConfigFile = utilflag.NewStringFlag(s.KubeletConfigFile.Value())
}
// TestRoundTrip ensures that flag values from the Kubelet can be serialized

View File

@ -866,16 +866,16 @@ func parseResourceList(m map[string]string) (v1.ResourceList, error) {
// BootstrapKubeletConfigController constructs and bootstrap a configuration controller
func BootstrapKubeletConfigController(defaultConfig *kubeletconfiginternal.KubeletConfiguration,
initConfigDirFlag flag.StringFlag,
kubeletConfigFileFlag flag.StringFlag,
dynamicConfigDirFlag flag.StringFlag) (*kubeletconfiginternal.KubeletConfiguration, *kubeletconfig.Controller, error) {
var err error
// Alpha Dynamic Configuration Implementation; this section only loads config from disk, it does not contact the API server
// compute absolute paths based on current working dir
initConfigDir := ""
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletConfigFile) && initConfigDirFlag.Provided() {
initConfigDir, err = filepath.Abs(initConfigDirFlag.Value())
kubeletConfigFile := ""
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletConfigFile) && kubeletConfigFileFlag.Provided() {
kubeletConfigFile, err = filepath.Abs(kubeletConfigFileFlag.Value())
if err != nil {
return nil, nil, fmt.Errorf("failed to get absolute path for --init-config-dir")
return nil, nil, fmt.Errorf("failed to get absolute path for --config")
}
}
dynamicConfigDir := ""
@ -886,8 +886,8 @@ func BootstrapKubeletConfigController(defaultConfig *kubeletconfiginternal.Kubel
}
}
// get the latest KubeletConfiguration checkpoint from disk, or load the init or default config if no valid checkpoints exist
kubeletConfigController, err := kubeletconfig.NewController(defaultConfig, initConfigDir, dynamicConfigDir)
// get the latest KubeletConfiguration checkpoint from disk, or load the kubelet config file or default config if no valid checkpoints exist
kubeletConfigController, err := kubeletconfig.NewController(defaultConfig, kubeletConfigFile, dynamicConfigDir)
if err != nil {
return nil, nil, fmt.Errorf("failed to construct controller, error: %v", err)
}

View File

@ -75,7 +75,7 @@ func main() {
// bootstrap the kubelet config controller, app.BootstrapKubeletConfigController will check
// feature gates and only turn on relevant parts of the controller
kubeletConfig, kubeletConfigController, err := app.BootstrapKubeletConfigController(
defaultConfig, kubeletFlags.InitConfigDir, kubeletFlags.DynamicConfigDir)
defaultConfig, kubeletFlags.KubeletConfigFile, kubeletFlags.DynamicConfigDir)
if err != nil {
die(err)
}

View File

@ -27,8 +27,6 @@ import (
utilfs "k8s.io/kubernetes/pkg/util/filesystem"
)
const kubeletFile = "kubelet"
// Loader loads configuration from a storage layer
type Loader interface {
// Load loads and returns the KubeletConfiguration from the storage layer, or an error if a configuration could not be loaded
@ -41,12 +39,12 @@ type fsLoader struct {
fs utilfs.Filesystem
// kubeletCodecs is the scheme used to decode config files
kubeletCodecs *serializer.CodecFactory
// configDir is the absolute path to the directory containing the configuration files
configDir string
// kubeletFile is an absolute path to the file containing a serialized KubeletConfiguration
kubeletFile string
}
// NewFsLoader returns a Loader that loads a KubeletConfiguration from the files in `configDir`
func NewFsLoader(fs utilfs.Filesystem, configDir string) (Loader, error) {
// NewFsLoader returns a Loader that loads a KubeletConfiguration from the `kubeletFile`
func NewFsLoader(fs utilfs.Filesystem, kubeletFile string) (Loader, error) {
_, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
if err != nil {
return nil, err
@ -55,21 +53,19 @@ func NewFsLoader(fs utilfs.Filesystem, configDir string) (Loader, error) {
return &fsLoader{
fs: fs,
kubeletCodecs: kubeletCodecs,
configDir: configDir,
kubeletFile: kubeletFile,
}, nil
}
func (loader *fsLoader) Load() (*kubeletconfig.KubeletConfiguration, error) {
// require the config be in a file called "kubelet"
path := filepath.Join(loader.configDir, kubeletFile)
data, err := loader.fs.ReadFile(path)
data, err := loader.fs.ReadFile(loader.kubeletFile)
if err != nil {
return nil, fmt.Errorf("failed to read init config file %q, error: %v", path, err)
return nil, fmt.Errorf("failed to read kubelet config file %q, error: %v", loader.kubeletFile, err)
}
// no configuration is an error, some parameters are required
if len(data) == 0 {
return nil, fmt.Errorf("init config file %q was empty, but some parameters are required", path)
return nil, fmt.Errorf("kubelet config file %q was empty", loader.kubeletFile)
}
kc, err := utilcodec.DecodeKubeletConfiguration(loader.kubeletCodecs, data)
@ -78,7 +74,7 @@ func (loader *fsLoader) Load() (*kubeletconfig.KubeletConfiguration, error) {
}
// make all paths absolute
resolveRelativePaths(kubeletconfig.KubeletConfigurationPathRefs(kc), loader.configDir)
resolveRelativePaths(kubeletconfig.KubeletConfigurationPathRefs(kc), filepath.Dir(loader.kubeletFile))
return kc, nil
}

View File

@ -32,6 +32,7 @@ import (
const configDir = "/test-config-dir"
const relativePath = "relative/path/test"
const kubeletFile = "kubelet"
func TestLoad(t *testing.T) {
cases := []struct {
@ -136,12 +137,13 @@ podManifestPath: %s`, relativePath)),
for _, c := range cases {
t.Run(c.desc, func(t *testing.T) {
fs := utilfs.NewFakeFs()
path := filepath.Join(configDir, kubeletFile)
if c.file != nil {
if err := addFile(fs, filepath.Join(configDir, kubeletFile), *c.file); err != nil {
if err := addFile(fs, path, *c.file); err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
loader, err := NewFsLoader(fs, configDir)
loader, err := NewFsLoader(fs, path)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

View File

@ -40,7 +40,6 @@ import (
const (
checkpointsDir = "checkpoints"
initConfigDir = "init"
)
// Controller is the controller which, among other things:
@ -74,19 +73,19 @@ type Controller struct {
}
// NewController constructs a new Controller object and returns it. Directory paths must be absolute.
// If the `initConfigDir` is an empty string, skips trying to load the init config.
// If the `kubeletConfigFile` is an empty string, skips trying to load the kubelet config file.
// If the `dynamicConfigDir` is an empty string, skips trying to load checkpoints or download new config,
// but will still sync the ConfigOK condition if you call StartSync with a non-nil client.
func NewController(defaultConfig *kubeletconfig.KubeletConfiguration,
initConfigDir string,
kubeletConfigFile string,
dynamicConfigDir string) (*Controller, error) {
var err error
fs := utilfs.DefaultFs{}
var fileLoader configfiles.Loader
if len(initConfigDir) > 0 {
fileLoader, err = configfiles.NewFsLoader(fs, initConfigDir)
if len(kubeletConfigFile) > 0 {
fileLoader, err = configfiles.NewFsLoader(fs, kubeletConfigFile)
if err != nil {
return nil, err
}
@ -116,7 +115,7 @@ func (cc *Controller) Bootstrap() (*kubeletconfig.KubeletConfiguration, error) {
local, err := cc.loadLocalConfig()
if err != nil {
return nil, err
} // Assert: the default and init configs are both valid
} // Assert: the default and file configs are both valid
// if dynamic config is disabled, we just stop here
if !cc.dynamicConfig {