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" +} 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)