mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
cmd: silence warnings in kube-controller-manager/kube-apiserver, dedupe/color warnings in kubectl
This commit is contained in:
parent
e4bb1daecf
commit
0d674c4edb
@ -53,6 +53,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/util/webhook"
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
clientgoinformers "k8s.io/client-go/informers"
|
clientgoinformers "k8s.io/client-go/informers"
|
||||||
clientgoclientset "k8s.io/client-go/kubernetes"
|
clientgoclientset "k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/util/keyutil"
|
"k8s.io/client-go/util/keyutil"
|
||||||
cloudprovider "k8s.io/cloud-provider"
|
cloudprovider "k8s.io/cloud-provider"
|
||||||
cliflag "k8s.io/component-base/cli/flag"
|
cliflag "k8s.io/component-base/cli/flag"
|
||||||
@ -100,6 +101,12 @@ cluster's shared state through which all other components interact.`,
|
|||||||
|
|
||||||
// stop printing usage when the command errors
|
// stop printing usage when the command errors
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
|
PersistentPreRunE: func(*cobra.Command, []string) error {
|
||||||
|
// silence client-go warnings.
|
||||||
|
// kube-apiserver loopback clients should not log self-issued warnings.
|
||||||
|
rest.SetDefaultWarningHandler(rest.NoWarnings{})
|
||||||
|
return nil
|
||||||
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
verflag.PrintAndExitIfRequested()
|
verflag.PrintAndExitIfRequested()
|
||||||
cliflag.PrintFlags(cmd.Flags())
|
cliflag.PrintFlags(cmd.Flags())
|
||||||
|
@ -104,6 +104,13 @@ state of the cluster through the apiserver and makes changes attempting to move
|
|||||||
current state towards the desired state. Examples of controllers that ship with
|
current state towards the desired state. Examples of controllers that ship with
|
||||||
Kubernetes today are the replication controller, endpoints controller, namespace
|
Kubernetes today are the replication controller, endpoints controller, namespace
|
||||||
controller, and serviceaccounts controller.`,
|
controller, and serviceaccounts controller.`,
|
||||||
|
PersistentPreRunE: func(*cobra.Command, []string) error {
|
||||||
|
// silence client-go warnings.
|
||||||
|
// kube-controller-manager generically watches APIs (including deprecated ones),
|
||||||
|
// and CI ensures it works properly against matching kube-apiserver versions.
|
||||||
|
restclient.SetDefaultWarningHandler(restclient.NoWarnings{})
|
||||||
|
return nil
|
||||||
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
verflag.PrintAndExitIfRequested()
|
verflag.PrintAndExitIfRequested()
|
||||||
cliflag.PrintFlags(cmd.Flags())
|
cliflag.PrintFlags(cmd.Flags())
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
cliflag "k8s.io/component-base/cli/flag"
|
cliflag "k8s.io/component-base/cli/flag"
|
||||||
cmdpkg "k8s.io/kubectl/pkg/cmd"
|
cmdpkg "k8s.io/kubectl/pkg/cmd"
|
||||||
@ -69,6 +70,7 @@ import (
|
|||||||
"k8s.io/kubectl/pkg/cmd/wait"
|
"k8s.io/kubectl/pkg/cmd/wait"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
|
"k8s.io/kubectl/pkg/util/term"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/auth"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/auth"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/convert"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/convert"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/cp"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/cp"
|
||||||
@ -428,6 +430,9 @@ func HandlePluginCommand(pluginHandler PluginHandler, cmdArgs []string) error {
|
|||||||
|
|
||||||
// NewKubectlCommand creates the `kubectl` command and its nested children.
|
// NewKubectlCommand creates the `kubectl` command and its nested children.
|
||||||
func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
||||||
|
warningHandler := rest.NewWarningWriter(err, rest.WarningWriterOptions{Deduplicate: true, Color: term.AllowsColorOutput(err)})
|
||||||
|
warningsAsErrors := false
|
||||||
|
|
||||||
// Parent command to which all subcommands are added.
|
// Parent command to which all subcommands are added.
|
||||||
cmds := &cobra.Command{
|
cmds := &cobra.Command{
|
||||||
Use: "kubectl",
|
Use: "kubectl",
|
||||||
@ -441,10 +446,25 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
// Hook before and after Run initialize and write profiles to disk,
|
// Hook before and after Run initialize and write profiles to disk,
|
||||||
// respectively.
|
// respectively.
|
||||||
PersistentPreRunE: func(*cobra.Command, []string) error {
|
PersistentPreRunE: func(*cobra.Command, []string) error {
|
||||||
|
rest.SetDefaultWarningHandler(warningHandler)
|
||||||
return initProfiling()
|
return initProfiling()
|
||||||
},
|
},
|
||||||
PersistentPostRunE: func(*cobra.Command, []string) error {
|
PersistentPostRunE: func(*cobra.Command, []string) error {
|
||||||
return flushProfiling()
|
if err := flushProfiling(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if warningsAsErrors {
|
||||||
|
count := warningHandler.WarningCount()
|
||||||
|
switch count {
|
||||||
|
case 0:
|
||||||
|
// no warnings
|
||||||
|
case 1:
|
||||||
|
return fmt.Errorf("%d warning received", count)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("%d warnings received", count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
BashCompletionFunction: bashCompletionFunc,
|
BashCompletionFunction: bashCompletionFunc,
|
||||||
}
|
}
|
||||||
@ -458,6 +478,8 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
|
|
||||||
addProfilingFlags(flags)
|
addProfilingFlags(flags)
|
||||||
|
|
||||||
|
flags.BoolVar(&warningsAsErrors, "warnings-as-errors", warningsAsErrors, "Treat warnings received from the server as errors and exit with a non-zero exit code")
|
||||||
|
|
||||||
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
|
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
|
||||||
kubeConfigFlags.AddFlags(flags)
|
kubeConfigFlags.AddFlags(flags)
|
||||||
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)
|
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)
|
||||||
|
@ -19,6 +19,7 @@ package term
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"github.com/moby/term"
|
"github.com/moby/term"
|
||||||
|
|
||||||
@ -70,6 +71,32 @@ func IsTerminal(i interface{}) bool {
|
|||||||
return terminal
|
return terminal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllowsColorOutput returns true if the specified writer is a terminal and
|
||||||
|
// the process environment indicates color output is supported and desired.
|
||||||
|
func AllowsColorOutput(w io.Writer) bool {
|
||||||
|
if !IsTerminal(w) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/Computer_terminal#Dumb_terminals
|
||||||
|
if os.Getenv("TERM") == "dumb" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://no-color.org/
|
||||||
|
if _, nocolor := os.LookupEnv("NO_COLOR"); nocolor {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// On Windows WT_SESSION is set by the modern terminal component.
|
||||||
|
// Older terminals have poor support for UTF-8, VT escape codes, etc.
|
||||||
|
if runtime.GOOS == "windows" && os.Getenv("WT_SESSION") == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Safe invokes the provided function and will attempt to ensure that when the
|
// Safe invokes the provided function and will attempt to ensure that when the
|
||||||
// function returns (or a termination signal is sent) that the terminal state
|
// function returns (or a termination signal is sent) that the terminal state
|
||||||
// is reset to the condition it was in prior to the function being invoked. If
|
// is reset to the condition it was in prior to the function being invoked. If
|
||||||
|
@ -145,6 +145,14 @@ run_role_tests() {
|
|||||||
create_and_use_new_namespace
|
create_and_use_new_namespace
|
||||||
kube::log::status "Testing role"
|
kube::log::status "Testing role"
|
||||||
|
|
||||||
|
# Test deprecated API request output
|
||||||
|
# TODO(liggitt): switch this to a custom deprecated resource once CRDs support marking versions as deprecated
|
||||||
|
output_message=$(kubectl get roles.v1beta1.rbac.authorization.k8s.io 2>&1 "${kube_flags[@]}")
|
||||||
|
kube::test::if_has_string "${output_message}" 'Role is deprecated'
|
||||||
|
output_message=$(! kubectl get roles.v1beta1.rbac.authorization.k8s.io --warnings-as-errors 2>&1 "${kube_flags[@]}")
|
||||||
|
kube::test::if_has_string "${output_message}" 'Role is deprecated'
|
||||||
|
kube::test::if_has_string "${output_message}" 'Error: 1 warning received'
|
||||||
|
|
||||||
# Dry-run create
|
# Dry-run create
|
||||||
kubectl create "${kube_flags[@]}" role pod-admin --dry-run=client --verb=* --resource=pods
|
kubectl create "${kube_flags[@]}" role pod-admin --dry-run=client --verb=* --resource=pods
|
||||||
kubectl create "${kube_flags[@]}" role pod-admin --dry-run=server --verb=* --resource=pods
|
kubectl create "${kube_flags[@]}" role pod-admin --dry-run=server --verb=* --resource=pods
|
||||||
|
Loading…
Reference in New Issue
Block a user