Skip to content

Commit c930ee7

Browse files
stttsbertinatto
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 #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 0bb57fe commit c930ee7

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

cmd/kube-apiserver/app/server.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,8 @@ func init() {
7171
// NewAPIServerCommand creates a *cobra.Command object with default parameters
7272
func NewAPIServerCommand() *cobra.Command {
7373
s := options.NewServerRunOptions()
74-
ctx := genericapiserver.SetupSignalContext()
74+
ctx := genericapiserver.SetupSignalContextNotExiting()
7575
featureGate := s.GenericServerRunOptions.ComponentGlobalsRegistry.FeatureGateFor(basecompatibility.DefaultKubeComponent)
76-
7776
cmd := &cobra.Command{
7877
Use: "kube-apiserver",
7978
Long: `The Kubernetes API server validates and configures data
@@ -158,6 +157,7 @@ cluster's shared state through which all other components interact.`,
158157
return nil
159158
},
160159
}
160+
161161
cmd.SetContext(ctx)
162162

163163
fs := cmd.Flags()

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

+27-2
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)