diff --git a/BUILD.bazel b/BUILD.bazel index 10cbe28ab..14ee04418 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -60,6 +60,7 @@ filegroup( "//cmd/cainjector:all-srcs", "//cmd/controller:all-srcs", "//cmd/ctl:all-srcs", + "//cmd/util:all-srcs", "//cmd/webhook:all-srcs", "//deploy:all-srcs", "//devel:all-srcs", diff --git a/cmd/acmesolver/BUILD.bazel b/cmd/acmesolver/BUILD.bazel index 52072030a..dcd102644 100644 --- a/cmd/acmesolver/BUILD.bazel +++ b/cmd/acmesolver/BUILD.bazel @@ -8,7 +8,7 @@ go_library( visibility = ["//visibility:private"], deps = [ "//cmd/acmesolver/app:go_default_library", - "//pkg/util/cmd:go_default_library", + "//cmd/util:go_default_library", ], ) diff --git a/cmd/acmesolver/app/BUILD.bazel b/cmd/acmesolver/app/BUILD.bazel index 5e26cba8f..ab7d86938 100644 --- a/cmd/acmesolver/app/BUILD.bazel +++ b/cmd/acmesolver/app/BUILD.bazel @@ -6,9 +6,9 @@ go_library( importpath = "github.com/jetstack/cert-manager/cmd/acmesolver/app", visibility = ["//visibility:public"], deps = [ + "//cmd/util:go_default_library", "//pkg/issuer/acme/http/solver:go_default_library", "//pkg/logs:go_default_library", - "//pkg/util:go_default_library", "@com_github_spf13_cobra//:go_default_library", ], ) diff --git a/cmd/acmesolver/app/app.go b/cmd/acmesolver/app/app.go index 3ab47cd56..641aa644d 100644 --- a/cmd/acmesolver/app/app.go +++ b/cmd/acmesolver/app/app.go @@ -21,9 +21,9 @@ import ( "github.com/spf13/cobra" + "github.com/jetstack/cert-manager/cmd/util" "github.com/jetstack/cert-manager/pkg/issuer/acme/http/solver" logf "github.com/jetstack/cert-manager/pkg/logs" - "github.com/jetstack/cert-manager/pkg/util" ) func NewACMESolverCommand(stopCh <-chan struct{}) *cobra.Command { diff --git a/cmd/acmesolver/main.go b/cmd/acmesolver/main.go index d7a5d43c9..8837fa9cc 100644 --- a/cmd/acmesolver/main.go +++ b/cmd/acmesolver/main.go @@ -21,7 +21,7 @@ import ( "os" "github.com/jetstack/cert-manager/cmd/acmesolver/app" - utilcmd "github.com/jetstack/cert-manager/pkg/util/cmd" + "github.com/jetstack/cert-manager/cmd/util" ) // acmesolver solves ACME http-01 challenges. This is intended to run as a pod @@ -29,10 +29,13 @@ import ( // cert-manager. func main() { - stopCh := utilcmd.SetupSignalHandler() + stopCh, exit := util.SetupExitHandler(util.GracefulShutdown) + defer exit() // This function might call os.Exit, so defer last + cmd := app.NewACMESolverCommand(stopCh) if err := cmd.Execute(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) + util.SetExitCode(err) } } diff --git a/cmd/cainjector/BUILD.bazel b/cmd/cainjector/BUILD.bazel index d5406a7a3..64ba379d0 100644 --- a/cmd/cainjector/BUILD.bazel +++ b/cmd/cainjector/BUILD.bazel @@ -8,9 +8,8 @@ go_library( visibility = ["//visibility:private"], deps = [ "//cmd/cainjector/app:go_default_library", + "//cmd/util:go_default_library", "//pkg/logs:go_default_library", - "//pkg/util:go_default_library", - "//pkg/util/cmd:go_default_library", "@io_k8s_sigs_controller_runtime//:go_default_library", ], ) diff --git a/cmd/cainjector/main.go b/cmd/cainjector/main.go index 9043df210..370322751 100644 --- a/cmd/cainjector/main.go +++ b/cmd/cainjector/main.go @@ -25,19 +25,20 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "github.com/jetstack/cert-manager/cmd/cainjector/app" + "github.com/jetstack/cert-manager/cmd/util" logf "github.com/jetstack/cert-manager/pkg/logs" - "github.com/jetstack/cert-manager/pkg/util" - utilcmd "github.com/jetstack/cert-manager/pkg/util/cmd" ) func main() { + // Set up signal handlers and a cancellable context which gets cancelled on + // when either SIGINT or SIGTERM are received. + stopCh, exit := util.SetupExitHandler(util.GracefulShutdown) + defer exit() // This function might call os.Exit, so defer last + logf.InitLogs(flag.CommandLine) defer logf.FlushLogs() ctrl.SetLogger(logf.Log) - // Set up signal handlers and a cancellable context which gets cancelled on - // when either SIGINT or SIGTERM are received. - stopCh := utilcmd.SetupSignalHandler() ctx := util.ContextWithStopCh(context.Background(), stopCh) cmd := app.NewCommandStartInjectorController(ctx, os.Stdout, os.Stderr) @@ -46,6 +47,6 @@ func main() { flag.CommandLine.Parse([]string{}) if err := cmd.Execute(); err != nil { cmd.PrintErrln(err) - os.Exit(1) + util.SetExitCode(err) } } diff --git a/cmd/controller/BUILD.bazel b/cmd/controller/BUILD.bazel index f2f377a6d..ea9d91469 100644 --- a/cmd/controller/BUILD.bazel +++ b/cmd/controller/BUILD.bazel @@ -8,8 +8,8 @@ go_library( visibility = ["//visibility:private"], deps = [ "//cmd/controller/app:go_default_library", + "//cmd/util:go_default_library", "//pkg/logs:go_default_library", - "//pkg/util/cmd:go_default_library", ], ) diff --git a/cmd/controller/app/BUILD.bazel b/cmd/controller/app/BUILD.bazel index 797bf62bf..f4239ab87 100644 --- a/cmd/controller/app/BUILD.bazel +++ b/cmd/controller/app/BUILD.bazel @@ -10,6 +10,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//cmd/controller/app/options:go_default_library", + "//cmd/util:go_default_library", "//pkg/acme/accounts:go_default_library", "//pkg/client/clientset/versioned:go_default_library", "//pkg/client/clientset/versioned/scheme:go_default_library", diff --git a/cmd/controller/app/controller.go b/cmd/controller/app/controller.go index d52477629..548c2439c 100644 --- a/cmd/controller/app/controller.go +++ b/cmd/controller/app/controller.go @@ -42,6 +42,7 @@ import ( gwinformers "sigs.k8s.io/gateway-api/pkg/client/informers/externalversions" "github.com/jetstack/cert-manager/cmd/controller/app/options" + cmdutil "github.com/jetstack/cert-manager/cmd/util" "github.com/jetstack/cert-manager/pkg/acme/accounts" clientset "github.com/jetstack/cert-manager/pkg/client/clientset/versioned" intscheme "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/scheme" @@ -63,7 +64,7 @@ const controllerAgentName = "cert-manager" const resyncPeriod = 10 * time.Hour func Run(opts *options.ControllerOptions, stopCh <-chan struct{}) { - rootCtx := util.ContextWithStopCh(context.Background(), stopCh) + rootCtx := cmdutil.ContextWithStopCh(context.Background(), stopCh) rootCtx = logf.NewContext(rootCtx, nil, "controller") log := logf.FromContext(rootCtx) diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 5d1a7257b..2c3eeef2c 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -18,24 +18,25 @@ package main import ( "flag" - "os" "github.com/jetstack/cert-manager/cmd/controller/app" + "github.com/jetstack/cert-manager/cmd/util" logf "github.com/jetstack/cert-manager/pkg/logs" - utilcmd "github.com/jetstack/cert-manager/pkg/util/cmd" ) func main() { + stopCh, exit := util.SetupExitHandler(util.GracefulShutdown) + defer exit() // This function might call os.Exit, so defer last + logf.InitLogs(flag.CommandLine) defer logf.FlushLogs() - stopCh := utilcmd.SetupSignalHandler() cmd := app.NewCommandStartCertManagerController(stopCh) cmd.Flags().AddGoFlagSet(flag.CommandLine) flag.CommandLine.Parse([]string{}) if err := cmd.Execute(); err != nil { logf.Log.Error(err, "error executing command") - os.Exit(1) + util.SetExitCode(err) } } diff --git a/cmd/ctl/BUILD.bazel b/cmd/ctl/BUILD.bazel index d332cde59..a7602aebc 100644 --- a/cmd/ctl/BUILD.bazel +++ b/cmd/ctl/BUILD.bazel @@ -8,8 +8,7 @@ go_library( visibility = ["//visibility:private"], deps = [ "//cmd/ctl/cmd:go_default_library", - "//pkg/util:go_default_library", - "//pkg/util/cmd:go_default_library", + "//cmd/util:go_default_library", ], ) diff --git a/cmd/ctl/cmd/cmd.go b/cmd/ctl/cmd/cmd.go index 9a45adc3e..60c986cde 100644 --- a/cmd/ctl/cmd/cmd.go +++ b/cmd/ctl/cmd/cmd.go @@ -28,7 +28,7 @@ import ( // Load all auth plugins _ "k8s.io/client-go/plugin/pkg/client/auth" "k8s.io/klog/v2" - cmdutil "k8s.io/kubectl/pkg/cmd/util" + "k8s.io/kubectl/pkg/cmd/util" "github.com/jetstack/cert-manager/cmd/ctl/pkg/approve" "github.com/jetstack/cert-manager/cmd/ctl/pkg/check" @@ -53,9 +53,9 @@ kubectl cert-manager is a CLI tool manage and configure cert-manager resources f kubeConfigFlags := genericclioptions.NewConfigFlags(true) kubeConfigFlags.AddFlags(cmds.PersistentFlags()) - matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags) + matchVersionKubeConfigFlags := util.NewMatchVersionFlags(kubeConfigFlags) matchVersionKubeConfigFlags.AddFlags(cmds.PersistentFlags()) - factory := cmdutil.NewFactory(matchVersionKubeConfigFlags) + factory := util.NewFactory(matchVersionKubeConfigFlags) cmds.Flags().AddGoFlagSet(flag.CommandLine) flag.CommandLine.Parse([]string{}) diff --git a/cmd/ctl/main.go b/cmd/ctl/main.go index 2bc2ef1e4..647d09e18 100644 --- a/cmd/ctl/main.go +++ b/cmd/ctl/main.go @@ -22,17 +22,18 @@ import ( "os" ctlcmd "github.com/jetstack/cert-manager/cmd/ctl/cmd" - "github.com/jetstack/cert-manager/pkg/util" - utilcmd "github.com/jetstack/cert-manager/pkg/util/cmd" + "github.com/jetstack/cert-manager/cmd/util" ) func main() { - stopCh := utilcmd.SetupSignalHandler() + stopCh, exit := util.SetupExitHandler(util.AlwaysErrCode) + defer exit() // This function might call os.Exit, so defer last + ctx := util.ContextWithStopCh(context.Background(), stopCh) cmd := ctlcmd.NewCertManagerCtlCommand(ctx, os.Stdin, os.Stdout, os.Stderr) if err := cmd.Execute(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) - os.Exit(1) + util.SetExitCode(err) } } diff --git a/cmd/ctl/pkg/check/api/BUILD.bazel b/cmd/ctl/pkg/check/api/BUILD.bazel index b23225aec..a9c027181 100644 --- a/cmd/ctl/pkg/check/api/BUILD.bazel +++ b/cmd/ctl/pkg/check/api/BUILD.bazel @@ -6,6 +6,7 @@ go_library( importpath = "github.com/jetstack/cert-manager/cmd/ctl/pkg/check/api", visibility = ["//visibility:public"], deps = [ + "//cmd/util:go_default_library", "//pkg/util/cmapichecker:go_default_library", "@com_github_spf13_cobra//:go_default_library", "@io_k8s_apimachinery//pkg/util/wait:go_default_library", diff --git a/cmd/ctl/pkg/check/api/api.go b/cmd/ctl/pkg/check/api/api.go index 533138e23..e65a5eb7b 100644 --- a/cmd/ctl/pkg/check/api/api.go +++ b/cmd/ctl/pkg/check/api/api.go @@ -21,7 +21,7 @@ import ( "errors" "fmt" "log" - "os" + "runtime" "time" "github.com/spf13/cobra" @@ -32,6 +32,7 @@ import ( "k8s.io/kubectl/pkg/util/i18n" "k8s.io/kubectl/pkg/util/templates" + cmcmdutil "github.com/jetstack/cert-manager/cmd/util" "github.com/jetstack/cert-manager/pkg/util/cmapichecker" ) @@ -150,7 +151,9 @@ func (o *Options) Run(ctx context.Context) { log.Printf("Timed out after %s", o.Wait) } - os.Exit(1) + cmcmdutil.SetExitCode(pollContext.Err()) + + runtime.Goexit() // Do soft exit (handle all defers, that should set correct exit code) } log.Printf("The cert-manager API is ready") diff --git a/pkg/util/cmd/BUILD.bazel b/cmd/util/BUILD.bazel similarity index 83% rename from pkg/util/cmd/BUILD.bazel rename to cmd/util/BUILD.bazel index 1a219c301..e03e7d558 100644 --- a/pkg/util/cmd/BUILD.bazel +++ b/cmd/util/BUILD.bazel @@ -3,11 +3,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", srcs = [ + "context.go", + "exit.go", "signal.go", "signal_posix.go", "signal_windows.go", ], - importpath = "github.com/jetstack/cert-manager/pkg/util/cmd", + importpath = "github.com/jetstack/cert-manager/cmd/util", visibility = ["//visibility:public"], ) diff --git a/pkg/util/context.go b/cmd/util/context.go similarity index 96% rename from pkg/util/context.go rename to cmd/util/context.go index 27dca3ff2..6f3c57f38 100644 --- a/pkg/util/context.go +++ b/cmd/util/context.go @@ -1,5 +1,5 @@ /* -Copyright 2020 The cert-manager Authors. +Copyright 2021 The cert-manager Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/util/exit.go b/cmd/util/exit.go new file mode 100644 index 000000000..206fc0cb0 --- /dev/null +++ b/cmd/util/exit.go @@ -0,0 +1,29 @@ +/* +Copyright 2021 The cert-manager 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 util + +import ( + "context" + "errors" +) + +// SetExitCode sets the exit code to 1 if the error is not a context.Canceled error. +func SetExitCode(err error) { + if (err != nil) && !errors.Is(err, context.Canceled) { + errorExitCodeChannel <- 1 // Indicate that there was an error + } +} diff --git a/cmd/util/signal.go b/cmd/util/signal.go new file mode 100644 index 000000000..00174504a --- /dev/null +++ b/cmd/util/signal.go @@ -0,0 +1,78 @@ +/* +Copyright 2021 The cert-manager 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 util + +import ( + "os" + "os/signal" + "syscall" +) + +var onlyOneSignalHandler = make(chan struct{}) +var errorExitCodeChannel = make(chan int, 1) + +// ExitBehavior controls how the program should be terminated +// in response to a shutdown signal. +type ExitBehavior int + +const ( + // AlwaysErrCode indicates the exit code of the program should always be nonzero + // and should correspond to the numeric value of the signal that was received. + AlwaysErrCode ExitBehavior = iota + + // GracefulShutdown treats a shutdown signal as a request to exit gracefully, terminating + // goroutines and returning an exit code of 0 if there are no errors during shutdown. + GracefulShutdown ExitBehavior = iota +) + +// SetupExitHandler: +// A stop channel is returned which is closed on receiving a shutdown signal (SIGTERM +// or SIGINT). If a second signal is caught, the program is terminated directly with +// exit code 130. +// SetupExitHandler also returns an exit function, this exit function calls os.Exit(...) +// if there is a exit code in the errorExitCodeChannel. +// The errorExitCodeChannel receives exit codes when SetExitCode is called or when +// a shutdown signal is received (only if exitBehavior is AlwaysErrCode). +func SetupExitHandler(exitBehavior ExitBehavior) (<-chan struct{}, func()) { + close(onlyOneSignalHandler) // panics when called twice + + stop := make(chan struct{}) + c := make(chan os.Signal, 2) + signal.Notify(c, shutdownSignals...) + go func() { + // first signal. Close stop chan and pass exit code to exitCodeChannel. + exitCode := 128 + int((<-c).(syscall.Signal)) + if exitBehavior == AlwaysErrCode { + errorExitCodeChannel <- exitCode + } + close(stop) + // second signal. Exit directly. + <-c + os.Exit(130) + }() + + return stop, func() { + select { + case signal := <-errorExitCodeChannel: + os.Exit(signal) + default: + // Do not exit, there are no exit codes in the channel, + // so just continue and let the main function go out of + // scope instead. + } + } +} diff --git a/pkg/util/cmd/signal_posix.go b/cmd/util/signal_posix.go similarity index 98% rename from pkg/util/cmd/signal_posix.go rename to cmd/util/signal_posix.go index eaabf7edc..67c7f8cb6 100644 --- a/pkg/util/cmd/signal_posix.go +++ b/cmd/util/signal_posix.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package util import ( "os" diff --git a/pkg/util/cmd/signal_windows.go b/cmd/util/signal_windows.go similarity index 98% rename from pkg/util/cmd/signal_windows.go rename to cmd/util/signal_windows.go index ebca2cbb9..489cc5c4c 100644 --- a/pkg/util/cmd/signal_windows.go +++ b/cmd/util/signal_windows.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package util import ( "os" diff --git a/cmd/webhook/BUILD.bazel b/cmd/webhook/BUILD.bazel index 9982a55a2..1aa5045ae 100644 --- a/cmd/webhook/BUILD.bazel +++ b/cmd/webhook/BUILD.bazel @@ -7,9 +7,9 @@ go_library( importpath = "github.com/jetstack/cert-manager/cmd/webhook", visibility = ["//visibility:private"], deps = [ + "//cmd/util:go_default_library", "//cmd/webhook/app:go_default_library", "//pkg/logs:go_default_library", - "//pkg/util/cmd:go_default_library", ], ) diff --git a/cmd/webhook/app/BUILD.bazel b/cmd/webhook/app/BUILD.bazel index fa9509908..12f803dcd 100644 --- a/cmd/webhook/app/BUILD.bazel +++ b/cmd/webhook/app/BUILD.bazel @@ -6,6 +6,7 @@ go_library( importpath = "github.com/jetstack/cert-manager/cmd/webhook/app", visibility = ["//visibility:public"], deps = [ + "//cmd/util:go_default_library", "//cmd/webhook/app/options:go_default_library", "//pkg/logs:go_default_library", "//pkg/util:go_default_library", diff --git a/cmd/webhook/app/webhook.go b/cmd/webhook/app/webhook.go index af8948fd7..71936070e 100644 --- a/cmd/webhook/app/webhook.go +++ b/cmd/webhook/app/webhook.go @@ -25,6 +25,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" + cmdutil "github.com/jetstack/cert-manager/cmd/util" "github.com/jetstack/cert-manager/cmd/webhook/app/options" logf "github.com/jetstack/cert-manager/pkg/logs" "github.com/jetstack/cert-manager/pkg/util" @@ -102,7 +103,7 @@ func NewServerCommand(stopCh <-chan struct{}) *cobra.Command { Use: "webhook", Short: fmt.Sprintf("Webhook component providing API validation, mutation and conversion functionality for cert-manager (%s) (%s)", util.AppVersion, util.AppGitCommit), RunE: func(cmd *cobra.Command, args []string) error { - ctx := util.ContextWithStopCh(context.Background(), stopCh) + ctx := cmdutil.ContextWithStopCh(context.Background(), stopCh) ctx = logf.NewContext(ctx, nil, "webhook") log := logf.FromContext(ctx) diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index b3ee12476..3f167593e 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -18,24 +18,25 @@ package main import ( "flag" - "os" + "github.com/jetstack/cert-manager/cmd/util" "github.com/jetstack/cert-manager/cmd/webhook/app" logf "github.com/jetstack/cert-manager/pkg/logs" - utilcmd "github.com/jetstack/cert-manager/pkg/util/cmd" ) func main() { + stopCh, exit := util.SetupExitHandler(util.GracefulShutdown) + defer exit() // This function might call os.Exit, so defer last + logf.InitLogs(flag.CommandLine) defer logf.FlushLogs() - stopCh := utilcmd.SetupSignalHandler() cmd := app.NewServerCommand(stopCh) cmd.Flags().AddGoFlagSet(flag.CommandLine) flag.CommandLine.Parse([]string{}) if err := cmd.Execute(); err != nil { logf.Log.Error(err, "error executing command") - os.Exit(1) + util.SetExitCode(err) } } diff --git a/pkg/acme/webhook/cmd/BUILD.bazel b/pkg/acme/webhook/cmd/BUILD.bazel index 59de0036b..120403f14 100644 --- a/pkg/acme/webhook/cmd/BUILD.bazel +++ b/pkg/acme/webhook/cmd/BUILD.bazel @@ -6,10 +6,10 @@ go_library( importpath = "github.com/jetstack/cert-manager/pkg/acme/webhook/cmd", visibility = ["//visibility:public"], deps = [ + "//cmd/util:go_default_library", "//pkg/acme/webhook:go_default_library", "//pkg/acme/webhook/cmd/server:go_default_library", "//pkg/logs:go_default_library", - "@io_k8s_apiserver//pkg/server:go_default_library", "@io_k8s_component_base//logs:go_default_library", ], ) diff --git a/pkg/acme/webhook/cmd/cmd.go b/pkg/acme/webhook/cmd/cmd.go index bc993711e..f18a5162a 100644 --- a/pkg/acme/webhook/cmd/cmd.go +++ b/pkg/acme/webhook/cmd/cmd.go @@ -21,15 +21,18 @@ import ( "os" "runtime" - genericapiserver "k8s.io/apiserver/pkg/server" "k8s.io/component-base/logs" + "github.com/jetstack/cert-manager/cmd/util" "github.com/jetstack/cert-manager/pkg/acme/webhook" "github.com/jetstack/cert-manager/pkg/acme/webhook/cmd/server" logf "github.com/jetstack/cert-manager/pkg/logs" ) func RunWebhookServer(groupName string, hooks ...webhook.Solver) { + stopCh, exit := util.SetupExitHandler(util.GracefulShutdown) + defer exit() // This function might call os.Exit, so defer last + logs.InitLogs() defer logs.FlushLogs() @@ -37,12 +40,10 @@ func RunWebhookServer(groupName string, hooks ...webhook.Solver) { runtime.GOMAXPROCS(runtime.NumCPU()) } - stopCh := genericapiserver.SetupSignalHandler() - cmd := server.NewCommandStartWebhookServer(os.Stdout, os.Stderr, stopCh, groupName, hooks...) cmd.Flags().AddGoFlagSet(flag.CommandLine) if err := cmd.Execute(); err != nil { logf.Log.Error(err, "error executing command") - os.Exit(1) + util.SetExitCode(err) } } diff --git a/pkg/util/BUILD.bazel b/pkg/util/BUILD.bazel index c4b848a82..e576962cb 100644 --- a/pkg/util/BUILD.bazel +++ b/pkg/util/BUILD.bazel @@ -3,7 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ - "context.go", "useragent.go", "util.go", "version.go", @@ -34,7 +33,6 @@ filegroup( srcs = [ ":package-srcs", "//pkg/util/cmapichecker:all-srcs", - "//pkg/util/cmd:all-srcs", "//pkg/util/coverage:all-srcs", "//pkg/util/errors:all-srcs", "//pkg/util/feature:all-srcs", diff --git a/pkg/util/cmd/signal.go b/pkg/util/cmd/signal.go deleted file mode 100644 index d38e9a041..000000000 --- a/pkg/util/cmd/signal.go +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright 2020 The cert-manager 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 cmd - -import ( - "os" - "os/signal" -) - -var onlyOneSignalHandler = make(chan struct{}) - -// SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned -// which is closed on one of these signals. If a second signal is caught, the program -// is terminated with exit code 1. -func SetupSignalHandler() <-chan struct{} { - close(onlyOneSignalHandler) // panics when called twice - - stop := make(chan struct{}) - c := make(chan os.Signal, 2) - signal.Notify(c, shutdownSignals...) - go func() { - <-c - close(stop) - <-c - os.Exit(1) // second signal. Exit directly. - }() - - return stop -}