diff --git a/cmd/kube-apiserver/app/options/options.go b/cmd/kube-apiserver/app/options/options.go index 9672b18766a..3fb4dcc22b1 100644 --- a/cmd/kube-apiserver/app/options/options.go +++ b/cmd/kube-apiserver/app/options/options.go @@ -29,6 +29,7 @@ import ( "k8s.io/component-base/logs" "k8s.io/component-base/metrics" + logsapi "k8s.io/component-base/logs/api/v1" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/cluster/ports" "k8s.io/kubernetes/pkg/controlplane/reconcilers" @@ -155,7 +156,7 @@ func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) { s.EgressSelector.AddFlags(fss.FlagSet("egress selector")) s.Admission.AddFlags(fss.FlagSet("admission")) s.Metrics.AddFlags(fss.FlagSet("metrics")) - s.Logs.AddFlags(fss.FlagSet("logs")) + logsapi.AddFlags(s.Logs, fss.FlagSet("logs")) s.Traces.AddFlags(fss.FlagSet("traces")) // Note: the weird ""+ in below lines seems to be the only way to get gofmt to diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index fc0d51d2eca..aa2995428ba 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -110,7 +110,7 @@ cluster's shared state through which all other components interact.`, // Activate logging as soon as possible, after that // show flags with the final logging configuration. - if err := s.Logs.ValidateAndApply(utilfeature.DefaultFeatureGate); err != nil { + if err := logsapi.ValidateAndApply(s.Logs, utilfeature.DefaultFeatureGate); err != nil { return err } cliflag.PrintFlags(fs) diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go index a0dd399972a..dd284fdca85 100644 --- a/cmd/kube-controller-manager/app/controllermanager.go +++ b/cmd/kube-controller-manager/app/controllermanager.go @@ -124,7 +124,7 @@ controller, and serviceaccounts controller.`, // Activate logging as soon as possible, after that // show flags with the final logging configuration. - if err := s.Logs.ValidateAndApply(utilfeature.DefaultFeatureGate); err != nil { + if err := logsapi.ValidateAndApply(s.Logs, utilfeature.DefaultFeatureGate); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } diff --git a/cmd/kube-controller-manager/app/options/options.go b/cmd/kube-controller-manager/app/options/options.go index 59bffd53fc1..b3d2e7e2da5 100644 --- a/cmd/kube-controller-manager/app/options/options.go +++ b/cmd/kube-controller-manager/app/options/options.go @@ -34,6 +34,7 @@ import ( cpoptions "k8s.io/cloud-provider/options" cliflag "k8s.io/component-base/cli/flag" "k8s.io/component-base/logs" + logsapi "k8s.io/component-base/logs/api/v1" "k8s.io/component-base/metrics" cmoptions "k8s.io/controller-manager/options" kubectrlmgrconfigv1alpha1 "k8s.io/kube-controller-manager/config/v1alpha1" @@ -256,7 +257,7 @@ func (s *KubeControllerManagerOptions) Flags(allControllers []string, disabledBy s.SAController.AddFlags(fss.FlagSet("serviceaccount controller")) s.TTLAfterFinishedController.AddFlags(fss.FlagSet("ttl-after-finished controller")) s.Metrics.AddFlags(fss.FlagSet("metrics")) - s.Logs.AddFlags(fss.FlagSet("logs")) + logsapi.AddFlags(s.Logs, fss.FlagSet("logs")) fs := fss.FlagSet("misc") fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig).") diff --git a/cmd/kube-scheduler/app/options/options.go b/cmd/kube-scheduler/app/options/options.go index bffb6c44608..6a5b2a1c131 100644 --- a/cmd/kube-scheduler/app/options/options.go +++ b/cmd/kube-scheduler/app/options/options.go @@ -40,6 +40,7 @@ import ( componentbaseconfig "k8s.io/component-base/config" "k8s.io/component-base/config/options" "k8s.io/component-base/logs" + logsapi "k8s.io/component-base/logs/api/v1" "k8s.io/component-base/metrics" schedulerappconfig "k8s.io/kubernetes/cmd/kube-scheduler/app/config" "k8s.io/kubernetes/pkg/scheduler" @@ -194,7 +195,7 @@ func (o *Options) initFlags() { options.BindLeaderElectionFlags(o.LeaderElection, nfs.FlagSet("leader election")) utilfeature.DefaultMutableFeatureGate.AddFlag(nfs.FlagSet("feature gate")) o.Metrics.AddFlags(nfs.FlagSet("metrics")) - o.Logs.AddFlags(nfs.FlagSet("logs")) + logsapi.AddFlags(o.Logs, nfs.FlagSet("logs")) o.Flags = &nfs } diff --git a/cmd/kube-scheduler/app/server.go b/cmd/kube-scheduler/app/server.go index 93230343492..c352ba664d0 100644 --- a/cmd/kube-scheduler/app/server.go +++ b/cmd/kube-scheduler/app/server.go @@ -120,7 +120,7 @@ func runCommand(cmd *cobra.Command, opts *options.Options, registryOptions ...Op // Activate logging as soon as possible, after that // show flags with the final logging configuration. - if err := opts.Logs.ValidateAndApply(utilfeature.DefaultFeatureGate); err != nil { + if err := logsapi.ValidateAndApply(opts.Logs, utilfeature.DefaultFeatureGate); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } diff --git a/cmd/kubelet/app/options/options.go b/cmd/kubelet/app/options/options.go index 6da44a38789..69b4d326e94 100644 --- a/cmd/kubelet/app/options/options.go +++ b/cmd/kubelet/app/options/options.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" cliflag "k8s.io/component-base/cli/flag" + logsapi "k8s.io/component-base/logs/api/v1" "k8s.io/kubelet/config/v1beta1" kubeletapis "k8s.io/kubelet/pkg/apis" "k8s.io/kubernetes/pkg/cluster/ports" @@ -499,7 +500,7 @@ func AddKubeletConfigFlags(mainfs *pflag.FlagSet, c *kubeletconfig.KubeletConfig fs.StringSliceVar(&c.EnforceNodeAllocatable, "enforce-node-allocatable", c.EnforceNodeAllocatable, "A comma separated list of levels of node allocatable enforcement to be enforced by kubelet. Acceptable options are 'none', 'pods', 'system-reserved', and 'kube-reserved'. If the latter two options are specified, '--system-reserved-cgroup' and '--kube-reserved-cgroup' must also be set, respectively. If 'none' is specified, no additional options should be set. See https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/ for more details.") fs.StringVar(&c.SystemReservedCgroup, "system-reserved-cgroup", c.SystemReservedCgroup, "Absolute name of the top level cgroup that is used to manage non-kubernetes components for which compute resources were reserved via '--system-reserved' flag. Ex. '/system-reserved'. [default='']") fs.StringVar(&c.KubeReservedCgroup, "kube-reserved-cgroup", c.KubeReservedCgroup, "Absolute name of the top level cgroup that is used to manage kubernetes components for which compute resources were reserved via '--kube-reserved' flag. Ex. '/kube-reserved'. [default='']") - c.Logging.AddFlags(fs) + logsapi.AddFlags(&c.Logging, fs) // Memory Manager Flags fs.StringVar(&c.MemoryManagerPolicy, "memory-manager-policy", c.MemoryManagerPolicy, "Memory Manager policy to use. Possible values: 'None', 'Static'.") diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 06704135881..d00dd05a972 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -215,7 +215,7 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API // Config and flags parsed, now we can initialize logging. logs.InitLogs() - if err := kubeletConfig.Logging.ValidateAndApplyAsField(utilfeature.DefaultFeatureGate, field.NewPath("logging")); err != nil { + if err := logsapi.ValidateAndApplyAsField(&kubeletConfig.Logging, utilfeature.DefaultFeatureGate, field.NewPath("logging")); err != nil { return fmt.Errorf("initialize logging: %v", err) } cliflag.PrintFlags(cleanFlagSet) diff --git a/pkg/kubelet/apis/config/v1beta1/defaults.go b/pkg/kubelet/apis/config/v1beta1/defaults.go index 06ea4559e97..be5715ba85a 100644 --- a/pkg/kubelet/apis/config/v1beta1/defaults.go +++ b/pkg/kubelet/apis/config/v1beta1/defaults.go @@ -24,6 +24,7 @@ import ( kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1" // TODO: Cut references to k8s.io/kubernetes, eventually there should be none from this package + logsapi "k8s.io/component-base/logs/api/v1" "k8s.io/kubernetes/pkg/cluster/ports" "k8s.io/kubernetes/pkg/kubelet/qos" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" @@ -244,7 +245,7 @@ func SetDefaults_KubeletConfiguration(obj *kubeletconfigv1beta1.KubeletConfigura obj.VolumePluginDir = DefaultVolumePluginDir } // Use the Default LoggingConfiguration option - obj.Logging.SetRecommendedLoggingConfiguration() + logsapi.SetRecommendedLoggingConfiguration(&obj.Logging) if obj.EnableSystemLogHandler == nil { obj.EnableSystemLogHandler = utilpointer.BoolPtr(true) } diff --git a/pkg/kubelet/apis/config/validation/validation.go b/pkg/kubelet/apis/config/validation/validation.go index 7b88556b11a..872c912957c 100644 --- a/pkg/kubelet/apis/config/validation/validation.go +++ b/pkg/kubelet/apis/config/validation/validation.go @@ -25,6 +25,7 @@ import ( utilvalidation "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/component-base/featuregate" + logsapi "k8s.io/component-base/logs/api/v1" "k8s.io/component-base/metrics" "k8s.io/kubernetes/pkg/features" kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" @@ -236,7 +237,7 @@ func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration, featur } allErrors = append(allErrors, metrics.ValidateShowHiddenMetricsVersion(kc.ShowHiddenMetricsForVersion)...) - if errs := kc.Logging.Validate(localFeatureGate, field.NewPath("logging")); len(errs) > 0 { + if errs := logsapi.Validate(&kc.Logging, localFeatureGate, field.NewPath("logging")); len(errs) > 0 { allErrors = append(allErrors, errs.ToAggregate().Errors()...) } diff --git a/staging/src/k8s.io/component-base/logs/api/v1/options.go b/staging/src/k8s.io/component-base/logs/api/v1/options.go index 84cbdf97444..dd4e7f8a218 100644 --- a/staging/src/k8s.io/component-base/logs/api/v1/options.go +++ b/staging/src/k8s.io/component-base/logs/api/v1/options.go @@ -50,7 +50,7 @@ const ( // NewLoggingConfiguration returns a struct holding the default logging configuration. func NewLoggingConfiguration() *LoggingConfiguration { c := LoggingConfiguration{} - c.SetRecommendedLoggingConfiguration() + SetRecommendedLoggingConfiguration(&c) return &c } @@ -61,26 +61,26 @@ func NewLoggingConfiguration() *LoggingConfiguration { // // The optional FeatureGate controls logging features. If nil, the default for // these features is used. -func (c *LoggingConfiguration) ValidateAndApply(featureGate featuregate.FeatureGate) error { - return c.ValidateAndApplyAsField(featureGate, nil) +func ValidateAndApply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { + return ValidateAndApplyAsField(c, featureGate, nil) } // ValidateAndApplyAsField is a variant of ValidateAndApply that should be used // when the LoggingConfiguration is embedded in some larger configuration // structure. -func (c *LoggingConfiguration) ValidateAndApplyAsField(featureGate featuregate.FeatureGate, fldPath *field.Path) error { - errs := c.Validate(featureGate, fldPath) +func ValidateAndApplyAsField(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) error { + errs := Validate(c, featureGate, fldPath) if len(errs) > 0 { return errs.ToAggregate() } - return c.apply(featureGate) + return apply(c, featureGate) } // Validate can be used to check for invalid settings without applying them. // Most binaries should validate and apply the logging configuration as soon // as possible via ValidateAndApply. The field path is optional: nil // can be passed when the struct is not embedded in some larger struct. -func (c *LoggingConfiguration) Validate(featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList { +func Validate(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList { errs := field.ErrorList{} if c.Format != DefaultLogFormat { // WordSepNormalizeFunc is just a guess. Commands should use it, @@ -127,17 +127,17 @@ func (c *LoggingConfiguration) Validate(featureGate featuregate.FeatureGate, fld } } - errs = append(errs, c.validateFormatOptions(featureGate, fldPath.Child("options"))...) + errs = append(errs, validateFormatOptions(c, featureGate, fldPath.Child("options"))...) return errs } -func (c *LoggingConfiguration) validateFormatOptions(featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList { +func validateFormatOptions(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList { errs := field.ErrorList{} - errs = append(errs, c.validateJSONOptions(featureGate, fldPath.Child("json"))...) + errs = append(errs, validateJSONOptions(c, featureGate, fldPath.Child("json"))...) return errs } -func (c *LoggingConfiguration) validateJSONOptions(featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList { +func validateJSONOptions(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList { errs := field.ErrorList{} if gate := LoggingAlphaOptions; c.Options.JSON.SplitStream && !featureEnabled(featureGate, gate) { errs = append(errs, field.Forbidden(fldPath.Child("splitStream"), fmt.Sprintf("Feature %s is disabled", gate))) @@ -156,7 +156,7 @@ func featureEnabled(featureGate featuregate.FeatureGate, feature featuregate.Fea return enabled } -func (c *LoggingConfiguration) apply(featureGate featuregate.FeatureGate) error { +func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { contextualLoggingEnabled := contextualLoggingDefault if featureGate != nil { contextualLoggingEnabled = featureGate.Enabled(ContextualLogging) @@ -182,7 +182,7 @@ func (c *LoggingConfiguration) apply(featureGate featuregate.FeatureGate) error } // AddFlags adds command line flags for the configuration. -func (c *LoggingConfiguration) AddFlags(fs *pflag.FlagSet) { +func AddFlags(c *LoggingConfiguration, fs *pflag.FlagSet) { // The help text is generated assuming that flags will eventually use // hyphens, even if currently no normalization function is set for the // flag set yet. @@ -210,7 +210,7 @@ func (c *LoggingConfiguration) AddFlags(fs *pflag.FlagSet) { // Consumers who embed LoggingConfiguration in their own configuration structs // may set custom defaults and then should call this function to add the // global defaults. -func (c *LoggingConfiguration) SetRecommendedLoggingConfiguration() { +func SetRecommendedLoggingConfiguration(c *LoggingConfiguration) { if c.Format == "" { c.Format = "text" } diff --git a/staging/src/k8s.io/component-base/logs/api/v1/options_test.go b/staging/src/k8s.io/component-base/logs/api/v1/options_test.go index 40f334df902..0d2083dca8b 100644 --- a/staging/src/k8s.io/component-base/logs/api/v1/options_test.go +++ b/staging/src/k8s.io/component-base/logs/api/v1/options_test.go @@ -35,7 +35,7 @@ func TestFlags(t *testing.T) { c := NewLoggingConfiguration() fs := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError) output := bytes.Buffer{} - c.AddFlags(fs) + AddFlags(c, fs) fs.SetOutput(&output) fs.PrintDefaults() want := ` --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) @@ -88,12 +88,12 @@ func TestOptions(t *testing.T) { t.Run(tc.name, func(t *testing.T) { c := NewLoggingConfiguration() fs := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError) - c.AddFlags(fs) + AddFlags(c, fs) fs.Parse(tc.args) if !assert.Equal(t, tc.want, c) { t.Errorf("Wrong Validate() result for %q. expect %v, got %v", tc.name, tc.want, c) } - errs := c.ValidateAndApply(nil /* We don't care about feature gates here. */) + errs := ValidateAndApply(c, nil /* We don't care about feature gates here. */) defer klog.StopFlushDaemon() if !assert.ElementsMatch(t, tc.errs, errs) { t.Errorf("Wrong Validate() result for %q.\n expect:\t%+v\n got:\t%+v", tc.name, tc.errs, errs) @@ -120,7 +120,7 @@ func testContextualLogging(t *testing.T, enabled bool) { AddFeatureGates(featureGate) err = featureGate.SetFromMap(map[string]bool{string(ContextualLogging): enabled}) require.NoError(t, err) - err = c.ValidateAndApply(featureGate) + err = ValidateAndApply(c, featureGate) require.NoError(t, err) defer klog.StopFlushDaemon() defer klog.EnableContextualLogging(true) diff --git a/staging/src/k8s.io/component-base/logs/api/v1/validate_test.go b/staging/src/k8s.io/component-base/logs/api/v1/validate_test.go index 99c7f657cad..10a8d790d31 100644 --- a/staging/src/k8s.io/component-base/logs/api/v1/validate_test.go +++ b/staging/src/k8s.io/component-base/logs/api/v1/validate_test.go @@ -151,7 +151,7 @@ func TestValidation(t *testing.T) { if featureGate == nil { featureGate = defaultFeatureGate } - err := test.config.Validate(featureGate, test.path) + err := Validate(&test.config, featureGate, test.path) if len(err) == 0 { if test.expectErrors != "" { t.Fatalf("did not get expected error(s): %s", test.expectErrors) diff --git a/staging/src/k8s.io/component-base/logs/example/cmd/logger.go b/staging/src/k8s.io/component-base/logs/example/cmd/logger.go index 16d9f3b93cd..5b8ed2e4d0d 100644 --- a/staging/src/k8s.io/component-base/logs/example/cmd/logger.go +++ b/staging/src/k8s.io/component-base/logs/example/cmd/logger.go @@ -53,7 +53,7 @@ func NewLoggerCommand() *cobra.Command { cmd := &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { logs.InitLogs() - if err := c.ValidateAndApply(featureGate); err != nil { + if err := logsapi.ValidateAndApply(c, featureGate); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } @@ -67,7 +67,7 @@ func NewLoggerCommand() *cobra.Command { } logsapi.AddFeatureGates(featureGate) featureGate.AddFlag(cmd.Flags()) - c.AddFlags(cmd.Flags()) + logsapi.AddFlags(c, cmd.Flags()) return cmd } diff --git a/staging/src/k8s.io/component-base/logs/json/register/register_test.go b/staging/src/k8s.io/component-base/logs/json/register/register_test.go index 0b5398ae4a0..6ec743414ab 100644 --- a/staging/src/k8s.io/component-base/logs/json/register/register_test.go +++ b/staging/src/k8s.io/component-base/logs/json/register/register_test.go @@ -34,7 +34,7 @@ func TestJSONFlag(t *testing.T) { c := logsapi.NewLoggingConfiguration() fs := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError) output := bytes.Buffer{} - c.AddFlags(fs) + logsapi.AddFlags(c, fs) fs.SetOutput(&output) fs.PrintDefaults() wantSubstring := `Permitted formats: "json" (gated by LoggingBetaOptions), "text".` @@ -142,7 +142,7 @@ func TestJSONFormatRegister(t *testing.T) { t.Run(tc.name, func(t *testing.T) { c := logsapi.NewLoggingConfiguration() fs := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError) - c.AddFlags(fs) + logsapi.AddFlags(c, fs) fs.Parse(tc.args) if !assert.Equal(t, tc.want, c) { t.Errorf("Wrong Validate() result for %q. expect %v, got %v", tc.name, tc.want, c) @@ -155,7 +155,7 @@ func TestJSONFormatRegister(t *testing.T) { err := mutable.SetFromMap(map[string]bool{string(logsapi.ContextualLogging): tc.contextualLogging}) require.NoError(t, err) featureGate = mutable - errs := c.ValidateAndApply(featureGate) + errs := logsapi.ValidateAndApply(c, featureGate) defer klog.ClearLogger() if !assert.ElementsMatch(t, tc.errs, errs) { t.Errorf("Wrong Validate() result for %q.\n expect:\t%+v\n got:\t%+v", tc.name, tc.errs, errs)