diff --git a/cmd/airgap/airgap.go b/cmd/airgap/airgap.go index 7f0cf19affa3..2f597edcaa42 100644 --- a/cmd/airgap/airgap.go +++ b/cmd/airgap/airgap.go @@ -29,6 +29,7 @@ func NewAirgapCmd() *cobra.Command { cmd.SilenceUsage = true cmd.AddCommand(NewAirgapListImagesCmd()) + cmd.PersistentFlags().AddFlagSet(config.FileInputFlag()) cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } diff --git a/cmd/airgap/listimages.go b/cmd/airgap/listimages.go index 9f501deb8417..398b00793bf5 100644 --- a/cmd/airgap/listimages.go +++ b/cmd/airgap/listimages.go @@ -44,6 +44,7 @@ func NewAirgapListImagesCmd() *cobra.Command { return nil }, } + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } diff --git a/cmd/api/api.go b/cmd/api/api.go index 26b992a63e47..571a3780dbea 100644 --- a/cmd/api/api.go +++ b/cmd/api/api.go @@ -72,6 +72,7 @@ func NewAPICmd() *cobra.Command { }, } cmd.SilenceUsage = true + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } diff --git a/cmd/backup/backup.go b/cmd/backup/backup.go index eabca14b1e91..b68b38d8a9fb 100644 --- a/cmd/backup/backup.go +++ b/cmd/backup/backup.go @@ -54,6 +54,7 @@ func NewBackupCmd() *cobra.Command { } cmd.Flags().StringVar(&savePath, "save-path", "", "destination directory path for backup assets") cmd.SilenceUsage = true + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } @@ -89,7 +90,7 @@ func (c *CmdOpts) backup() error { func preRunValidateConfig(cmd *cobra.Command, args []string) error { c := CmdOpts(config.GetCmdOpts()) - _, err := config.ValidateYaml(c.CfgFile, c.K0sVars) + _, err := config.GetConfigFromYAML(c.CfgFile, c.K0sVars) if err != nil { return err } diff --git a/cmd/config/validate.go b/cmd/config/validate.go index faaf0d3574de..d7ca7802d979 100644 --- a/cmd/config/validate.go +++ b/cmd/config/validate.go @@ -36,5 +36,6 @@ func NewValidateCmd() *cobra.Command { } cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + cmd.Flags().AddFlagSet(config.FileInputFlag()) return cmd } diff --git a/cmd/etcd/etcd.go b/cmd/etcd/etcd.go index 50b9fec1a9cd..e12fa156ea7a 100644 --- a/cmd/etcd/etcd.go +++ b/cmd/etcd/etcd.go @@ -46,6 +46,7 @@ func NewEtcdCmd() *cobra.Command { cmd.SilenceUsage = true cmd.AddCommand(etcdLeaveCmd()) cmd.AddCommand(etcdListCmd()) + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } diff --git a/cmd/etcd/leave.go b/cmd/etcd/leave.go index 32e26ce717a7..4e90033b204a 100644 --- a/cmd/etcd/leave.go +++ b/cmd/etcd/leave.go @@ -75,5 +75,6 @@ func etcdLeaveCmd() *cobra.Command { cmd.Flags().StringVar(&etcdPeerAddress, "peer-address", "", "etcd peer address") cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + cmd.Flags().AddFlagSet(config.FileInputFlag()) return cmd } diff --git a/cmd/etcd/list.go b/cmd/etcd/list.go index e85ac002c856..d66c387d7756 100644 --- a/cmd/etcd/list.go +++ b/cmd/etcd/list.go @@ -45,6 +45,7 @@ func etcdListCmd() *cobra.Command { return json.NewEncoder(os.Stdout).Encode(map[string]interface{}{"members": members}) }, } + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } diff --git a/cmd/install/install.go b/cmd/install/install.go index e7fcf6a01956..7ad8821a5586 100644 --- a/cmd/install/install.go +++ b/cmd/install/install.go @@ -22,7 +22,6 @@ import ( "github.com/spf13/cobra" - "github.com/k0sproject/k0s/internal/pkg/dir" "github.com/k0sproject/k0s/internal/pkg/file" "github.com/k0sproject/k0s/pkg/config" "github.com/k0sproject/k0s/pkg/install" @@ -50,10 +49,6 @@ func (c *CmdOpts) setup(role string, args []string) error { return fmt.Errorf("this command must be run as root") } - // if cfgFile is not provided k0s will handle this so no need to check if the file exists. - if c.CfgFile != "" && !dir.IsDirectory(c.CfgFile) && !file.Exists(c.CfgFile) { - return fmt.Errorf("file %s does not exist", c.CfgFile) - } if role == "controller" { cfg, err := config.GetNodeConfig(c.CfgFile, c.K0sVars) if err != nil { @@ -102,7 +97,7 @@ func (c *CmdOpts) convertFileParamsToAbsolute() (err error) { func preRunValidateConfig(_ *cobra.Command, _ []string) error { c := CmdOpts(config.GetCmdOpts()) - _, err := config.ValidateYaml(c.CfgFile, c.K0sVars) + _, err := config.GetConfigFromYAML(c.CfgFile, c.K0sVars) if err != nil { return err } diff --git a/cmd/kubeconfig/create.go b/cmd/kubeconfig/create.go index 4548b6f32b0c..5aeabf0b953b 100644 --- a/cmd/kubeconfig/create.go +++ b/cmd/kubeconfig/create.go @@ -130,6 +130,7 @@ Note: A certificate once signed cannot be revoked for a particular user`, }, } cmd.Flags().StringVar(&groups, "groups", "", "Specify groups") + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } @@ -137,7 +138,6 @@ Note: A certificate once signed cannot be revoked for a particular user`, func (c *CmdOpts) getAPIURL() (string, error) { // Disable logrus logrus.SetLevel(logrus.WarnLevel) - cfg, err := config.GetNodeConfig(c.CfgFile, c.K0sVars) if err != nil { return "", err diff --git a/cmd/reset/reset.go b/cmd/reset/reset.go index 7e288f54f73a..4096d4658ea3 100644 --- a/cmd/reset/reset.go +++ b/cmd/reset/reset.go @@ -46,6 +46,7 @@ func NewResetCmd() *cobra.Command { cmd.SilenceUsage = true cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) cmd.Flags().AddFlagSet(config.GetCriSocketFlag()) + cmd.Flags().AddFlagSet(config.FileInputFlag()) return cmd } @@ -74,7 +75,7 @@ func (c *CmdOpts) reset() error { func preRunValidateConfig(_ *cobra.Command, _ []string) error { c := CmdOpts(config.GetCmdOpts()) - _, err := config.ValidateYaml(c.CfgFile, c.K0sVars) + _, err := config.GetConfigFromYAML(c.CfgFile, c.K0sVars) if err != nil { return err } diff --git a/cmd/restore/restore.go b/cmd/restore/restore.go index f5909d9548b7..7f8be26da584 100644 --- a/cmd/restore/restore.go +++ b/cmd/restore/restore.go @@ -56,6 +56,7 @@ func NewRestoreCmd() *cobra.Command { cmd.SilenceUsage = true cmd.Flags().StringVar(&restoredConfigPath, "config-out", "", "Specify desired name and full path for the restored k0s.yaml file (default: ${cwd}/k0s_.yaml)") + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } @@ -95,7 +96,7 @@ func (c *CmdOpts) restore(path string) error { // TODO Need to move to some common place, now it's defined in restore and backup commands func preRunValidateConfig(_ *cobra.Command, _ []string) error { c := CmdOpts(config.GetCmdOpts()) - _, err := config.ValidateYaml(c.CfgFile, c.K0sVars) + _, err := config.GetConfigFromYAML(c.CfgFile, c.K0sVars) if err != nil { return err } diff --git a/cmd/token/create.go b/cmd/token/create.go index 41183eedd7a3..aad58cb7b7f1 100644 --- a/cmd/token/create.go +++ b/cmd/token/create.go @@ -76,7 +76,7 @@ k0s token create --role worker --expiry 10m //sets expiration time to 10 minute } // append flags cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) - + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.Flags().StringVar(&tokenExpiry, "expiry", "0s", "Expiration time of the token. Format 1.5h, 2h45m or 300ms.") cmd.Flags().StringVar(&createTokenRole, "role", "worker", "Either worker or controller") cmd.Flags().BoolVar(&waitCreate, "wait", false, "wait forever (default false)") diff --git a/cmd/token/token.go b/cmd/token/token.go index f59d1b5893c4..798e6beb078c 100644 --- a/cmd/token/token.go +++ b/cmd/token/token.go @@ -43,6 +43,5 @@ func NewTokenCmd() *cobra.Command { cmd.AddCommand(tokenCreateCmd()) cmd.AddCommand(tokenListCmd()) cmd.AddCommand(tokenInvalidateCmd()) - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } diff --git a/cmd/validate/validate.go b/cmd/validate/validate.go index 4139865a4123..c36152a15f95 100644 --- a/cmd/validate/validate.go +++ b/cmd/validate/validate.go @@ -1,12 +1,9 @@ /* Copyright 2021 k0s authors - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/inttest/Makefile b/inttest/Makefile index 150ad81655af..448d81300a3d 100644 --- a/inttest/Makefile +++ b/inttest/Makefile @@ -40,6 +40,7 @@ check-ctr: TIMEOUT=10m check-byocri: TIMEOUT=5m # readiness check for metric tests takes between around 5 and 6 minutes. check-metrics: TIMEOUT=6m +check-calico: TIMEOUT=6m # Establishing konnectivity tunnels with the LB in place takes a while, thus a bit longer timeout for the smoke check-customports: TIMEOUT=6m diff --git a/inttest/customports/customports_test.go b/inttest/customports/customports_test.go index 5b22b9b49f13..dd1a975b0e38 100644 --- a/inttest/customports/customports_test.go +++ b/inttest/customports/customports_test.go @@ -104,7 +104,7 @@ func (ds *Suite) TestControllerJoinsWithCustomPort() { workerToken, err := ds.GetJoinToken("worker", "", "--config=/tmp/k0s.yaml") ds.Require().NoError(err) - ds.Require().NoError(ds.RunWorkersWithToken("/var/lib/k0s", workerToken, `--config="/tmp/k0s.yaml"`)) + ds.Require().NoError(ds.RunWorkersWithToken("/var/lib/k0s", workerToken)) kc, err := ds.KubeClient("controller0", "") ds.Require().NoError(err) diff --git a/pkg/apis/k0s.k0sproject.io/v1beta1/clusterconfig_types.go b/pkg/apis/k0s.k0sproject.io/v1beta1/clusterconfig_types.go index 5fc908a02a19..63e34c8641fa 100644 --- a/pkg/apis/k0s.k0sproject.io/v1beta1/clusterconfig_types.go +++ b/pkg/apis/k0s.k0sproject.io/v1beta1/clusterconfig_types.go @@ -18,9 +18,7 @@ package v1beta1 import ( "bytes" "encoding/json" - "fmt" "io" - "os" "reflect" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -162,24 +160,6 @@ func (s *SchedulerSpec) IsZero() bool { return len(s.ExtraArgs) == 0 } -// ConfigFromFile takes a file path as Input, and parses it into a ClusterConfig -func ConfigFromFile(filename string, defaultStorage ...*StorageSpec) (*ClusterConfig, error) { - buf, err := os.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("failed to read config file at %s: %w", filename, err) - } - return ConfigFromString(string(buf), defaultStorage...) -} - -// ConfigFromStdin tries to read k0s.yaml config from stdin -func ConfigFromStdin(defaultStorage ...*StorageSpec) (*ClusterConfig, error) { - input, err := io.ReadAll(os.Stdin) - if err != nil { - return nil, fmt.Errorf("can't read configration from stdin: %v", err) - } - return ConfigFromString(string(input), defaultStorage...) -} - func ConfigFromString(yml string, defaultStorage ...*StorageSpec) (*ClusterConfig, error) { config := DefaultClusterConfig(defaultStorage...) err := strictyaml.YamlUnmarshalStrictIgnoringFields([]byte(yml), config, "interval") @@ -192,6 +172,15 @@ func ConfigFromString(yml string, defaultStorage ...*StorageSpec) (*ClusterConfi return config, nil } +// ConfigFromReader reads the configuration from any reader (can be stdin, file reader, etc) +func ConfigFromReader(r io.Reader, defaultStorage ...*StorageSpec) (*ClusterConfig, error) { + input, err := io.ReadAll(r) + if err != nil { + return nil, err + } + return ConfigFromString(string(input), defaultStorage...) +} + // DefaultClusterConfig sets the default ClusterConfig values, when none are given func DefaultClusterConfig(defaultStorage ...*StorageSpec) *ClusterConfig { return &ClusterConfig{ @@ -289,6 +278,56 @@ func (c *ClusterConfig) Validate() []error { return errors } +// GetBootstrappingConfig returns a ClusterConfig object stripped of Cluster-Wide Settings +func (c *ClusterConfig) GetBootstrappingConfig(storageSpec *StorageSpec) *ClusterConfig { + return &ClusterConfig{ + ObjectMeta: c.ObjectMeta, + TypeMeta: c.TypeMeta, + Spec: &ClusterSpec{ + API: c.Spec.API, + Storage: storageSpec, + Network: &Network{ + ServiceCIDR: c.Spec.Network.ServiceCIDR, + DualStack: c.Spec.Network.DualStack, + }, + Install: c.Spec.Install, + }, + Status: c.Status, + } +} + +// HACK: the current ClusterConfig struct holds both bootstrapping config & cluster-wide config +// this hack strips away the node-specific bootstrapping config so that we write a "clean" config to the CR +// This function accepts a standard ClusterConfig and returns the same config minus the node specific info: +// - APISpec +// - StorageSpec +// - Network.ServiceCIDR +// - Install +func (c *ClusterConfig) GetClusterWideConfig() *ClusterConfig { + return &ClusterConfig{ + ObjectMeta: c.ObjectMeta, + TypeMeta: c.TypeMeta, + Spec: &ClusterSpec{ + ControllerManager: c.Spec.ControllerManager, + Scheduler: c.Spec.Scheduler, + Network: &Network{ + Calico: c.Spec.Network.Calico, + KubeProxy: c.Spec.Network.KubeProxy, + KubeRouter: c.Spec.Network.KubeRouter, + PodCIDR: c.Spec.Network.PodCIDR, + Provider: c.Spec.Network.Provider, + }, + PodSecurityPolicy: c.Spec.PodSecurityPolicy, + WorkerProfiles: c.Spec.WorkerProfiles, + Telemetry: c.Spec.Telemetry, + Images: c.Spec.Images, + Extensions: c.Spec.Extensions, + Konnectivity: c.Spec.Konnectivity, + }, + Status: c.Status, + } +} + // CRValidator is used to make sure a config CR is created with correct values func (c *ClusterConfig) CRValidator() *ClusterConfig { copy := c.DeepCopy() diff --git a/pkg/component/controller/clusterConfig.go b/pkg/component/controller/clusterConfig.go index 9a6c811eca2f..338549bb2ccf 100644 --- a/pkg/component/controller/clusterConfig.go +++ b/pkg/component/controller/clusterConfig.go @@ -201,7 +201,7 @@ func (r *ClusterConfigReconciler) reportStatus(config *v1beta1.ClusterConfig, re func (r *ClusterConfigReconciler) copyRunningConfigToCR(baseCtx context.Context) (*v1beta1.ClusterConfig, error) { ctx, cancel := context.WithTimeout(baseCtx, 5*time.Second) defer cancel() - clusterWideConfig := config.ClusterConfigMinusNodeConfig(r.YamlConfig).StripDefaults().CRValidator() + clusterWideConfig := r.YamlConfig.GetClusterWideConfig().StripDefaults().CRValidator() clusterConfig, err := r.configClient.Create(ctx, clusterWideConfig, cOpts) if err != nil { return nil, err diff --git a/pkg/config/cli.go b/pkg/config/cli.go index eb2439840c3d..72d1ea35dec1 100644 --- a/pkg/config/cli.go +++ b/pkg/config/cli.go @@ -104,7 +104,6 @@ func DefaultLogLevels() map[string]string { func GetPersistentFlagSet() *pflag.FlagSet { flagset := &pflag.FlagSet{} - flagset.StringVarP(&CfgFile, "config", "c", "", "config file, use '-' to read the config from stdin") flagset.BoolVarP(&Debug, "debug", "d", false, "Debug logging (default: false)") flagset.BoolVarP(&Verbose, "verbose", "v", false, "Verbose logging (default: false)") flagset.StringVar(&DataDir, "data-dir", "", "Data Directory for k0s (default: /var/lib/k0s). DO NOT CHANGE for an existing setup, things will break!") @@ -179,6 +178,16 @@ func GetControllerFlags() *pflag.FlagSet { flagset.IntVar(&controllerOpts.K0sCloudProviderPort, "k0s-cloud-provider-port", cloudprovider.CloudControllerManagerPort, "the port that k0s-cloud-provider binds on") flagset.AddFlagSet(GetCriSocketFlag()) flagset.BoolVar(&controllerOpts.EnableDynamicConfig, "enable-dynamic-config", false, "enable cluster-wide dynamic config based on custom resource") + flagset.AddFlagSet(FileInputFlag()) + return flagset +} + +// The config flag used to be a persistent, joint flag to all commands +// now only a few commands use it. This function helps to share the flag with multiple commands without needing to define +// it in multiple places +func FileInputFlag() *pflag.FlagSet { + flagset := &pflag.FlagSet{} + flagset.StringVarP(&CfgFile, "config", "c", constant.K0sConfigPathDefault, "config file, use '-' to read the config from stdin") return flagset } diff --git a/pkg/config/config.go b/pkg/config/config.go index 378f312fe66f..6e1779aef42e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -18,6 +18,7 @@ package config import ( "context" "fmt" + "os" "strings" "time" @@ -65,7 +66,7 @@ func GetFullConfig(cfgPath string, k0sVars constant.CfgVars) (clusterConfig *v1b // no config file exists, using defaults logrus.Warn("no config file given, using defaults") } - cfg, err := ValidateYaml(cfgPath, k0sVars) + cfg, err := GetConfigFromYAML(cfgPath, k0sVars) if err != nil { return nil, err } @@ -108,43 +109,77 @@ func GetYamlFromFile(cfgPath string, k0sVars constant.CfgVars) (clusterConfig *v // no config file exists, using defaults logrus.Warn("no config file given, using defaults") } - cfg, err := ValidateYaml(cfgPath, k0sVars) + cfg, err := GetConfigFromYAML(cfgPath, k0sVars) if err != nil { return nil, err } return cfg, nil } -func ValidateYaml(cfgPath string, k0sVars constant.CfgVars) (clusterConfig *v1beta1.ClusterConfig, err error) { +// GetConfigFromYAML will attempt to read a config yaml, validate it and return a clusterConfig object +func GetConfigFromYAML(cfgPath string, k0sVars constant.CfgVars) (clusterConfig *v1beta1.ClusterConfig, err error) { var storage *v1beta1.StorageSpec + var cfg *v1beta1.ClusterConfig + + CfgFile = cfgPath + + // first, let's set the default storage type if k0sVars.DefaultStorageType == "kine" { storage = &v1beta1.StorageSpec{ Type: v1beta1.KineStorageType, Kine: v1beta1.DefaultKineConfig(k0sVars.DataDir), } - } - switch cfgPath { - case "-": - clusterConfig, err = v1beta1.ConfigFromStdin(storage) - case "": - clusterConfig = v1beta1.DefaultClusterConfig(storage) + + switch CfgFile { + // read config file flag default: - clusterConfig, err = v1beta1.ConfigFromFile(cfgPath, storage) - } - if err != nil { - return nil, err + f, err := os.Open(CfgFile) + if err != nil { + return nil, err + } + defer f.Close() + + cfg, err = v1beta1.ConfigFromReader(f, storage) + if err != nil { + return nil, err + } + + // stdin input + case "-": + cfg, err = v1beta1.ConfigFromReader(os.Stdin, storage) + + // config file not provided: try to read config from default location. + // if not exists, generate default config + case constant.K0sConfigPathDefault: + f, err := os.Open(constant.K0sConfigPathDefault) + if err != nil { + if os.IsNotExist(err) { + logrus.Debugf("could not find config in %s, using defaults", constant.K0sConfigPathDefault) + cfg = v1beta1.DefaultClusterConfig(storage) + } else { + return nil, err + } + } + if err == nil { + logrus.Debugf("found config file in %s", constant.K0sConfigPathDefault) + cfg, err = v1beta1.ConfigFromReader(f, storage) + if err != nil { + return nil, err + } + defer f.Close() + } } - if clusterConfig.Spec.Storage.Type == v1beta1.KineStorageType && clusterConfig.Spec.Storage.Kine == nil { + if cfg.Spec.Storage.Type == v1beta1.KineStorageType && cfg.Spec.Storage.Kine == nil { logrus.Warn("storage type is kine but no config given, setting up defaults") - clusterConfig.Spec.Storage.Kine = v1beta1.DefaultKineConfig(k0sVars.DataDir) + cfg.Spec.Storage.Kine = v1beta1.DefaultKineConfig(k0sVars.DataDir) } - if clusterConfig.Spec.Install == nil { - clusterConfig.Spec.Install = v1beta1.DefaultInstallSpec() + if cfg.Spec.Install == nil { + cfg.Spec.Install = v1beta1.DefaultInstallSpec() } - errors := clusterConfig.Validate() + errors := cfg.Validate() if len(errors) > 0 { messages := make([]string, len(errors)) for _, e := range errors { @@ -152,47 +187,7 @@ func ValidateYaml(cfgPath string, k0sVars constant.CfgVars) (clusterConfig *v1be } return nil, fmt.Errorf(strings.Join(messages, "\n")) } - return clusterConfig, nil -} - -// HACK: the current ClusterConfig struct holds both bootstrapping config & cluster-wide config -// this hack strips away the node-specific bootstrapping config so that we write a "clean" config to the CR -// This function accepts a standard ClusterConfig and returns the same config minus the node specific info: -// - APISpec -// - StorageSpec -// - Network.ServiceCIDR -// - Install -func ClusterConfigMinusNodeConfig(config *v1beta1.ClusterConfig) *v1beta1.ClusterConfig { - clusterSpec := &v1beta1.ClusterSpec{ - ControllerManager: config.Spec.ControllerManager, - Scheduler: config.Spec.Scheduler, - Network: &v1beta1.Network{ - Calico: config.Spec.Network.Calico, - DualStack: config.Spec.Network.DualStack, - KubeProxy: config.Spec.Network.KubeProxy, - KubeRouter: config.Spec.Network.KubeRouter, - PodCIDR: config.Spec.Network.PodCIDR, - Provider: config.Spec.Network.Provider, - }, - PodSecurityPolicy: config.Spec.PodSecurityPolicy, - WorkerProfiles: config.Spec.WorkerProfiles, - Telemetry: config.Spec.Telemetry, - Images: config.Spec.Images, - Extensions: config.Spec.Extensions, - Konnectivity: config.Spec.Konnectivity, - API: &v1beta1.APISpec{ - ExternalAddress: config.Spec.API.ExternalAddress, - Address: config.Spec.API.Address, - Port: config.Spec.API.Port, - }, - } - - return &v1beta1.ClusterConfig{ - ObjectMeta: config.ObjectMeta, - TypeMeta: config.TypeMeta, - Spec: clusterSpec, - Status: config.Status, - } + return cfg, nil } // GetNodeConfig takes a config-file parameter and returns a ClusterConfig stripped of Cluster-Wide Settings @@ -201,31 +196,13 @@ func GetNodeConfig(cfgPath string, k0sVars constant.CfgVars) (*v1beta1.ClusterCo if err != nil { return nil, err } + nodeConfig := cfg.GetBootstrappingConfig(cfg.Spec.Storage) var etcdConfig *v1beta1.EtcdConfig if cfg.Spec.Storage.Type == v1beta1.EtcdStorageType { etcdConfig = &v1beta1.EtcdConfig{ PeerAddress: cfg.Spec.Storage.Etcd.PeerAddress, } - } - - clusterSpec := &v1beta1.ClusterSpec{ - API: cfg.Spec.API, - Storage: &v1beta1.StorageSpec{ - Type: cfg.Spec.Storage.Type, - Etcd: etcdConfig, - Kine: cfg.Spec.Storage.Kine, - }, - Network: &v1beta1.Network{ - ServiceCIDR: cfg.Spec.Network.ServiceCIDR, - DualStack: cfg.Spec.Network.DualStack, - }, - Install: cfg.Spec.Install, - } - nodeConfig := &v1beta1.ClusterConfig{ - ObjectMeta: cfg.ObjectMeta, - TypeMeta: cfg.TypeMeta, - Spec: clusterSpec, - Status: cfg.Status, + nodeConfig.Spec.Storage.Etcd = etcdConfig } return nodeConfig, nil } diff --git a/pkg/constant/constant_posix.go b/pkg/constant/constant_posix.go index 82af82908e4f..03b209ec1adf 100644 --- a/pkg/constant/constant_posix.go +++ b/pkg/constant/constant_posix.go @@ -27,6 +27,7 @@ const ( KineSocket = "kine/kine.sock:2379" KubePauseContainerImage = "k8s.gcr.io/pause" KubePauseContainerImageVersion = "3.5" + K0sConfigPathDefault = "/etc/k0s/k0s.yaml" ) func formatPath(dir string, file string) string { diff --git a/pkg/constant/constant_windows.go b/pkg/constant/constant_windows.go index d946cf908540..b6ca027981c0 100644 --- a/pkg/constant/constant_windows.go +++ b/pkg/constant/constant_windows.go @@ -36,6 +36,7 @@ const ( KineSocket = "kine\\kine.sock:2379" KubePauseContainerImage = "mcr.microsoft.com/oss/kubernetes/pause" KubePauseContainerImageVersion = "1.4.1" + K0sConfigPathDefault = "C:\\etc\\k0s\\k0s.yaml" ) func formatPath(dir string, file string) string {