From 69682b75e508462e01f865a156f2171233b653d1 Mon Sep 17 00:00:00 2001 From: Maciej Szulik Date: Thu, 8 May 2025 13:29:11 +0200 Subject: [PATCH 1/2] Manually read verbosity before kubectl command construction kubectl command construction is slowly getting more functionality which sometimes requires to log certain actions. Currently we parse the verbosity only when actually running the command, so all of construction code is not able to use -v=5. This commit adds the manual parsing and loglevel setting berore we even start creating the kubectl command. Signed-off-by: Maciej Szulik --- cmd/kubectl/kubectl.go | 10 +++++++++ staging/src/k8s.io/kubectl/pkg/cmd/cmd.go | 26 +++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/cmd/kubectl/kubectl.go b/cmd/kubectl/kubectl.go index 09c18cfa209..4351585e684 100644 --- a/cmd/kubectl/kubectl.go +++ b/cmd/kubectl/kubectl.go @@ -17,7 +17,10 @@ limitations under the License. package main import ( + "os" + "k8s.io/component-base/cli" + "k8s.io/component-base/logs" "k8s.io/kubectl/pkg/cmd" "k8s.io/kubectl/pkg/cmd/util" @@ -26,6 +29,13 @@ import ( ) func main() { + // We need to manually parse the arguments looking for verbosity flag and + // set appropriate level here, because in the normal flow the flag parsing, + // including the logging verbosity, happens inside cli.RunNoErrOutput. + // Doing it here ensures we can continue using klog during kubectl command + // construction, which includes handling plugins and parsing .kuberc file, + // for example. + logs.GlogSetter(cmd.GetLogVerbosity(os.Args)) // nolint:errcheck command := cmd.NewDefaultKubectlCommand() if err := cli.RunNoErrOutput(command); err != nil { // Pretty-print the error and exit with an error. diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/cmd.go b/staging/src/k8s.io/kubectl/pkg/cmd/cmd.go index ed3772c5adf..ccf85a55c9a 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/cmd.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/cmd.go @@ -583,3 +583,29 @@ func registerCompletionFuncForGlobalFlags(cmd *cobra.Command, f cmdutil.Factory) return utilcomp.ListUsersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp })) } + +// GetLogVerbosity parses the provided command-line arguments to determine +// the verbosity level for logging. Returns string representing the verbosity +// level, or 0 if no verbosity flag is specified. +func GetLogVerbosity(args []string) string { + for i, arg := range args { + if arg == "--" { + // flags after "--" does not represent any flag of + // the command. We should short cut the iteration in here. + break + } + + if arg == "--v" || arg == "-v" { + if i+1 < len(args) { + return args[i+1] + } + } else if strings.Contains(arg, "--v=") || strings.Contains(arg, "-v=") { + parg := strings.Split(arg, "=") + if len(parg) > 1 && parg[1] != "" { + return parg[1] + } + } + } + + return "0" +} From 6cca37b36febf5fec646782a9499c18db91d566f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arda=20G=C3=BC=C3=A7l=C3=BC?= Date: Mon, 14 Apr 2025 15:30:09 +0300 Subject: [PATCH 2/2] Add integration test for log verbosity --- test/cmd/kuberc.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/cmd/kuberc.sh b/test/cmd/kuberc.sh index a9702dca7ce..2942544141b 100755 --- a/test/cmd/kuberc.sh +++ b/test/cmd/kuberc.sh @@ -184,6 +184,18 @@ EOF # assure that warning message is also printed for the notexist kuberc version kube::test::if_has_string "${output_message}" "strict decoding error" "unknown" + touch "${TMPDIR:-/tmp}"/empty_kuberc_file + output_message=$(kubectl get namespace test-kuberc-ns 2>&1 "${kube_flags[@]:?}" --kuberc="${TMPDIR:-/tmp}"/empty_kuberc_file) + kube::test::if_has_not_string "${output_message}" "kuberc: no preferences found in" + output_message=$(kubectl get namespace test-kuberc-ns 2>&1 "${kube_flags[@]:?}" --kuberc="${TMPDIR:-/tmp}"/empty_kuberc_file -v=5) + kube::test::if_has_string "${output_message}" "kuberc: no preferences found in" + output_message=$(kubectl get namespace test-kuberc-ns 2>&1 -v 5 "${kube_flags[@]:?}" --kuberc="${TMPDIR:-/tmp}"/empty_kuberc_file) + kube::test::if_has_string "${output_message}" "kuberc: no preferences found in" + output_message=$(kubectl get namespace test-kuberc-ns 2>&1 "${kube_flags[@]:?}" --v=5 --kuberc="${TMPDIR:-/tmp}"/empty_kuberc_file) + kube::test::if_has_string "${output_message}" "kuberc: no preferences found in" + output_message=$(kubectl get --v 5 namespace test-kuberc-ns 2>&1 "${kube_flags[@]:?}" --kuberc="${TMPDIR:-/tmp}"/empty_kuberc_file) + kube::test::if_has_string "${output_message}" "kuberc: no preferences found in" + # explicitly overwriting the value that is also defaulted in kuberc and # assure that explicit value supersedes output_message=$(kubectl delete namespace/test-kuberc-ns --interactive=false --kuberc="${TMPDIR:-/tmp}"/kuberc_file)