From d9ea126e2523af007cd05ac400511ee462233327 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Mon, 5 Oct 2020 10:05:49 -0700 Subject: [PATCH 1/9] put EnableInjectionOrDie back on the main path --- injection/sharedmain/main.go | 59 ++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/injection/sharedmain/main.go b/injection/sharedmain/main.go index 33d45391e2..d76996d650 100644 --- a/injection/sharedmain/main.go +++ b/injection/sharedmain/main.go @@ -127,6 +127,32 @@ func GetLeaderElectionConfig(ctx context.Context) (*leaderelection.Config, error return leaderelection.NewConfigFromConfigMap(leaderElectionConfigMap) } +const ( + defaultStartInformerDelayTime = 5 * time.Second +) + +type informerStartChanKey struct{} +type informerStartTimeoutKey struct{} + +func WithInformerStart(ctx context.Context, start <-chan struct{}, timeout time.Duration) context.Context { + ctx = context.WithValue(ctx, informerStartChanKey{}, start) + return context.WithValue(ctx, informerStartTimeoutKey{}, timeout) +} + +func getInformerStartChanTimeout(ctx context.Context) (<-chan struct{}, time.Duration) { + timeout := defaultStartInformerDelayTime + tuntyped := ctx.Value(informerStartTimeoutKey{}) + if tuntyped != nil { + timeout = tuntyped.(time.Duration) + } + + untyped := ctx.Value(informerStartChanKey{}) + if untyped == nil { + return make(chan struct{}, 1), timeout + } + return untyped.(<-chan struct{}), timeout +} + // EnableInjectionOrDie enables Knative Injection and starts the informers. // Both Context and Config are optional. func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) context.Context { @@ -148,14 +174,18 @@ func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) context.Context ctx, informers := injection.Default.SetupInformers(ctx, cfg) - // Start the injection clients and informers. - logging.FromContext(ctx).Info("Starting informers...") - go func(ctx context.Context) { + start, timeout := getInformerStartChanTimeout(ctx) + go func() { + // Block until the timeout or we are told it is ok to start informers. + select { + case <-start: + case <-time.After(timeout): + } + logging.FromContext(ctx).Info("Starting informers...") if err := controller.StartInformers(ctx.Done(), informers...); err != nil { logging.FromContext(ctx).Fatalw("Failed to start informers", zap.Error(err)) } - <-ctx.Done() - }(ctx) + }() return ctx } @@ -225,16 +255,8 @@ func MainWithConfig(ctx context.Context, component string, cfg *rest.Config, cto cfg.Burst = len(ctors) * rest.DefaultBurst } - // Respect user provided settings, but if omitted customize the default behavior. - if cfg.QPS == 0 { - cfg.QPS = rest.DefaultQPS - } - if cfg.Burst == 0 { - cfg.Burst = rest.DefaultBurst - } - ctx = injection.WithConfig(ctx, cfg) - - ctx, informers := injection.Default.SetupInformers(ctx, cfg) + startCh := make(chan struct{}, 1) + ctx = EnableInjectionOrDie(WithInformerStart(ctx, startCh, defaultStartInformerDelayTime), cfg) logger, atomicLevel := SetupLoggerOrDie(ctx, component) defer flush(logger) @@ -287,11 +309,10 @@ func MainWithConfig(ctx context.Context, component string, cfg *rest.Config, cto return wh.Run(ctx.Done()) }) } + // Start the injection clients and informers. - logging.FromContext(ctx).Info("Starting informers...") - if err := controller.StartInformers(ctx.Done(), informers...); err != nil { - logging.FromContext(ctx).Fatalw("Failed to start informers", zap.Error(err)) - } + startCh <- struct{}{} + // Wait for webhook informers to sync. if wh != nil { wh.InformersHaveSynced() From e9ae4cc076f336b3192491d270b302f0219ee69f Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Mon, 5 Oct 2020 11:02:01 -0700 Subject: [PATCH 2/9] nil check pointer type --- injection/sharedmain/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/injection/sharedmain/main.go b/injection/sharedmain/main.go index d76996d650..270fbe0467 100644 --- a/injection/sharedmain/main.go +++ b/injection/sharedmain/main.go @@ -25,6 +25,7 @@ import ( "os" "os/user" "path/filepath" + "reflect" "time" "go.opencensus.io/stats/view" @@ -147,7 +148,7 @@ func getInformerStartChanTimeout(ctx context.Context) (<-chan struct{}, time.Dur } untyped := ctx.Value(informerStartChanKey{}) - if untyped == nil { + if untyped == nil || reflect.ValueOf(untyped).IsNil() { return make(chan struct{}, 1), timeout } return untyped.(<-chan struct{}), timeout From c0b722beade8e6ba39643410e44ebc2eea0dfb9a Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 6 Oct 2020 09:14:26 -0700 Subject: [PATCH 3/9] move enable injeciton out of sharedmain --- injection/config.go | 88 ++++++++++++++++++++++++++++++++ injection/context.go | 1 - injection/injection.go | 57 +++++++++++++++++++++ injection/sharedmain/main.go | 51 ++++-------------- leaderelection/chaosduck/main.go | 5 +- 5 files changed, 157 insertions(+), 45 deletions(-) create mode 100644 injection/config.go create mode 100644 injection/injection.go diff --git a/injection/config.go b/injection/config.go new file mode 100644 index 0000000000..e0873add8d --- /dev/null +++ b/injection/config.go @@ -0,0 +1,88 @@ +/* +Copyright 2020 The Knative 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 injection + +import ( + "errors" + "flag" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/klog" + "log" + "os" + "os/user" + "path/filepath" +) + +// ParseAndGetRestConfigOrDie parses the rest config flags and creates a client or +// dies by calling log.Fatalf. +func ParseAndGetRestConfigOrDie() *rest.Config { + var ( + serverURL = flag.String("server", "", + "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.") + kubeconfig = flag.String("kubeconfig", "", + "Path to a kubeconfig. Only required if out-of-cluster.") + ) + klog.InitFlags(flag.CommandLine) + flag.Parse() + + cfg, err := GetRestConfig(*serverURL, *kubeconfig) + if err != nil { + log.Fatalf("Error building kubeconfig: %v", err) + } + + return cfg +} + +// GetConfig returns a rest.Config to be used for kubernetes client creation. +// It does so in the following order: +// 1. Use the passed kubeconfig/serverURL. +// 2. Fallback to the KUBECONFIG environment variable. +// 3. Fallback to in-cluster config. +// 4. Fallback to the ~/.kube/config. +func GetRestConfig(serverURL, kubeconfig string) (*rest.Config, error) { + if kubeconfig == "" { + kubeconfig = os.Getenv("KUBECONFIG") + } + + // We produce configs a bunch of ways, this gives us a single place + // to "decorate" them with common useful things (e.g. for debugging) + decorate := func(cfg *rest.Config) *rest.Config { + return cfg + } + + // If we have an explicit indication of where the kubernetes config lives, read that. + if kubeconfig != "" { + c, err := clientcmd.BuildConfigFromFlags(serverURL, kubeconfig) + if err != nil { + return nil, err + } + return decorate(c), nil + } + // If not, try the in-cluster config. + if c, err := rest.InClusterConfig(); err == nil { + return decorate(c), nil + } + // If no in-cluster config, try the default location in the user's home directory. + if usr, err := user.Current(); err == nil { + if c, err := clientcmd.BuildConfigFromFlags("", filepath.Join(usr.HomeDir, ".kube", "config")); err == nil { + return decorate(c), nil + } + } + + return nil, errors.New("could not create a valid kubeconfig") +} diff --git a/injection/context.go b/injection/context.go index 4594ebeb78..4a523cc643 100644 --- a/injection/context.go +++ b/injection/context.go @@ -18,7 +18,6 @@ package injection import ( "context" - "k8s.io/client-go/rest" ) diff --git a/injection/injection.go b/injection/injection.go new file mode 100644 index 0000000000..c799966f87 --- /dev/null +++ b/injection/injection.go @@ -0,0 +1,57 @@ +/* +Copyright 2019 The Knative 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 injection + +import ( + "context" + "go.uber.org/zap" + "knative.dev/pkg/controller" + "knative.dev/pkg/logging" + "knative.dev/pkg/signals" + + "k8s.io/client-go/rest" +) + +// EnableInjectionOrDie enables Knative Injection and starts the informers. +// Both Context and Config are optional. Returns context with rest config set +// and a function to start the informers after watches have been set up. +func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) (context.Context, func()) { + if ctx == nil { + ctx = signals.NewContext() + } + if cfg == nil { + cfg = ParseAndGetRestConfigOrDie() + } + + // Respect user provided settings, but if omitted customize the default behavior. + if cfg.QPS == 0 { + cfg.QPS = rest.DefaultQPS + } + if cfg.Burst == 0 { + cfg.Burst = rest.DefaultBurst + } + ctx = WithConfig(ctx, cfg) + + ctx, informers := Default.SetupInformers(ctx, cfg) + + return ctx, func() { + logging.FromContext(ctx).Info("Starting informers...") + if err := controller.StartInformers(ctx.Done(), informers...); err != nil { + logging.FromContext(ctx).Fatalw("Failed to start informers", zap.Error(err)) + } + } +} diff --git a/injection/sharedmain/main.go b/injection/sharedmain/main.go index 270fbe0467..cafc5bc65c 100644 --- a/injection/sharedmain/main.go +++ b/injection/sharedmain/main.go @@ -25,7 +25,6 @@ import ( "os" "os/user" "path/filepath" - "reflect" "time" "go.opencensus.io/stats/view" @@ -64,6 +63,7 @@ import ( // 2. Fallback to the KUBECONFIG environment variable. // 3. Fallback to in-cluster config. // 4. Fallback to the ~/.kube/config. +// Deprecated: use injection.GetRestConfig func GetConfig(serverURL, kubeconfig string) (*rest.Config, error) { if kubeconfig == "" { kubeconfig = os.Getenv("KUBECONFIG") @@ -128,40 +128,15 @@ func GetLeaderElectionConfig(ctx context.Context) (*leaderelection.Config, error return leaderelection.NewConfigFromConfigMap(leaderElectionConfigMap) } -const ( - defaultStartInformerDelayTime = 5 * time.Second -) - -type informerStartChanKey struct{} -type informerStartTimeoutKey struct{} - -func WithInformerStart(ctx context.Context, start <-chan struct{}, timeout time.Duration) context.Context { - ctx = context.WithValue(ctx, informerStartChanKey{}, start) - return context.WithValue(ctx, informerStartTimeoutKey{}, timeout) -} - -func getInformerStartChanTimeout(ctx context.Context) (<-chan struct{}, time.Duration) { - timeout := defaultStartInformerDelayTime - tuntyped := ctx.Value(informerStartTimeoutKey{}) - if tuntyped != nil { - timeout = tuntyped.(time.Duration) - } - - untyped := ctx.Value(informerStartChanKey{}) - if untyped == nil || reflect.ValueOf(untyped).IsNil() { - return make(chan struct{}, 1), timeout - } - return untyped.(<-chan struct{}), timeout -} - // EnableInjectionOrDie enables Knative Injection and starts the informers. // Both Context and Config are optional. +// Deprecated: use injection.EnableInjectionOrDie func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) context.Context { if ctx == nil { ctx = signals.NewContext() } if cfg == nil { - cfg = ParseAndGetConfigOrDie() + cfg = injection.ParseAndGetRestConfigOrDie() } // Respect user provided settings, but if omitted customize the default behavior. @@ -175,13 +150,7 @@ func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) context.Context ctx, informers := injection.Default.SetupInformers(ctx, cfg) - start, timeout := getInformerStartChanTimeout(ctx) go func() { - // Block until the timeout or we are told it is ok to start informers. - select { - case <-start: - case <-time.After(timeout): - } logging.FromContext(ctx).Info("Starting informers...") if err := controller.StartInformers(ctx.Done(), informers...); err != nil { logging.FromContext(ctx).Fatalw("Failed to start informers", zap.Error(err)) @@ -192,8 +161,8 @@ func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) context.Context } // Main runs the generic main flow with a new context. -// If any of the contructed controllers are AdmissionControllers or Conversion webhooks, -// then a webhook is started to serve them. +// If any of the constructed controllers are AdmissionControllers or Conversion +// webhooks, then a webhook is started to serve them. func Main(component string, ctors ...injection.ControllerConstructor) { // Set up signals so we handle the first shutdown signal gracefully. MainWithContext(signals.NewContext(), component, ctors...) @@ -216,7 +185,7 @@ func MainWithContext(ctx context.Context, component string, ctors ...injection.C "issue upstream!") // HACK: This parses flags, so the above should be set once this runs. - cfg := ParseAndGetConfigOrDie() + cfg := injection.ParseAndGetRestConfigOrDie() if *disableHighAvailability { ctx = WithHADisabled(ctx) @@ -256,8 +225,7 @@ func MainWithConfig(ctx context.Context, component string, cfg *rest.Config, cto cfg.Burst = len(ctors) * rest.DefaultBurst } - startCh := make(chan struct{}, 1) - ctx = EnableInjectionOrDie(WithInformerStart(ctx, startCh, defaultStartInformerDelayTime), cfg) + ctx, startInformers := injection.EnableInjectionOrDie(ctx, cfg) logger, atomicLevel := SetupLoggerOrDie(ctx, component) defer flush(logger) @@ -312,7 +280,7 @@ func MainWithConfig(ctx context.Context, component string, cfg *rest.Config, cto } // Start the injection clients and informers. - startCh <- struct{}{} + startInformers() // Wait for webhook informers to sync. if wh != nil { @@ -339,6 +307,7 @@ func flush(logger *zap.SugaredLogger) { // ParseAndGetConfigOrDie parses the rest config flags and creates a client or // dies by calling log.Fatalf. +// Deprecated: use injeciton.ParseAndGetRestConfigOrDie func ParseAndGetConfigOrDie() *rest.Config { var ( serverURL = flag.String("server", "", @@ -349,7 +318,7 @@ func ParseAndGetConfigOrDie() *rest.Config { klog.InitFlags(flag.CommandLine) flag.Parse() - cfg, err := GetConfig(*serverURL, *kubeconfig) + cfg, err := injection.GetRestConfig(*serverURL, *kubeconfig) if err != nil { log.Fatal("Error building kubeconfig: ", err) } diff --git a/leaderelection/chaosduck/main.go b/leaderelection/chaosduck/main.go index d4950b911b..a84b7fee0d 100644 --- a/leaderelection/chaosduck/main.go +++ b/leaderelection/chaosduck/main.go @@ -23,6 +23,7 @@ import ( "context" "errors" "flag" + "knative.dev/pkg/injection" "log" "strings" "time" @@ -33,7 +34,6 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" kubeclient "knative.dev/pkg/client/injection/kube/client" - "knative.dev/pkg/injection/sharedmain" "knative.dev/pkg/kflag" "knative.dev/pkg/signals" "knative.dev/pkg/system" @@ -116,8 +116,7 @@ func quack(ctx context.Context, kc kubernetes.Interface, component string, leade } func main() { - ctx := signals.NewContext() - ctx = sharedmain.EnableInjectionOrDie(ctx, nil) + ctx, _ := injection.EnableInjectionOrDie(signals.NewContext(), nil) kc := kubeclient.Get(ctx) From 54e14deecb697442e0290e9703d9ad0f8ce4f0f9 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 6 Oct 2020 09:21:23 -0700 Subject: [PATCH 4/9] lint --- injection/config.go | 7 ++++--- injection/context.go | 1 + injection/injection.go | 1 + leaderelection/chaosduck/main.go | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/injection/config.go b/injection/config.go index e0873add8d..99645c7d8f 100644 --- a/injection/config.go +++ b/injection/config.go @@ -19,13 +19,14 @@ package injection import ( "errors" "flag" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/klog" "log" "os" "os/user" "path/filepath" + + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/klog" ) // ParseAndGetRestConfigOrDie parses the rest config flags and creates a client or diff --git a/injection/context.go b/injection/context.go index 4a523cc643..4594ebeb78 100644 --- a/injection/context.go +++ b/injection/context.go @@ -18,6 +18,7 @@ package injection import ( "context" + "k8s.io/client-go/rest" ) diff --git a/injection/injection.go b/injection/injection.go index c799966f87..afc8f313d5 100644 --- a/injection/injection.go +++ b/injection/injection.go @@ -18,6 +18,7 @@ package injection import ( "context" + "go.uber.org/zap" "knative.dev/pkg/controller" "knative.dev/pkg/logging" diff --git a/leaderelection/chaosduck/main.go b/leaderelection/chaosduck/main.go index a84b7fee0d..2ad685fe31 100644 --- a/leaderelection/chaosduck/main.go +++ b/leaderelection/chaosduck/main.go @@ -23,11 +23,12 @@ import ( "context" "errors" "flag" - "knative.dev/pkg/injection" "log" "strings" "time" + "knative.dev/pkg/injection" + "golang.org/x/sync/errgroup" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" From 67f91616a4061fcfa8f152dd190e2206318ad6a4 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 6 Oct 2020 09:26:45 -0700 Subject: [PATCH 5/9] nit picking fmt.... --- injection/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/injection/config.go b/injection/config.go index 99645c7d8f..84c88316b0 100644 --- a/injection/config.go +++ b/injection/config.go @@ -43,7 +43,7 @@ func ParseAndGetRestConfigOrDie() *rest.Config { cfg, err := GetRestConfig(*serverURL, *kubeconfig) if err != nil { - log.Fatalf("Error building kubeconfig: %v", err) + log.Fatal("Error building kubeconfig: ", err) } return cfg From a8fb062fb5c39a5330db0fac0fd24c40d812abe8 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 6 Oct 2020 10:27:48 -0700 Subject: [PATCH 6/9] add documentation --- injection/injection.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/injection/injection.go b/injection/injection.go index afc8f313d5..9ca42d653a 100644 --- a/injection/injection.go +++ b/injection/injection.go @@ -20,16 +20,24 @@ import ( "context" "go.uber.org/zap" + "k8s.io/client-go/rest" + "knative.dev/pkg/controller" "knative.dev/pkg/logging" "knative.dev/pkg/signals" - - "k8s.io/client-go/rest" ) -// EnableInjectionOrDie enables Knative Injection and starts the informers. -// Both Context and Config are optional. Returns context with rest config set -// and a function to start the informers after watches have been set up. +// EnableInjectionOrDie enables Knative Client Injection, and provides a +// callback to start the informers. Both Context and Config are optional. +// Returns context with rest config set and a callback to start the informers +// after watches have been set. +// +// Typical integration: +// ```go +// ctx, startInformers := injection.EnableInjectionOrDie(signals.NewContext(), nil) +// ... start watches with informers, if required ... +// startInformers() +// ``` func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) (context.Context, func()) { if ctx == nil { ctx = signals.NewContext() From 6fb2c29685b70501ecb2fa2614d7cc3f9c75cdfc Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 6 Oct 2020 13:25:27 -0700 Subject: [PATCH 7/9] feedback cleanup --- injection/config.go | 24 ++++++++++-------------- injection/injection.go | 2 +- injection/sharedmain/main.go | 10 +++++----- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/injection/config.go b/injection/config.go index 84c88316b0..a741a79039 100644 --- a/injection/config.go +++ b/injection/config.go @@ -29,9 +29,9 @@ import ( "k8s.io/klog" ) -// ParseAndGetRestConfigOrDie parses the rest config flags and creates a client or +// ParseAndGetKubeconfigOrDie parses the rest config flags and creates a client or // dies by calling log.Fatalf. -func ParseAndGetRestConfigOrDie() *rest.Config { +func ParseAndGetKubeconfigOrDie() *rest.Config { var ( serverURL = flag.String("server", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.") @@ -41,7 +41,7 @@ func ParseAndGetRestConfigOrDie() *rest.Config { klog.InitFlags(flag.CommandLine) flag.Parse() - cfg, err := GetRestConfig(*serverURL, *kubeconfig) + cfg, err := GetKubeconfig(*serverURL, *kubeconfig) if err != nil { log.Fatal("Error building kubeconfig: ", err) } @@ -49,39 +49,35 @@ func ParseAndGetRestConfigOrDie() *rest.Config { return cfg } -// GetConfig returns a rest.Config to be used for kubernetes client creation. +// GetKubeconfig returns a rest.Config to be used for kubernetes client creation. // It does so in the following order: // 1. Use the passed kubeconfig/serverURL. // 2. Fallback to the KUBECONFIG environment variable. // 3. Fallback to in-cluster config. // 4. Fallback to the ~/.kube/config. -func GetRestConfig(serverURL, kubeconfig string) (*rest.Config, error) { +func GetKubeconfig(serverURL, kubeconfig string) (*rest.Config, error) { if kubeconfig == "" { kubeconfig = os.Getenv("KUBECONFIG") } - // We produce configs a bunch of ways, this gives us a single place - // to "decorate" them with common useful things (e.g. for debugging) - decorate := func(cfg *rest.Config) *rest.Config { - return cfg - } - // If we have an explicit indication of where the kubernetes config lives, read that. if kubeconfig != "" { c, err := clientcmd.BuildConfigFromFlags(serverURL, kubeconfig) if err != nil { return nil, err } - return decorate(c), nil + return c, nil } + // If not, try the in-cluster config. if c, err := rest.InClusterConfig(); err == nil { - return decorate(c), nil + return c, nil } + // If no in-cluster config, try the default location in the user's home directory. if usr, err := user.Current(); err == nil { if c, err := clientcmd.BuildConfigFromFlags("", filepath.Join(usr.HomeDir, ".kube", "config")); err == nil { - return decorate(c), nil + return c, nil } } diff --git a/injection/injection.go b/injection/injection.go index 9ca42d653a..8d384ce6ce 100644 --- a/injection/injection.go +++ b/injection/injection.go @@ -43,7 +43,7 @@ func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) (context.Contex ctx = signals.NewContext() } if cfg == nil { - cfg = ParseAndGetRestConfigOrDie() + cfg = ParseAndGetKubeconfigOrDie() } // Respect user provided settings, but if omitted customize the default behavior. diff --git a/injection/sharedmain/main.go b/injection/sharedmain/main.go index cafc5bc65c..639d9b2757 100644 --- a/injection/sharedmain/main.go +++ b/injection/sharedmain/main.go @@ -63,7 +63,7 @@ import ( // 2. Fallback to the KUBECONFIG environment variable. // 3. Fallback to in-cluster config. // 4. Fallback to the ~/.kube/config. -// Deprecated: use injection.GetRestConfig +// Deprecated: use injection.GetKubeconfig func GetConfig(serverURL, kubeconfig string) (*rest.Config, error) { if kubeconfig == "" { kubeconfig = os.Getenv("KUBECONFIG") @@ -136,7 +136,7 @@ func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) context.Context ctx = signals.NewContext() } if cfg == nil { - cfg = injection.ParseAndGetRestConfigOrDie() + cfg = injection.ParseAndGetKubeconfigOrDie() } // Respect user provided settings, but if omitted customize the default behavior. @@ -185,7 +185,7 @@ func MainWithContext(ctx context.Context, component string, ctors ...injection.C "issue upstream!") // HACK: This parses flags, so the above should be set once this runs. - cfg := injection.ParseAndGetRestConfigOrDie() + cfg := injection.ParseAndGetKubeconfigOrDie() if *disableHighAvailability { ctx = WithHADisabled(ctx) @@ -307,7 +307,7 @@ func flush(logger *zap.SugaredLogger) { // ParseAndGetConfigOrDie parses the rest config flags and creates a client or // dies by calling log.Fatalf. -// Deprecated: use injeciton.ParseAndGetRestConfigOrDie +// Deprecated: use injeciton.ParseAndGetKubeconfigOrDie func ParseAndGetConfigOrDie() *rest.Config { var ( serverURL = flag.String("server", "", @@ -318,7 +318,7 @@ func ParseAndGetConfigOrDie() *rest.Config { klog.InitFlags(flag.CommandLine) flag.Parse() - cfg, err := injection.GetRestConfig(*serverURL, *kubeconfig) + cfg, err := injection.GetKubeconfig(*serverURL, *kubeconfig) if err != nil { log.Fatal("Error building kubeconfig: ", err) } From 24f3a3dd30c9a5c26f26c148b8d759e917215d79 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 6 Oct 2020 16:14:35 -0700 Subject: [PATCH 8/9] injection.GetRESTConfig --- injection/config.go | 10 +++++----- injection/injection.go | 2 +- injection/sharedmain/main.go | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/injection/config.go b/injection/config.go index a741a79039..01a5962b7e 100644 --- a/injection/config.go +++ b/injection/config.go @@ -29,9 +29,9 @@ import ( "k8s.io/klog" ) -// ParseAndGetKubeconfigOrDie parses the rest config flags and creates a client or +// ParseAndGetRESTConfigOrDie parses the rest config flags and creates a client or // dies by calling log.Fatalf. -func ParseAndGetKubeconfigOrDie() *rest.Config { +func ParseAndGetRESTConfigOrDie() *rest.Config { var ( serverURL = flag.String("server", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.") @@ -41,7 +41,7 @@ func ParseAndGetKubeconfigOrDie() *rest.Config { klog.InitFlags(flag.CommandLine) flag.Parse() - cfg, err := GetKubeconfig(*serverURL, *kubeconfig) + cfg, err := GetRESTConfig(*serverURL, *kubeconfig) if err != nil { log.Fatal("Error building kubeconfig: ", err) } @@ -49,13 +49,13 @@ func ParseAndGetKubeconfigOrDie() *rest.Config { return cfg } -// GetKubeconfig returns a rest.Config to be used for kubernetes client creation. +// GetRESTConfig returns a rest.Config to be used for kubernetes client creation. // It does so in the following order: // 1. Use the passed kubeconfig/serverURL. // 2. Fallback to the KUBECONFIG environment variable. // 3. Fallback to in-cluster config. // 4. Fallback to the ~/.kube/config. -func GetKubeconfig(serverURL, kubeconfig string) (*rest.Config, error) { +func GetRESTConfig(serverURL, kubeconfig string) (*rest.Config, error) { if kubeconfig == "" { kubeconfig = os.Getenv("KUBECONFIG") } diff --git a/injection/injection.go b/injection/injection.go index 8d384ce6ce..d8cefc9fbe 100644 --- a/injection/injection.go +++ b/injection/injection.go @@ -43,7 +43,7 @@ func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) (context.Contex ctx = signals.NewContext() } if cfg == nil { - cfg = ParseAndGetKubeconfigOrDie() + cfg = ParseAndGetRESTConfigOrDie() } // Respect user provided settings, but if omitted customize the default behavior. diff --git a/injection/sharedmain/main.go b/injection/sharedmain/main.go index 639d9b2757..6b7581b7db 100644 --- a/injection/sharedmain/main.go +++ b/injection/sharedmain/main.go @@ -63,7 +63,7 @@ import ( // 2. Fallback to the KUBECONFIG environment variable. // 3. Fallback to in-cluster config. // 4. Fallback to the ~/.kube/config. -// Deprecated: use injection.GetKubeconfig +// Deprecated: use injection.GetRESTConfig func GetConfig(serverURL, kubeconfig string) (*rest.Config, error) { if kubeconfig == "" { kubeconfig = os.Getenv("KUBECONFIG") @@ -136,7 +136,7 @@ func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) context.Context ctx = signals.NewContext() } if cfg == nil { - cfg = injection.ParseAndGetKubeconfigOrDie() + cfg = injection.ParseAndGetRESTConfigOrDie() } // Respect user provided settings, but if omitted customize the default behavior. @@ -185,7 +185,7 @@ func MainWithContext(ctx context.Context, component string, ctors ...injection.C "issue upstream!") // HACK: This parses flags, so the above should be set once this runs. - cfg := injection.ParseAndGetKubeconfigOrDie() + cfg := injection.ParseAndGetRESTConfigOrDie() if *disableHighAvailability { ctx = WithHADisabled(ctx) @@ -307,7 +307,7 @@ func flush(logger *zap.SugaredLogger) { // ParseAndGetConfigOrDie parses the rest config flags and creates a client or // dies by calling log.Fatalf. -// Deprecated: use injeciton.ParseAndGetKubeconfigOrDie +// Deprecated: use injeciton.ParseAndGetRESTConfigOrDie func ParseAndGetConfigOrDie() *rest.Config { var ( serverURL = flag.String("server", "", @@ -318,7 +318,7 @@ func ParseAndGetConfigOrDie() *rest.Config { klog.InitFlags(flag.CommandLine) flag.Parse() - cfg, err := injection.GetKubeconfig(*serverURL, *kubeconfig) + cfg, err := injection.GetRESTConfig(*serverURL, *kubeconfig) if err != nil { log.Fatal("Error building kubeconfig: ", err) } From ff424102eb41315262fdbb24ebe0ee5ad6ac566e Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 6 Oct 2020 16:39:38 -0700 Subject: [PATCH 9/9] redirect code that moved: --- injection/sharedmain/main.go | 84 +++--------------------------------- 1 file changed, 6 insertions(+), 78 deletions(-) diff --git a/injection/sharedmain/main.go b/injection/sharedmain/main.go index 6b7581b7db..c9dd034de2 100644 --- a/injection/sharedmain/main.go +++ b/injection/sharedmain/main.go @@ -18,16 +18,15 @@ package sharedmain import ( "context" - "errors" "flag" "log" "net/http" "os" - "os/user" - "path/filepath" "time" "go.opencensus.io/stats/view" + _ "go.uber.org/automaxprocs" // automatically set GOMAXPROCS based on cgroups + "go.uber.org/zap" "golang.org/x/sync/errgroup" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -35,11 +34,6 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/klog" - - _ "go.uber.org/automaxprocs" // automatically set GOMAXPROCS based on cgroups - "go.uber.org/zap" kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/configmap" @@ -65,36 +59,7 @@ import ( // 4. Fallback to the ~/.kube/config. // Deprecated: use injection.GetRESTConfig func GetConfig(serverURL, kubeconfig string) (*rest.Config, error) { - if kubeconfig == "" { - kubeconfig = os.Getenv("KUBECONFIG") - } - - // We produce configs a bunch of ways, this gives us a single place - // to "decorate" them with common useful things (e.g. for debugging) - decorate := func(cfg *rest.Config) *rest.Config { - return cfg - } - - // If we have an explicit indication of where the kubernetes config lives, read that. - if kubeconfig != "" { - c, err := clientcmd.BuildConfigFromFlags(serverURL, kubeconfig) - if err != nil { - return nil, err - } - return decorate(c), nil - } - // If not, try the in-cluster config. - if c, err := rest.InClusterConfig(); err == nil { - return decorate(c), nil - } - // If no in-cluster config, try the default location in the user's home directory. - if usr, err := user.Current(); err == nil { - if c, err := clientcmd.BuildConfigFromFlags("", filepath.Join(usr.HomeDir, ".kube", "config")); err == nil { - return decorate(c), nil - } - } - - return nil, errors.New("could not create a valid kubeconfig") + return injection.GetRESTConfig(serverURL, kubeconfig) } // GetLoggingConfig gets the logging config from either the file system if present @@ -132,31 +97,8 @@ func GetLeaderElectionConfig(ctx context.Context) (*leaderelection.Config, error // Both Context and Config are optional. // Deprecated: use injection.EnableInjectionOrDie func EnableInjectionOrDie(ctx context.Context, cfg *rest.Config) context.Context { - if ctx == nil { - ctx = signals.NewContext() - } - if cfg == nil { - cfg = injection.ParseAndGetRESTConfigOrDie() - } - - // Respect user provided settings, but if omitted customize the default behavior. - if cfg.QPS == 0 { - cfg.QPS = rest.DefaultQPS - } - if cfg.Burst == 0 { - cfg.Burst = rest.DefaultBurst - } - ctx = injection.WithConfig(ctx, cfg) - - ctx, informers := injection.Default.SetupInformers(ctx, cfg) - - go func() { - logging.FromContext(ctx).Info("Starting informers...") - if err := controller.StartInformers(ctx.Done(), informers...); err != nil { - logging.FromContext(ctx).Fatalw("Failed to start informers", zap.Error(err)) - } - }() - + ctx, startInformers := injection.EnableInjectionOrDie(ctx, cfg) + go startInformers() return ctx } @@ -309,21 +251,7 @@ func flush(logger *zap.SugaredLogger) { // dies by calling log.Fatalf. // Deprecated: use injeciton.ParseAndGetRESTConfigOrDie func ParseAndGetConfigOrDie() *rest.Config { - var ( - serverURL = flag.String("server", "", - "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.") - kubeconfig = flag.String("kubeconfig", "", - "Path to a kubeconfig. Only required if out-of-cluster.") - ) - klog.InitFlags(flag.CommandLine) - flag.Parse() - - cfg, err := injection.GetRESTConfig(*serverURL, *kubeconfig) - if err != nil { - log.Fatal("Error building kubeconfig: ", err) - } - - return cfg + return injection.ParseAndGetRESTConfigOrDie() } // MemStatsOrDie sets up reporting on Go memory usage every 30 seconds or dies