Skip to content

Commit bdd6fdf

Browse files
stttsjacobsee
authored andcommitted
UPSTREAM: <carry>: kube-apiserver: ignore SIGTERM/INT after the first one
UPSTREAM: <carry>: kube-apiserver: set up separate signal handler functions to ignore further signals This patches the changes from openshift#558 to provide these new functions without changing the behavior for other repos that depend on them, such as library-go. OpenShift-Rebase-Source: 63ed200
1 parent d5951a6 commit bdd6fdf

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

cmd/kube-apiserver/app/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,8 @@ func init() {
7373
// NewAPIServerCommand creates a *cobra.Command object with default parameters
7474
func NewAPIServerCommand() *cobra.Command {
7575
s := options.NewServerRunOptions()
76-
ctx := genericapiserver.SetupSignalContext()
76+
ctx := genericapiserver.SetupSignalContextNotExiting()
7777
featureGate := s.GenericServerRunOptions.ComponentGlobalsRegistry.FeatureGateFor(basecompatibility.DefaultKubeComponent)
78-
7978
cmd := &cobra.Command{
8079
Use: "kube-apiserver",
8180
Long: `The Kubernetes API server validates and configures data
@@ -162,6 +161,7 @@ cluster's shared state through which all other components interact.`,
162161
return nil
163162
},
164163
}
164+
165165
cmd.SetContext(ctx)
166166

167167
fs := cmd.Flags()

staging/src/k8s.io/apiserver/pkg/server/signal.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"context"
2121
"os"
2222
"os/signal"
23+
24+
"k8s.io/klog/v2"
2325
)
2426

2527
var onlyOneSignalHandler = make(chan struct{})
@@ -34,10 +36,26 @@ func SetupSignalHandler() <-chan struct{} {
3436
return SetupSignalContext().Done()
3537
}
3638

39+
// SetupSignalHandlerIgnoringFurtherSignals is the same as SetupSignalContext, except
40+
// it ignores further exit signals after receiving the first one.
41+
func SetupSignalHandlerIgnoringFurtherSignals() <-chan struct{} {
42+
return SetupSignalContextNotExiting().Done()
43+
}
44+
3745
// SetupSignalContext is same as SetupSignalHandler, but a context.Context is returned.
3846
// Only one of SetupSignalContext and SetupSignalHandler should be called, and only can
3947
// be called once.
4048
func SetupSignalContext() context.Context {
49+
return setupSignalContext(true)
50+
}
51+
52+
// SetupSignalContextNotExiting is the same as SetupSignalContext, except
53+
// it ignores further exit signals after receiving the first one.
54+
func SetupSignalContextNotExiting() context.Context {
55+
return setupSignalContext(false)
56+
}
57+
58+
func setupSignalContext(exitOnSecondSignal bool) context.Context {
4159
close(onlyOneSignalHandler) // panics when called twice
4260

4361
shutdownHandler = make(chan os.Signal, 2)
@@ -47,8 +65,15 @@ func SetupSignalContext() context.Context {
4765
go func() {
4866
<-shutdownHandler
4967
cancel()
50-
<-shutdownHandler
51-
os.Exit(1) // second signal. Exit directly.
68+
if exitOnSecondSignal {
69+
<-shutdownHandler
70+
os.Exit(1)
71+
} else {
72+
for {
73+
<-shutdownHandler
74+
klog.Infof("Termination signal has been received already. Ignoring signal.")
75+
}
76+
}
5277
}()
5378

5479
return ctx

0 commit comments

Comments
 (0)