From 665f66d2bc572342bb22603d966bc96ce9dbe919 Mon Sep 17 00:00:00 2001 From: "Lubomir I. Ivanov" Date: Mon, 6 Jun 2022 17:31:54 +0300 Subject: [PATCH] kubeadm: pass io.Writer and "patches dir" to WriteConfigToDisk() With phases/kubelet/WriteConfigToDisk() about to support patches it is required that the function accepts an io.Writer where the PatchManager can output to and also a patch directory. Modify all call sites of the function WriteConfigToDisk() to properly prepare an pass an io.Writer and patches dir to it. This results in command phases for init/join/upgrade to pass the root io.Writer (usually stdout) and the patchesDir populated either via the config file or --patches flag. --- cmd/kubeadm/app/cmd/phases/init/kubelet.go | 2 +- cmd/kubeadm/app/cmd/phases/join/kubelet.go | 2 +- cmd/kubeadm/app/cmd/phases/upgrade/node/data.go | 3 +++ .../app/cmd/phases/upgrade/node/kubeletconfig.go | 2 +- cmd/kubeadm/app/cmd/upgrade/apply.go | 2 +- cmd/kubeadm/app/cmd/upgrade/node.go | 13 ++++++++++--- cmd/kubeadm/app/cmd/upgrade/upgrade.go | 2 +- cmd/kubeadm/app/phases/kubelet/config.go | 3 ++- cmd/kubeadm/app/phases/upgrade/postupgrade.go | 9 +++++---- 9 files changed, 25 insertions(+), 13 deletions(-) diff --git a/cmd/kubeadm/app/cmd/phases/init/kubelet.go b/cmd/kubeadm/app/cmd/phases/init/kubelet.go index bf43d23821a..e5246861e1c 100644 --- a/cmd/kubeadm/app/cmd/phases/init/kubelet.go +++ b/cmd/kubeadm/app/cmd/phases/init/kubelet.go @@ -74,7 +74,7 @@ func runKubeletStart(c workflow.RunData) error { } // Write the kubelet configuration file to disk. - if err := kubeletphase.WriteConfigToDisk(&data.Cfg().ClusterConfiguration, data.KubeletDir()); err != nil { + if err := kubeletphase.WriteConfigToDisk(&data.Cfg().ClusterConfiguration, data.KubeletDir(), data.PatchesDir(), data.OutputWriter()); err != nil { return errors.Wrap(err, "error writing kubelet configuration to disk") } diff --git a/cmd/kubeadm/app/cmd/phases/join/kubelet.go b/cmd/kubeadm/app/cmd/phases/join/kubelet.go index 377db62dab0..db46fa02542 100644 --- a/cmd/kubeadm/app/cmd/phases/join/kubelet.go +++ b/cmd/kubeadm/app/cmd/phases/join/kubelet.go @@ -174,7 +174,7 @@ func runKubeletStartJoinPhase(c workflow.RunData) (returnErr error) { } // Write the configuration for the kubelet (using the bootstrap token credentials) to disk so the kubelet can start - if err := kubeletphase.WriteConfigToDisk(&initCfg.ClusterConfiguration, data.KubeletDir()); err != nil { + if err := kubeletphase.WriteConfigToDisk(&initCfg.ClusterConfiguration, data.KubeletDir(), data.PatchesDir(), data.OutputWriter()); err != nil { return err } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/data.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/data.go index c6ab05a970f..429ce185937 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/data.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/data.go @@ -17,6 +17,8 @@ limitations under the License. package node import ( + "io" + "k8s.io/apimachinery/pkg/util/sets" clientset "k8s.io/client-go/kubernetes" @@ -35,4 +37,5 @@ type Data interface { IgnorePreflightErrors() sets.String PatchesDir() string KubeConfigPath() string + OutputWriter() io.Writer } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go index 773b5a8d7ad..3869c0f679c 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go @@ -73,7 +73,7 @@ func runKubeletConfigPhase() func(c workflow.RunData) error { // TODO: Checkpoint the current configuration first so that if something goes wrong it can be recovered // Store the kubelet component configuration. - if err = kubeletphase.WriteConfigToDisk(&cfg.ClusterConfiguration, kubeletDir); err != nil { + if err = kubeletphase.WriteConfigToDisk(&cfg.ClusterConfiguration, kubeletDir, data.PatchesDir(), data.OutputWriter()); err != nil { return err } diff --git a/cmd/kubeadm/app/cmd/upgrade/apply.go b/cmd/kubeadm/app/cmd/upgrade/apply.go index 9900964db3e..ee99707aa27 100644 --- a/cmd/kubeadm/app/cmd/upgrade/apply.go +++ b/cmd/kubeadm/app/cmd/upgrade/apply.go @@ -168,7 +168,7 @@ func runApply(flags *applyFlags, args []string) error { // Upgrade RBAC rules and addons. klog.V(1).Infoln("[upgrade/postupgrade] upgrading RBAC rules and addons") - if err := upgrade.PerformPostUpgradeTasks(client, cfg, flags.dryRun); err != nil { + if err := upgrade.PerformPostUpgradeTasks(client, cfg, flags.patchesDir, flags.dryRun, flags.applyPlanFlags.out); err != nil { return errors.Wrap(err, "[upgrade/postupgrade] FATAL post-upgrade error") } diff --git a/cmd/kubeadm/app/cmd/upgrade/node.go b/cmd/kubeadm/app/cmd/upgrade/node.go index 8548fc79364..b76f78ab55c 100644 --- a/cmd/kubeadm/app/cmd/upgrade/node.go +++ b/cmd/kubeadm/app/cmd/upgrade/node.go @@ -17,6 +17,7 @@ limitations under the License. package upgrade import ( + "io" "os" "github.com/pkg/errors" @@ -63,10 +64,11 @@ type nodeData struct { patchesDir string ignorePreflightErrors sets.String kubeConfigPath string + outputWriter io.Writer } // newCmdNode returns the cobra command for `kubeadm upgrade node` -func newCmdNode() *cobra.Command { +func newCmdNode(out io.Writer) *cobra.Command { nodeOptions := newNodeOptions() nodeRunner := workflow.NewRunner() @@ -92,7 +94,7 @@ func newCmdNode() *cobra.Command { // sets the data builder function, that will be used by the runner // both when running the entire workflow or single phases nodeRunner.SetDataInitializer(func(cmd *cobra.Command, args []string) (workflow.RunData, error) { - return newNodeData(cmd, args, nodeOptions) + return newNodeData(cmd, args, nodeOptions, out) }) // binds the Runner to kubeadm upgrade node command by altering @@ -123,7 +125,7 @@ func addUpgradeNodeFlags(flagSet *flag.FlagSet, nodeOptions *nodeOptions) { // newNodeData returns a new nodeData struct to be used for the execution of the kubeadm upgrade node workflow. // This func takes care of validating nodeOptions passed to the command, and then it converts // options into the internal InitConfiguration type that is used as input all the phases in the kubeadm upgrade node workflow -func newNodeData(cmd *cobra.Command, args []string, options *nodeOptions) (*nodeData, error) { +func newNodeData(cmd *cobra.Command, args []string, options *nodeOptions, out io.Writer) (*nodeData, error) { client, err := getClient(options.kubeConfigPath, options.dryRun) if err != nil { return nil, errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", options.kubeConfigPath) @@ -168,6 +170,7 @@ func newNodeData(cmd *cobra.Command, args []string, options *nodeOptions) (*node patchesDir: options.patchesDir, ignorePreflightErrors: ignorePreflightErrorsSet, kubeConfigPath: options.kubeConfigPath, + outputWriter: out, }, nil } @@ -215,3 +218,7 @@ func (d *nodeData) IgnorePreflightErrors() sets.String { func (d *nodeData) KubeConfigPath() string { return d.kubeConfigPath } + +func (d *nodeData) OutputWriter() io.Writer { + return d.outputWriter +} diff --git a/cmd/kubeadm/app/cmd/upgrade/upgrade.go b/cmd/kubeadm/app/cmd/upgrade/upgrade.go index f65376b6f0b..32499f1d4ac 100644 --- a/cmd/kubeadm/app/cmd/upgrade/upgrade.go +++ b/cmd/kubeadm/app/cmd/upgrade/upgrade.go @@ -60,7 +60,7 @@ func NewCmdUpgrade(out io.Writer) *cobra.Command { cmd.AddCommand(newCmdApply(flags)) cmd.AddCommand(newCmdPlan(flags)) cmd.AddCommand(newCmdDiff(out)) - cmd.AddCommand(newCmdNode()) + cmd.AddCommand(newCmdNode(out)) return cmd } diff --git a/cmd/kubeadm/app/phases/kubelet/config.go b/cmd/kubeadm/app/phases/kubelet/config.go index 8ef11d60d68..5ec7dcb3c3a 100644 --- a/cmd/kubeadm/app/phases/kubelet/config.go +++ b/cmd/kubeadm/app/phases/kubelet/config.go @@ -18,6 +18,7 @@ package kubelet import ( "fmt" + "io" "os" "path/filepath" @@ -38,7 +39,7 @@ import ( // WriteConfigToDisk writes the kubelet config object down to a file // Used at "kubeadm init" and "kubeadm upgrade" time -func WriteConfigToDisk(cfg *kubeadmapi.ClusterConfiguration, kubeletDir string) error { +func WriteConfigToDisk(cfg *kubeadmapi.ClusterConfiguration, kubeletDir, patchesDir string, output io.Writer) error { kubeletCfg, ok := cfg.ComponentConfigs[componentconfigs.KubeletGroup] if !ok { return errors.New("no kubelet component config found") diff --git a/cmd/kubeadm/app/phases/upgrade/postupgrade.go b/cmd/kubeadm/app/phases/upgrade/postupgrade.go index aad71841736..190c3afefa9 100644 --- a/cmd/kubeadm/app/phases/upgrade/postupgrade.go +++ b/cmd/kubeadm/app/phases/upgrade/postupgrade.go @@ -19,6 +19,7 @@ package upgrade import ( "context" "fmt" + "io" "os" "strings" @@ -48,7 +49,7 @@ import ( // PerformPostUpgradeTasks runs nearly the same functions as 'kubeadm init' would do // Note that the mark-control-plane phase is left out, not needed, and no token is created as that doesn't belong to the upgrade -func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, dryRun bool) error { +func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, patchesDir string, dryRun bool, out io.Writer) error { errs := []error{} // Upload currently used configuration to the cluster @@ -64,7 +65,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon } // Write the new kubelet config down to disk and the env file if needed - if err := writeKubeletConfigFiles(client, cfg, dryRun); err != nil { + if err := writeKubeletConfigFiles(client, cfg, patchesDir, dryRun, out); err != nil { errs = append(errs, err) } @@ -158,7 +159,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon return errorsutil.NewAggregate(errs) } -func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, dryRun bool) error { +func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, patchesDir string, dryRun bool, out io.Writer) error { kubeletDir, err := GetKubeletDir(dryRun) if err != nil { // The error here should never occur in reality, would only be thrown if /tmp doesn't exist on the machine. @@ -166,7 +167,7 @@ func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitCon } errs := []error{} // Write the configuration for the kubelet down to disk so the upgraded kubelet can start with fresh config - if err := kubeletphase.WriteConfigToDisk(&cfg.ClusterConfiguration, kubeletDir); err != nil { + if err := kubeletphase.WriteConfigToDisk(&cfg.ClusterConfiguration, kubeletDir, patchesDir, out); err != nil { errs = append(errs, errors.Wrap(err, "error writing kubelet configuration to file")) }