From e51ffd1ed3c4321549f9dc221a894a90347eae8f Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Tue, 24 Dec 2024 14:54:36 +0100 Subject: [PATCH] Encapsulate debug flag handling Introduce internal.DebugFlags to replace debug and verbose logging flag handling. Move the flag definitions from the "PersistentFlagSet" to a struct method. Remove the debug flag handling from the root command and move it to the sub-commands. This allows for the removal of CallPersistentPreRun, since the commands no longer rely on proper chaining of the PersistentPreRun hooks. Remove some redundant calls to the "PersistentFlagSet" in some sub-commands. Signed-off-by: Tom Wieczorek --- cmd/airgap/airgap.go | 18 +++-- cmd/airgap/listimages.go | 5 +- cmd/api/api.go | 22 ++++--- cmd/backup/backup_unix.go | 20 ++++-- cmd/config/config.go | 15 +++-- cmd/config/create.go | 20 ++++-- cmd/config/edit.go | 2 + cmd/config/status.go | 3 + cmd/config/validate.go | 14 +++- cmd/controller/controller.go | 33 +++++----- cmd/controller/controller_test.go | 4 +- cmd/etcd/etcd.go | 12 ++-- cmd/etcd/leave.go | 3 +- cmd/etcd/list.go | 2 + cmd/install/controller.go | 4 +- cmd/install/controller_test.go | 10 +-- cmd/install/install.go | 24 ++++--- cmd/install/worker.go | 7 +- cmd/internal/debug.go | 105 ++++++++++++++++++++++++++++++ cmd/kubeconfig/admin.go | 2 + cmd/kubeconfig/create.go | 4 +- cmd/kubeconfig/kubeconfig.go | 18 +++-- cmd/kubectl/kubectl.go | 8 ++- cmd/reset/reset.go | 28 +++++--- cmd/restore/restore_unix.go | 19 ++++-- cmd/root.go | 25 ------- cmd/start/start.go | 15 +++-- cmd/status/status.go | 25 ++++--- cmd/stop/stop.go | 15 +++-- cmd/sysinfo/sysinfo.go | 18 +++-- cmd/token/create.go | 9 ++- cmd/token/invalidate.go | 2 + cmd/token/list.go | 5 +- cmd/token/preshared.go | 22 +++++-- cmd/token/token.go | 15 +++-- cmd/worker/worker.go | 24 +++---- main.go | 1 - pkg/config/cli.go | 62 ++---------------- 38 files changed, 412 insertions(+), 228 deletions(-) create mode 100644 cmd/internal/debug.go diff --git a/cmd/airgap/airgap.go b/cmd/airgap/airgap.go index 9d15ee6df5d0..eb88379ce4f8 100644 --- a/cmd/airgap/airgap.go +++ b/cmd/airgap/airgap.go @@ -19,19 +19,23 @@ package airgap import ( "github.com/spf13/cobra" - "github.com/k0sproject/k0s/pkg/config" + "github.com/k0sproject/k0s/cmd/internal" ) func NewAirgapCmd() *cobra.Command { + var debugFlags internal.DebugFlags + cmd := &cobra.Command{ - Use: "airgap", - Short: "Manage airgap setup", - Args: cobra.NoArgs, - Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, + Use: "airgap", + Short: "Manage airgap setup", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, + Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, } + debugFlags.AddToFlagSet(cmd.PersistentFlags()) + 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 071b34b5f02e..ca00b3ee585d 100644 --- a/cmd/airgap/listimages.go +++ b/cmd/airgap/listimages.go @@ -53,8 +53,11 @@ func NewAirgapListImagesCmd() *cobra.Command { return nil }, } + + cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.Flags().BoolVar(&all, "all", false, "include all images, even if they are not used in the current configuration") - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/api/api.go b/cmd/api/api.go index 5961743f2adf..5522a44cf464 100644 --- a/cmd/api/api.go +++ b/cmd/api/api.go @@ -29,7 +29,7 @@ import ( "strings" "time" - k0slog "github.com/k0sproject/k0s/internal/pkg/log" + "github.com/k0sproject/k0s/cmd/internal" mw "github.com/k0sproject/k0s/internal/pkg/middleware" "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" "github.com/k0sproject/k0s/pkg/config" @@ -50,15 +50,13 @@ type command struct { } func NewAPICmd() *cobra.Command { + var debugFlags internal.DebugFlags + cmd := &cobra.Command{ - Use: "api", - Short: "Run the controller API", - Args: cobra.NoArgs, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - logrus.SetOutput(cmd.OutOrStdout()) - k0slog.SetInfoLevel() - return config.CallParentPersistentPreRun(cmd, args) - }, + Use: "api", + Short: "Run the controller API", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, RunE: func(cmd *cobra.Command, _ []string) error { opts, err := config.GetCmdOpts(cmd) if err != nil { @@ -67,7 +65,11 @@ func NewAPICmd() *cobra.Command { return (&command{CLIOptions: opts}).start() }, } - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + + pflags := cmd.PersistentFlags() + debugFlags.LongRunning().AddToFlagSet(pflags) + pflags.AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/backup/backup_unix.go b/cmd/backup/backup_unix.go index dd80d8443c6c..a0d52fb45343 100644 --- a/cmd/backup/backup_unix.go +++ b/cmd/backup/backup_unix.go @@ -25,6 +25,7 @@ import ( "os" "strings" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/internal/pkg/dir" "github.com/k0sproject/k0s/pkg/backup" "github.com/k0sproject/k0s/pkg/component/status" @@ -37,12 +38,16 @@ import ( type command config.CLIOptions func NewBackupCmd() *cobra.Command { - var savePath string + var ( + debugFlags internal.DebugFlags + savePath string + ) cmd := &cobra.Command{ - Use: "backup", - Short: "Back-Up k0s configuration. Must be run as root (or with sudo)", - Args: cobra.NoArgs, + Use: "backup", + Short: "Back-Up k0s configuration. Must be run as root (or with sudo)", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, PreRun: func(cmd *cobra.Command, args []string) { // ensure logs don't mess up output logrus.SetOutput(cmd.ErrOrStderr()) @@ -63,8 +68,13 @@ func NewBackupCmd() *cobra.Command { return c.backup(savePath, cmd.OutOrStdout()) }, } + + pflags := cmd.PersistentFlags() + debugFlags.AddToFlagSet(pflags) + pflags.AddFlagSet(config.GetPersistentFlagSet()) + cmd.Flags().StringVar(&savePath, "save-path", "", "destination directory path for backup assets, use '-' for stdout") - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/config/config.go b/cmd/config/config.go index d45ab38ba0e2..30198815c6b9 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -17,20 +17,27 @@ limitations under the License. package config import ( + "github.com/k0sproject/k0s/cmd/internal" "github.com/spf13/cobra" ) func NewConfigCmd() *cobra.Command { + var debugFlags internal.DebugFlags + cmd := &cobra.Command{ - Use: "config", - Short: "Configuration related sub-commands", - Args: cobra.NoArgs, - Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, + Use: "config", + Short: "Configuration related sub-commands", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, + Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, } cmd.AddCommand(NewCreateCmd()) cmd.AddCommand(NewEditCmd()) cmd.AddCommand(NewStatusCmd()) cmd.AddCommand(NewValidateCmd()) + + debugFlags.AddToFlagSet(cmd.PersistentFlags()) + return cmd } diff --git a/cmd/config/create.go b/cmd/config/create.go index 7f72e2d5747b..f9e45e4a3dec 100644 --- a/cmd/config/create.go +++ b/cmd/config/create.go @@ -17,13 +17,15 @@ limitations under the License. package config import ( - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "sigs.k8s.io/yaml" - "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" k0sscheme "github.com/k0sproject/k0s/pkg/client/clientset/scheme" "github.com/k0sproject/k0s/pkg/config" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "sigs.k8s.io/yaml" ) func NewCreateCmd() *cobra.Command { @@ -55,7 +57,15 @@ func NewCreateCmd() *cobra.Command { return err }, } + + pflags := cmd.PersistentFlags() + // Add unused persistent flags for backwards compatibility. + config.GetPersistentFlagSet().VisitAll(func(f *pflag.Flag) { + f.Hidden = true + pflags.AddFlag(f) + }) + cmd.Flags().BoolVar(&includeImages, "include-images", false, "include the default images in the output") - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/config/edit.go b/cmd/config/edit.go index f03e61f8a13a..a388c729444f 100644 --- a/cmd/config/edit.go +++ b/cmd/config/edit.go @@ -31,6 +31,8 @@ func NewEditCmd() *cobra.Command { return reExecKubectl(cmd, "-n", "kube-system", "edit", "clusterconfig", "k0s") }, } + cmd.PersistentFlags().AddFlagSet(config.GetKubeCtlFlagSet()) + return cmd } diff --git a/cmd/config/status.go b/cmd/config/status.go index 0bd9e69d6dc2..96c6200e47a1 100644 --- a/cmd/config/status.go +++ b/cmd/config/status.go @@ -38,7 +38,10 @@ func NewStatusCmd() *cobra.Command { return reExecKubectl(cmd, args...) }, } + cmd.PersistentFlags().AddFlagSet(config.GetKubeCtlFlagSet()) + cmd.Flags().StringVarP(&outputFormat, "output", "o", "", "Output format. Must be one of yaml|json") + return cmd } diff --git a/cmd/config/validate.go b/cmd/config/validate.go index 15cbdcc1e6dd..092825735969 100644 --- a/cmd/config/validate.go +++ b/cmd/config/validate.go @@ -25,7 +25,10 @@ import ( "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" "github.com/k0sproject/k0s/pkg/config" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "github.com/spf13/cobra" + "github.com/spf13/pflag" ) func NewValidateCmd() *cobra.Command { @@ -62,8 +65,15 @@ func NewValidateCmd() *cobra.Command { }, } - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + pflags := cmd.PersistentFlags() + // Add unused persistent flags for backwards compatibility. + config.GetPersistentFlagSet().VisitAll(func(f *pflag.Flag) { + f.Hidden = true + pflags.AddFlag(f) + }) + cmd.Flags().AddFlagSet(config.FileInputFlag()) - _ = cmd.MarkFlagRequired("config") + utilruntime.Must(cmd.MarkFlagRequired("config")) + return cmd } diff --git a/cmd/controller/controller.go b/cmd/controller/controller.go index 9c033c56e9ed..5a808800786e 100644 --- a/cmd/controller/controller.go +++ b/cmd/controller/controller.go @@ -31,10 +31,10 @@ import ( "time" "github.com/avast/retry-go" + "github.com/k0sproject/k0s/cmd/internal" workercmd "github.com/k0sproject/k0s/cmd/worker" "github.com/k0sproject/k0s/internal/pkg/dir" "github.com/k0sproject/k0s/internal/pkg/file" - k0slog "github.com/k0sproject/k0s/internal/pkg/log" "github.com/k0sproject/k0s/internal/pkg/sysinfo" "github.com/k0sproject/k0s/internal/sync/value" "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" @@ -67,7 +67,10 @@ import ( type command config.CLIOptions func NewControllerCmd() *cobra.Command { - var ignorePreFlightChecks bool + var ( + debugFlags internal.DebugFlags + ignorePreFlightChecks bool + ) cmd := &cobra.Command{ Use: "controller [join-token]", @@ -80,12 +83,8 @@ func NewControllerCmd() *cobra.Command { or CLI flag: $ k0s controller --token-file [path_to_file] Note: Token can be passed either as a CLI argument or as a flag`, - Args: cobra.MaximumNArgs(1), - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - logrus.SetOutput(cmd.OutOrStdout()) - k0slog.SetInfoLevel() - return config.CallParentPersistentPreRun(cmd, args) - }, + Args: cobra.MaximumNArgs(1), + PersistentPreRun: debugFlags.Run, RunE: func(cmd *cobra.Command, args []string) error { opts, err := config.GetCmdOpts(cmd) if err != nil { @@ -114,19 +113,23 @@ func NewControllerCmd() *cobra.Command { ctx, cancel := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGINT, syscall.SIGTERM) defer cancel() - return c.start(ctx) + return c.start(ctx, debugFlags.IsDebug()) }, } // append flags + pflags := cmd.PersistentFlags() + debugFlags.LongRunning().AddToFlagSet(pflags) + pflags.AddFlagSet(config.GetPersistentFlagSet()) + pflags.AddFlagSet(config.GetControllerFlags()) + pflags.AddFlagSet(config.GetWorkerFlags()) + cmd.Flags().BoolVar(&ignorePreFlightChecks, "ignore-pre-flight-checks", false, "continue even if pre-flight checks fail") - cmd.Flags().AddFlagSet(config.GetPersistentFlagSet()) - cmd.PersistentFlags().AddFlagSet(config.GetControllerFlags()) - cmd.PersistentFlags().AddFlagSet(config.GetWorkerFlags()) + return cmd } -func (c *command) start(ctx context.Context) error { +func (c *command) start(ctx context.Context, debug bool) error { perfTimer := performance.NewTimer("controller-start").Buffer().Start() nodeConfig, err := c.K0sVars.NodeConfig() @@ -247,8 +250,8 @@ func (c *command) start(ctx context.Context) error { nodeComponents.Add(ctx, &cplb.Keepalived{ K0sVars: c.K0sVars, Config: cplbCfg.Keepalived, - DetailedLogging: c.Debug, - LogConfig: c.Debug, + DetailedLogging: debug, + LogConfig: debug, KubeConfigPath: c.K0sVars.AdminKubeConfigPath, APIPort: nodeConfig.Spec.API.Port, }) diff --git a/cmd/controller/controller_test.go b/cmd/controller/controller_test.go index 31b761479088..e06afccc0478 100644 --- a/cmd/controller/controller_test.go +++ b/cmd/controller/controller_test.go @@ -59,7 +59,7 @@ Flags: -c, --config string config file, use '-' to read the config from stdin (default `+defaultConfigPath+`) --cri-socket string container runtime socket to use, default to internal containerd. Format: [remote|docker]:[path-to-socket] --data-dir string Data Directory for k0s. DO NOT CHANGE for an existing setup, things will break! (default `+defaultDataDir+`) - -d, --debug Debug logging (default: false) + -d, --debug Debug logging (implies verbose logging) --debugListenOn string Http listenOn for Debug pprof handler (default ":6060") --disable-components strings disable components (valid items: applier-manager,autopilot,control-api,coredns,csr-approver,endpoint-reconciler,helm,konnectivity-server,kube-controller-manager,kube-proxy,kube-scheduler,metrics-server,network-provider,node-role,system-rbac,windows-node,worker-config) --enable-cloud-provider Whether or not to enable cloud provider support in kubelet @@ -82,6 +82,6 @@ Flags: --status-socket string Full file path to the socket file. (default: /status.sock) --taints strings Node taints, list of key=value:effect strings --token-file string Path to the file containing join-token. - -v, --verbose Verbose logging (default: false) + -v, --verbose Verbose logging (default true) `, out.String()) } diff --git a/cmd/etcd/etcd.go b/cmd/etcd/etcd.go index f96a7564a979..554d7a33c74a 100644 --- a/cmd/etcd/etcd.go +++ b/cmd/etcd/etcd.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" "github.com/k0sproject/k0s/pkg/config" @@ -27,14 +28,14 @@ import ( ) func NewEtcdCmd() *cobra.Command { + var debugFlags internal.DebugFlags + cmd := &cobra.Command{ Use: "etcd", Short: "Manage etcd cluster", Args: cobra.NoArgs, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - if err := config.CallParentPersistentPreRun(cmd, args); err != nil { - return err - } + debugFlags.Run(cmd, args) opts, err := config.GetCmdOpts(cmd) if err != nil { @@ -54,8 +55,11 @@ func NewEtcdCmd() *cobra.Command { }, Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, } + + debugFlags.AddToFlagSet(cmd.PersistentFlags()) + cmd.AddCommand(etcdLeaveCmd()) cmd.AddCommand(etcdListCmd()) - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/etcd/leave.go b/cmd/etcd/leave.go index 19020b9382da..868569e58570 100644 --- a/cmd/etcd/leave.go +++ b/cmd/etcd/leave.go @@ -86,13 +86,14 @@ func etcdLeaveCmd() *cobra.Command { }, } + cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + cmd.Flags().AddFlag(&pflag.Flag{ Name: "peer-address", Usage: "etcd peer address to remove (default )", Value: (*ipOrDNSName)(&peerAddressArg), }) - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) return cmd } diff --git a/cmd/etcd/list.go b/cmd/etcd/list.go index 61e7bb324f67..6fd74b6edbc7 100644 --- a/cmd/etcd/list.go +++ b/cmd/etcd/list.go @@ -57,6 +57,8 @@ func etcdListCmd() *cobra.Command { return json.NewEncoder(cmd.OutOrStdout()).Encode(map[string]interface{}{"members": members}) }, } + cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/install/controller.go b/cmd/install/controller.go index 36e62c01b252..35c6bad031a7 100644 --- a/cmd/install/controller.go +++ b/cmd/install/controller.go @@ -66,9 +66,11 @@ With the controller subcommand you can setup a single node cluster by running: return nil }, } - // append flags + cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + cmd.Flags().AddFlagSet(config.GetControllerFlags()) cmd.Flags().AddFlagSet(config.GetWorkerFlags()) + return cmd } diff --git a/cmd/install/controller_test.go b/cmd/install/controller_test.go index 0571ff991fb7..52539c8843a5 100644 --- a/cmd/install/controller_test.go +++ b/cmd/install/controller_test.go @@ -58,8 +58,6 @@ Flags: -c, --config string config file, use '-' to read the config from stdin (default `+defaultConfigPath+`) --cri-socket string container runtime socket to use, default to internal containerd. Format: [remote|docker]:[path-to-socket] --data-dir string Data Directory for k0s. DO NOT CHANGE for an existing setup, things will break! (default `+defaultDataDir+`) - -d, --debug Debug logging (default: false) - --debugListenOn string Http listenOn for Debug pprof handler (default ":6060") --disable-components strings disable components (valid items: applier-manager,autopilot,control-api,coredns,csr-approver,endpoint-reconciler,helm,konnectivity-server,kube-controller-manager,kube-proxy,kube-scheduler,metrics-server,network-provider,node-role,system-rbac,windows-node,worker-config) --enable-cloud-provider Whether or not to enable cloud provider support in kubelet --enable-dynamic-config enable cluster-wide dynamic config based on custom resource @@ -80,10 +78,12 @@ Flags: --status-socket string Full file path to the socket file. (default: /status.sock) --taints strings Node taints, list of key=value:effect strings --token-file string Path to the file containing join-token. - -v, --verbose Verbose logging (default: false) Global Flags: - -e, --env stringArray set environment variable - --force force init script creation + -d, --debug Debug logging (implies verbose logging) + --debugListenOn string Http listenOn for Debug pprof handler (default ":6060") + -e, --env stringArray set environment variable + --force force init script creation + -v, --verbose Verbose logging `, out.String()) } diff --git a/cmd/install/install.go b/cmd/install/install.go index 11bd266faa30..833be57cf4a7 100644 --- a/cmd/install/install.go +++ b/cmd/install/install.go @@ -21,6 +21,7 @@ import ( "fmt" "os" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/pkg/config" "github.com/k0sproject/k0s/pkg/install" @@ -35,20 +36,27 @@ type installFlags struct { } func NewInstallCmd() *cobra.Command { - var installFlags installFlags + var ( + debugFlags internal.DebugFlags + installFlags installFlags + ) cmd := &cobra.Command{ - Use: "install", - Short: "Install k0s on a brand-new system. Must be run as root (or with sudo)", - Args: cobra.NoArgs, - Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, + Use: "install", + Short: "Install k0s on a brand-new system. Must be run as root (or with sudo)", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, + Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, } + pflags := cmd.PersistentFlags() + debugFlags.AddToFlagSet(pflags) + pflags.BoolVar(&installFlags.force, "force", false, "force init script creation") + pflags.StringArrayVarP(&installFlags.envVars, "env", "e", nil, "set environment variable") + cmd.AddCommand(installControllerCmd(&installFlags)) cmd.AddCommand(installWorkerCmd(&installFlags)) - cmd.PersistentFlags().BoolVar(&installFlags.force, "force", false, "force init script creation") - cmd.PersistentFlags().StringArrayVarP(&installFlags.envVars, "env", "e", nil, "set environment variable") - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/install/worker.go b/cmd/install/worker.go index 55c79cb7dc8a..916ef66d3a24 100644 --- a/cmd/install/worker.go +++ b/cmd/install/worker.go @@ -51,9 +51,10 @@ Windows flags like "--api-server", "--cidr-range" and "--cluster-dns" will be ig return nil }, } - // append flags - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) - cmd.PersistentFlags().AddFlagSet(config.GetWorkerFlags()) + + pflags := cmd.PersistentFlags() + pflags.AddFlagSet(config.GetPersistentFlagSet()) + pflags.AddFlagSet(config.GetWorkerFlags()) return cmd } diff --git a/cmd/internal/debug.go b/cmd/internal/debug.go new file mode 100644 index 000000000000..f58869b99be7 --- /dev/null +++ b/cmd/internal/debug.go @@ -0,0 +1,105 @@ +/* +Copyright 2024 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. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "errors" + "net/http" + _ "net/http/pprof" + "os" + "strconv" + + internallog "github.com/k0sproject/k0s/internal/pkg/log" + + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +type DebugFlags struct { + logsToStdout bool + verbose bool + verboseByDefault bool + debug bool + debugListenOn string +} + +func (f *DebugFlags) IsDebug() bool { + return f.debug +} + +// Configures the debug flags for long-running commands. +// Must be called before adding the flags to a FlagSet. +func (f *DebugFlags) LongRunning() *DebugFlags { + f.logsToStdout = true + + // The default value won't be reflected in the flag set + // once the flags have been added. + f.verboseByDefault = true + + return f +} + +// Adds the debug flags to the given FlagSet. +func (f *DebugFlags) AddToFlagSet(flags *pflag.FlagSet) { + flags.BoolVarP(&f.verbose, "verbose", "v", f.verboseByDefault, "Verbose logging") + flags.BoolVarP(&f.debug, "debug", "d", false, "Debug logging (implies verbose logging)") + flags.StringVar(&f.debugListenOn, "debugListenOn", ":6060", "Http listenOn for Debug pprof handler") +} + +// Adds the debug flags to the given FlagSet when in "kubectl" mode. +// This won't use shorthands, as this will interfere with kubectl's flags. +func (f *DebugFlags) AddToKubectlFlagSet(flags *pflag.FlagSet) { + debugDefault := false + if v, ok := os.LookupEnv("DEBUG"); ok { + debugDefault, _ = strconv.ParseBool(v) + } + + flags.BoolVar(&f.debug, "debug", debugDefault, "Debug logging [$DEBUG]") +} + +func (f *DebugFlags) Run(cmd *cobra.Command, _ []string) { + if f.logsToStdout { + logrus.SetOutput(cmd.OutOrStdout()) + } + + switch { + case f.debug: + internallog.SetDebugLevel() + + if f.verbose { + if !f.verboseByDefault { + logrus.Debug("--debug already implies --verbose") + } + } else if f.verboseByDefault { + logrus.Debug("--debug overrides --verbose=false") + } + + go func() { + log := logrus.WithField("debug_server", f.debugListenOn) + log.Debug("Starting debug server") + if err := http.ListenAndServe(f.debugListenOn, nil); !errors.Is(err, http.ErrServerClosed) { + log.WithError(err).Debug("Failed to start debug server") + } else { + log.Debug("Debug server closed") + } + }() + + case f.verbose: + internallog.SetInfoLevel() + } +} diff --git a/cmd/kubeconfig/admin.go b/cmd/kubeconfig/admin.go index e96f5fcb921f..ecc2709ec6f2 100644 --- a/cmd/kubeconfig/admin.go +++ b/cmd/kubeconfig/admin.go @@ -87,6 +87,8 @@ func kubeConfigAdminCmd() *cobra.Command { return err }, } + cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/kubeconfig/create.go b/cmd/kubeconfig/create.go index 6a50066ee783..c533b5370d71 100644 --- a/cmd/kubeconfig/create.go +++ b/cmd/kubeconfig/create.go @@ -77,9 +77,11 @@ Note: A certificate once signed cannot be revoked for a particular user`, }, } + cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + cmd.Flags().AddFlagSet(config.FileInputFlag()) cmd.Flags().StringVar(&groups, "groups", "", "Specify groups") - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/kubeconfig/kubeconfig.go b/cmd/kubeconfig/kubeconfig.go index 888bdd9eb3c9..254e1ee41259 100644 --- a/cmd/kubeconfig/kubeconfig.go +++ b/cmd/kubeconfig/kubeconfig.go @@ -17,20 +17,26 @@ limitations under the License. package kubeconfig import ( - "github.com/k0sproject/k0s/pkg/config" + "github.com/k0sproject/k0s/cmd/internal" "github.com/spf13/cobra" ) func NewKubeConfigCmd() *cobra.Command { + var debugFlags internal.DebugFlags + cmd := &cobra.Command{ - Use: "kubeconfig [command]", - Short: "Create a kubeconfig file for a specified user", - Args: cobra.NoArgs, - Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, + Use: "kubeconfig [command]", + Short: "Create a kubeconfig file for a specified user", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, + Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, } + + debugFlags.AddToFlagSet(cmd.PersistentFlags()) + cmd.AddCommand(kubeconfigCreateCmd()) cmd.AddCommand(kubeConfigAdminCmd()) - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/kubectl/kubectl.go b/cmd/kubectl/kubectl.go index 5fa636b5df66..e50e212a9eb8 100644 --- a/cmd/kubectl/kubectl.go +++ b/cmd/kubectl/kubectl.go @@ -26,6 +26,7 @@ import ( "slices" "strings" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/pkg/config" "k8s.io/cli-runtime/pkg/genericclioptions" @@ -104,6 +105,7 @@ func hookKubectlPluginHandler(kubectlCmd *cobra.Command) { // Intercept kubectl's PreRunE, so that generic k0s flags are honored and // kubectl plugins may be handled properly, e.g. so that `k0s kc foo bar` // works as expected when there's a `kubectl-foo` plugin installed. + var debugFlags internal.DebugFlags originalPreRunE := kubectlCmd.PersistentPreRunE kubectlCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { handleKubectlPlugins(kubectlCmd) @@ -126,9 +128,7 @@ func hookKubectlPluginHandler(kubectlCmd *cobra.Command) { logs.InitLogs() cobra.OnFinalize(logs.FlushLogs) - if err := config.CallParentPersistentPreRun(kubectlCmd, args); err != nil { - return err - } + debugFlags.Run(kubectlCmd, args) if err := fallbackToK0sKubeconfig(cmd); err != nil { return err @@ -136,6 +136,8 @@ func hookKubectlPluginHandler(kubectlCmd *cobra.Command) { return originalPreRunE(cmd, args) } + + debugFlags.AddToKubectlFlagSet(kubectlCmd.PersistentFlags()) } // handleKubectlPlugins calls kubectl's plugin handler and execs the plugin diff --git a/cmd/reset/reset.go b/cmd/reset/reset.go index 908c1540f7c5..7f0ecc2eaafe 100644 --- a/cmd/reset/reset.go +++ b/cmd/reset/reset.go @@ -21,6 +21,7 @@ import ( "fmt" "os" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/pkg/cleanup" "github.com/k0sproject/k0s/pkg/component/status" "github.com/k0sproject/k0s/pkg/config" @@ -32,26 +33,35 @@ import ( type command config.CLIOptions func NewResetCmd() *cobra.Command { + var debugFlags internal.DebugFlags + cmd := &cobra.Command{ - Use: "reset", - Short: "Uninstall k0s. Must be run as root (or with sudo)", - Args: cobra.NoArgs, + Use: "reset", + Short: "Uninstall k0s. Must be run as root (or with sudo)", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, RunE: func(cmd *cobra.Command, _ []string) error { opts, err := config.GetCmdOpts(cmd) if err != nil { return err } c := (*command)(opts) - return c.reset() + return c.reset(debugFlags.IsDebug()) }, } - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) - cmd.Flags().AddFlagSet(config.GetCriSocketFlag()) - cmd.Flags().AddFlagSet(config.FileInputFlag()) + + pflags := cmd.PersistentFlags() + debugFlags.AddToFlagSet(pflags) + pflags.AddFlagSet(config.GetPersistentFlagSet()) + + flags := cmd.Flags() + flags.AddFlagSet(config.GetCriSocketFlag()) + flags.AddFlagSet(config.FileInputFlag()) + return cmd } -func (c *command) reset() error { +func (c *command) reset(debug bool) error { if os.Geteuid() != 0 { return errors.New("this command must be run as root!") } @@ -70,7 +80,7 @@ func (c *command) reset() error { } // Get Cleanup Config - cfg, err := cleanup.NewConfig(c.Debug, c.K0sVars, c.WorkerOptions.CriSocket) + cfg, err := cleanup.NewConfig(debug, c.K0sVars, c.WorkerOptions.CriSocket) if err != nil { return fmt.Errorf("failed to configure cleanup: %w", err) } diff --git a/cmd/restore/restore_unix.go b/cmd/restore/restore_unix.go index 08845f726534..75de8b591231 100644 --- a/cmd/restore/restore_unix.go +++ b/cmd/restore/restore_unix.go @@ -27,6 +27,7 @@ import ( "path/filepath" "strings" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/internal/pkg/dir" "github.com/k0sproject/k0s/internal/pkg/file" "github.com/k0sproject/k0s/pkg/backup" @@ -44,12 +45,16 @@ type command struct { } func NewRestoreCmd() *cobra.Command { - var restoredConfigPath string + var ( + debugFlags internal.DebugFlags + restoredConfigPath string + ) cmd := &cobra.Command{ - Use: "restore filename", - Short: "restore k0s state from given backup archive. Use '-' as filename to read from stdin. Must be run as root (or with sudo)", - Args: cobra.ExactArgs(1), + Use: "restore filename", + Short: "restore k0s state from given backup archive. Use '-' as filename to read from stdin. Must be run as root (or with sudo)", + Args: cobra.ExactArgs(1), + PersistentPreRun: debugFlags.Run, RunE: func(cmd *cobra.Command, args []string) error { opts, err := config.GetCmdOpts(cmd) if err != nil { @@ -67,9 +72,13 @@ func NewRestoreCmd() *cobra.Command { logrus.Fatal("failed to get local path") } + pflags := cmd.PersistentFlags() + debugFlags.AddToFlagSet(pflags) + pflags.AddFlagSet(config.GetPersistentFlagSet()) + restoredConfigPathDescription := fmt.Sprintf("Specify desired name and full path for the restored k0s.yaml file (default: %s/k0s_.yaml", cwd) cmd.Flags().StringVar(&restoredConfigPath, "config-out", "", restoredConfigPathDescription) - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/root.go b/cmd/root.go index a4b8f164c4c0..66ce72895d06 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -18,7 +18,6 @@ package cmd import ( "errors" - "net/http" "os" "runtime" @@ -42,11 +41,8 @@ import ( "github.com/k0sproject/k0s/cmd/validate" "github.com/k0sproject/k0s/cmd/version" "github.com/k0sproject/k0s/cmd/worker" - k0slog "github.com/k0sproject/k0s/internal/pkg/log" "github.com/k0sproject/k0s/pkg/build" - "github.com/k0sproject/k0s/pkg/config" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" ) @@ -58,27 +54,6 @@ func NewRootCmd() *cobra.Command { Use: "k0s", Short: "k0s - Zero Friction Kubernetes", SilenceUsage: true, - - PersistentPreRun: func(cmd *cobra.Command, args []string) { - if config.Verbose { - k0slog.SetInfoLevel() - } - - if config.Debug { - // TODO: check if it actually works and is not overwritten by something else - k0slog.SetDebugLevel() - - go func() { - log := logrus.WithField("debug_server", config.DebugListenOn) - log.Debug("Starting debug server") - if err := http.ListenAndServe(config.DebugListenOn, nil); !errors.Is(err, http.ErrServerClosed) { - log.WithError(err).Debug("Failed to start debug server") - } else { - log.Debug("Debug server closed") - } - }() - } - }, } cmd.AddCommand(airgap.NewAirgapCmd()) diff --git a/cmd/start/start.go b/cmd/start/start.go index c0e511e04bb8..58ed2a87f459 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -20,6 +20,7 @@ import ( "errors" "os" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/pkg/install" "github.com/kardianos/service" @@ -27,10 +28,13 @@ import ( ) func NewStartCmd() *cobra.Command { - return &cobra.Command{ - Use: "start", - Short: "Start the k0s service configured on this host. Must be run as root (or with sudo)", - Args: cobra.NoArgs, + var debugFlags internal.DebugFlags + + cmd := &cobra.Command{ + Use: "start", + Short: "Start the k0s service configured on this host. Must be run as root (or with sudo)", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, RunE: func(cmd *cobra.Command, _ []string) error { if os.Geteuid() != 0 { return errors.New("this command must be run as root") @@ -47,4 +51,7 @@ func NewStartCmd() *cobra.Command { }, } + debugFlags.AddToFlagSet(cmd.PersistentFlags()) + + return cmd } diff --git a/cmd/status/status.go b/cmd/status/status.go index f797b6ebd033..76609b61f80b 100644 --- a/cmd/status/status.go +++ b/cmd/status/status.go @@ -20,8 +20,8 @@ import ( "encoding/json" "fmt" "io" - "path/filepath" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/pkg/component/status" "github.com/k0sproject/k0s/pkg/config" @@ -30,12 +30,17 @@ import ( ) func NewStatusCmd() *cobra.Command { - var output string + var ( + debugFlags internal.DebugFlags + output string + ) + cmd := &cobra.Command{ - Use: "status", - Short: "Get k0s instance status information", - Example: `The command will return information about system init, PID, k0s role, kubeconfig and similar.`, - Args: cobra.NoArgs, + Use: "status", + Short: "Get k0s instance status information", + Example: `The command will return information about system init, PID, k0s role, kubeconfig and similar.`, + PersistentPreRun: debugFlags.Run, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { opts, err := config.GetCmdOpts(cmd) if err != nil { @@ -55,9 +60,13 @@ func NewStatusCmd() *cobra.Command { }, } - cmd.PersistentFlags().StringVarP(&output, "out", "o", "", "sets type of output to json or yaml") - cmd.PersistentFlags().StringVar(&config.StatusSocket, "status-socket", filepath.Join(config.K0sVars.RunDir, "status.sock"), "Full file path to the socket file.") + pflags := cmd.PersistentFlags() + debugFlags.AddToFlagSet(pflags) + pflags.AddFlagSet(config.GetPersistentFlagSet()) + pflags.StringVarP(&output, "out", "o", "", "sets type of output to json or yaml") + cmd.AddCommand(NewStatusSubCmdComponents()) + return cmd } diff --git a/cmd/stop/stop.go b/cmd/stop/stop.go index 69429b9d26c0..77a7a58d1fe6 100644 --- a/cmd/stop/stop.go +++ b/cmd/stop/stop.go @@ -20,6 +20,7 @@ import ( "errors" "os" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/pkg/install" "github.com/kardianos/service" @@ -27,10 +28,13 @@ import ( ) func NewStopCmd() *cobra.Command { - return &cobra.Command{ - Use: "stop", - Short: "Stop the k0s service configured on this host. Must be run as root (or with sudo)", - Args: cobra.NoArgs, + var debugFlags internal.DebugFlags + + cmd := &cobra.Command{ + Use: "stop", + Short: "Stop the k0s service configured on this host. Must be run as root (or with sudo)", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, RunE: func(cmd *cobra.Command, _ []string) error { if os.Geteuid() != 0 { return errors.New("this command must be run as root") @@ -50,4 +54,7 @@ func NewStopCmd() *cobra.Command { }, } + debugFlags.AddToFlagSet(cmd.PersistentFlags()) + + return cmd } diff --git a/cmd/sysinfo/sysinfo.go b/cmd/sysinfo/sysinfo.go index 3ac0e433e38e..f8e8391d9b2f 100644 --- a/cmd/sysinfo/sysinfo.go +++ b/cmd/sysinfo/sysinfo.go @@ -21,6 +21,7 @@ import ( "io" "strings" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/internal/pkg/sysinfo" "github.com/k0sproject/k0s/internal/pkg/sysinfo/probes" "github.com/k0sproject/k0s/pkg/constant" @@ -31,14 +32,17 @@ import ( ) func NewSysinfoCmd() *cobra.Command { - - var sysinfoSpec sysinfo.K0sSysinfoSpec + var ( + debugFlags internal.DebugFlags + sysinfoSpec sysinfo.K0sSysinfoSpec + ) cmd := &cobra.Command{ - Use: "sysinfo", - Short: "Display system information", - Long: `Runs k0s's pre-flight checks and issues the results to stdout.`, - Args: cobra.NoArgs, + Use: "sysinfo", + Short: "Display system information", + Long: `Runs k0s's pre-flight checks and issues the results to stdout.`, + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, RunE: func(cmd *cobra.Command, _ []string) error { sysinfoSpec.AddDebugProbes = true probes := sysinfoSpec.NewSysinfoProbes() @@ -60,6 +64,8 @@ func NewSysinfoCmd() *cobra.Command { }, } + debugFlags.AddToFlagSet(cmd.PersistentFlags()) + // append flags flags := cmd.Flags() flags.BoolVar(&sysinfoSpec.ControllerRoleEnabled, "controller", true, "Include controller-specific sysinfo") diff --git a/cmd/token/create.go b/cmd/token/create.go index 05e24e45ae2c..8e7969627b8c 100644 --- a/cmd/token/create.go +++ b/cmd/token/create.go @@ -96,11 +96,14 @@ k0s token create --role worker --expiry 10m //sets expiration time to 10 minute return nil }, } + // append flags cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) - 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)") + + flags := cmd.Flags() + flags.StringVar(&tokenExpiry, "expiry", "0s", "Expiration time of the token. Format 1.5h, 2h45m or 300ms.") + flags.StringVar(&createTokenRole, "role", "worker", "Either worker or controller") + flags.BoolVar(&waitCreate, "wait", false, "wait forever (default false)") return cmd } diff --git a/cmd/token/invalidate.go b/cmd/token/invalidate.go index 8fe6ff68829a..02784015fdd6 100644 --- a/cmd/token/invalidate.go +++ b/cmd/token/invalidate.go @@ -51,6 +51,8 @@ func tokenInvalidateCmd() *cobra.Command { return nil }, } + cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + return cmd } diff --git a/cmd/token/list.go b/cmd/token/list.go index 493d8d6318f7..c066f694cd93 100644 --- a/cmd/token/list.go +++ b/cmd/token/list.go @@ -78,7 +78,10 @@ func tokenListCmd() *cobra.Command { return nil }, } - cmd.Flags().StringVar(&listTokenRole, "role", "", "Either worker, controller or empty for all roles") + cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + + cmd.Flags().StringVar(&listTokenRole, "role", "", "Either worker, controller or empty for all roles") + return cmd } diff --git a/cmd/token/preshared.go b/cmd/token/preshared.go index 8bb62d778b70..ff0114c846c0 100644 --- a/cmd/token/preshared.go +++ b/cmd/token/preshared.go @@ -35,6 +35,7 @@ import ( "github.com/k0sproject/k0s/pkg/token" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) func preSharedCmd() *cobra.Command { @@ -78,12 +79,21 @@ func preSharedCmd() *cobra.Command { return nil }, } - cmd.Flags().StringVar(&certPath, "cert", "", "path to the CA certificate file") - cmd.Flags().StringVar(&joinURL, "url", "", "url of the api server to join") - cmd.Flags().StringVar(&preSharedRole, "role", "worker", "token role. valid values: worker, controller. Default: worker") - cmd.Flags().StringVar(&outDir, "out", ".", "path to the output directory. Default: current dir") - cmd.Flags().DurationVar(&validity, "valid", 0, "how long token is valid, in Go duration format") - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) + + pflags := cmd.PersistentFlags() + // Add unused persistent flags for backwards compatibility. + config.GetPersistentFlagSet().VisitAll(func(f *pflag.Flag) { + f.Hidden = true + pflags.AddFlag(f) + }) + + flags := cmd.Flags() + flags.StringVar(&certPath, "cert", "", "path to the CA certificate file") + flags.StringVar(&joinURL, "url", "", "url of the api server to join") + flags.StringVar(&preSharedRole, "role", "worker", "token role. valid values: worker, controller. Default: worker") + flags.StringVar(&outDir, "out", ".", "path to the output directory. Default: current dir") + flags.DurationVar(&validity, "valid", 0, "how long token is valid, in Go duration format") + return cmd } diff --git a/cmd/token/token.go b/cmd/token/token.go index dee7086113d7..52ac71f5bda5 100644 --- a/cmd/token/token.go +++ b/cmd/token/token.go @@ -19,23 +19,30 @@ package token import ( "fmt" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/pkg/token" "github.com/spf13/cobra" ) func NewTokenCmd() *cobra.Command { + var debugFlags internal.DebugFlags + cmd := &cobra.Command{ - Use: "token", - Short: "Manage join tokens", - Args: cobra.NoArgs, - Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, + Use: "token", + Short: "Manage join tokens", + Args: cobra.NoArgs, + PersistentPreRun: debugFlags.Run, + Run: func(*cobra.Command, []string) { /* Enforce arg validation. */ }, } + debugFlags.AddToFlagSet(cmd.PersistentFlags()) + cmd.AddCommand(tokenCreateCmd()) cmd.AddCommand(tokenListCmd()) cmd.AddCommand(tokenInvalidateCmd()) cmd.AddCommand(preSharedCmd()) + return cmd } diff --git a/cmd/worker/worker.go b/cmd/worker/worker.go index 13c03c0c36ad..c792db0334aa 100644 --- a/cmd/worker/worker.go +++ b/cmd/worker/worker.go @@ -25,7 +25,7 @@ import ( "runtime" "syscall" - k0slog "github.com/k0sproject/k0s/internal/pkg/log" + "github.com/k0sproject/k0s/cmd/internal" "github.com/k0sproject/k0s/internal/pkg/sysinfo" "github.com/k0sproject/k0s/pkg/build" "github.com/k0sproject/k0s/pkg/component/iptables" @@ -46,7 +46,10 @@ import ( type Command config.CLIOptions func NewWorkerCmd() *cobra.Command { - var ignorePreFlightChecks bool + var ( + debugFlags internal.DebugFlags + ignorePreFlightChecks bool + ) cmd := &cobra.Command{ Use: "worker [join-token]", @@ -58,12 +61,8 @@ func NewWorkerCmd() *cobra.Command { or CLI flag: $ k0s worker --token-file [path_to_file] Note: Token can be passed either as a CLI argument or as a flag`, - Args: cobra.MaximumNArgs(1), - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - logrus.SetOutput(cmd.OutOrStdout()) - k0slog.SetInfoLevel() - return config.CallParentPersistentPreRun(cmd, args) - }, + Args: cobra.MaximumNArgs(1), + PersistentPreRun: debugFlags.Run, RunE: func(cmd *cobra.Command, args []string) error { opts, err := config.GetCmdOpts(cmd) if err != nil { @@ -95,10 +94,13 @@ func NewWorkerCmd() *cobra.Command { }, } - // append flags + pflags := cmd.PersistentFlags() + debugFlags.LongRunning().AddToFlagSet(pflags) + pflags.AddFlagSet(config.GetPersistentFlagSet()) + pflags.AddFlagSet(config.GetWorkerFlags()) + cmd.Flags().BoolVar(&ignorePreFlightChecks, "ignore-pre-flight-checks", false, "continue even if pre-flight checks fail") - cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet()) - cmd.PersistentFlags().AddFlagSet(config.GetWorkerFlags()) + return cmd } diff --git a/main.go b/main.go index 2ea483358293..ac3541ba7386 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,6 @@ limitations under the License. package main import ( - _ "net/http/pprof" "os" "path" "strings" diff --git a/pkg/config/cli.go b/pkg/config/cli.go index 2cca62e56b25..4d590379b95e 100644 --- a/pkg/config/cli.go +++ b/pkg/config/cli.go @@ -18,9 +18,7 @@ package config import ( "fmt" - "os" "slices" - "strconv" "strings" "time" @@ -28,18 +26,14 @@ import ( "github.com/k0sproject/k0s/pkg/constant" "github.com/k0sproject/k0s/pkg/k0scloudprovider" - "github.com/spf13/cobra" "github.com/spf13/pflag" ) var ( CfgFile string - Debug bool - DebugListenOn string StatusSocket string K0sVars CfgVars workerOpts WorkerOptions - Verbose bool controllerOpts ControllerOptions ) @@ -48,11 +42,8 @@ var ( type CLIOptions struct { WorkerOptions ControllerOptions - CfgFile string - Debug bool - DebugListenOn string - K0sVars *CfgVars - Verbose bool + CfgFile string + K0sVars *CfgVars } // Shared controller cli flags @@ -196,25 +187,14 @@ func (f *logLevelsFlag) String() string { func GetPersistentFlagSet() *pflag.FlagSet { flagset := &pflag.FlagSet{} - flagset.BoolVarP(&Debug, "debug", "d", false, "Debug logging (default: false)") - flagset.BoolVarP(&Verbose, "verbose", "v", false, "Verbose logging (default: false)") flagset.String("data-dir", constant.DataDirDefault, "Data Directory for k0s. DO NOT CHANGE for an existing setup, things will break!") flagset.StringVar(&StatusSocket, "status-socket", "", "Full file path to the socket file. (default: /status.sock)") - flagset.StringVar(&DebugListenOn, "debugListenOn", ":6060", "Http listenOn for Debug pprof handler") return flagset } -// XX: not a pretty hack, but we need the data-dir flag for the kubectl subcommand -// XX: when other global flags cannot be used (specifically -d and -c) func GetKubeCtlFlagSet() *pflag.FlagSet { - debugDefault := false - if v, ok := os.LookupEnv("DEBUG"); ok { - debugDefault, _ = strconv.ParseBool(v) - } - flagset := &pflag.FlagSet{} flagset.String("data-dir", constant.DataDirDefault, "Data Directory for k0s. DO NOT CHANGE for an existing setup, things will break!") - flagset.BoolVar(&Debug, "debug", debugDefault, "Debug logging [$DEBUG]") return flagset } @@ -313,41 +293,7 @@ func GetCmdOpts(cobraCmd command) (*CLIOptions, error) { ControllerOptions: controllerOpts, WorkerOptions: workerOpts, - CfgFile: CfgFile, - Debug: Debug, - Verbose: Verbose, - K0sVars: k0sVars, - DebugListenOn: DebugListenOn, + CfgFile: CfgFile, + K0sVars: k0sVars, }, nil } - -// CallParentPersistentPreRun runs the parent command's persistent pre-run. -// Cobra does not do this automatically. -// -// See: https://github.com/spf13/cobra/issues/216 -// See: https://github.com/spf13/cobra/blob/v1.4.0/command.go#L833-L843 -func CallParentPersistentPreRun(cmd *cobra.Command, args []string) error { - for p := cmd.Parent(); p != nil; p = p.Parent() { - preRunE := p.PersistentPreRunE - preRun := p.PersistentPreRun - - p.PersistentPreRunE = nil - p.PersistentPreRun = nil - - defer func() { - p.PersistentPreRunE = preRunE - p.PersistentPreRun = preRun - }() - - if preRunE != nil { - return preRunE(cmd, args) - } - - if preRun != nil { - preRun(cmd, args) - return nil - } - } - - return nil -}