diff --git a/pkg/manager/signals/doc.go b/pkg/manager/signals/doc.go index 737cc7eff2..246bf5275d 100644 --- a/pkg/manager/signals/doc.go +++ b/pkg/manager/signals/doc.go @@ -18,3 +18,9 @@ limitations under the License. // shutdown the manager in combination with Kubernetes pod graceful termination // policy. package signals + +import ( + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("signal") diff --git a/pkg/manager/signals/signal.go b/pkg/manager/signals/signal.go index 08eaef7b42..0341b42e54 100644 --- a/pkg/manager/signals/signal.go +++ b/pkg/manager/signals/signal.go @@ -19,6 +19,14 @@ package signals import ( "os" "os/signal" + "strconv" + "time" +) + +const ( + channelClosureDelaySecondsEnv = "CHANNEL_CLOSURE_DELAY_SECONDS" + + defaultChannelClosureDelaySeconds = 0 ) var onlyOneSignalHandler = make(chan struct{}) @@ -34,6 +42,9 @@ func SetupSignalHandler() (stopCh <-chan struct{}) { signal.Notify(c, shutdownSignals...) go func() { <-c + d := getDelaySecondsFromEnv() + log.Info("receive signal", "delay", d) + time.Sleep(time.Duration(d) * time.Second) close(stop) <-c os.Exit(1) // second signal. Exit directly. @@ -41,3 +52,21 @@ func SetupSignalHandler() (stopCh <-chan struct{}) { return stop } + +func getDelaySecondsFromEnv() int { + delayStr := os.Getenv(channelClosureDelaySecondsEnv) + if len(delayStr) == 0 { + return defaultChannelClosureDelaySeconds + } + + delay, err := strconv.Atoi(delayStr) + if err != nil { + log.Info("failed to convert channel closure delay", "envvar", delayStr) + return defaultChannelClosureDelaySeconds + } + if delay < 0 { + log.Info("get invalid channel closure delay from envvar", "envvar", delayStr) + return 0 + } + return delay +}