Skip to content

Commit 938c43a

Browse files
committed
add signal option to container stop command
Signed-off-by: Arjun Raja Yogidas <[email protected]>
1 parent 87cc074 commit 938c43a

File tree

5 files changed

+30
-10
lines changed

5 files changed

+30
-10
lines changed

cmd/nerdctl/container/container_stop.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func NewStopCommand() *cobra.Command {
4141
SilenceErrors: true,
4242
}
4343
stopCommand.Flags().IntP("time", "t", 10, "Seconds to wait before sending a SIGKILL")
44+
stopCommand.Flags().StringP("signal", "s", "SIGTERM", "Signal to send to the container")
4445
return stopCommand
4546
}
4647

@@ -58,11 +59,20 @@ func processContainerStopOptions(cmd *cobra.Command) (types.ContainerStopOptions
5859
t := time.Duration(timeValue) * time.Second
5960
timeout = &t
6061
}
62+
var signal string
63+
if cmd.Flags().Changed("signal") {
64+
signalValue, err := cmd.Flags().GetString("signal")
65+
if err != nil {
66+
return types.ContainerStopOptions{}, err
67+
}
68+
signal = signalValue
69+
}
6170
return types.ContainerStopOptions{
6271
Stdout: cmd.OutOrStdout(),
6372
Stderr: cmd.ErrOrStderr(),
6473
GOptions: globalOptions,
6574
Timeout: timeout,
75+
Signal: signal,
6676
}, nil
6777
}
6878

pkg/api/types/container_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ type ContainerStopOptions struct {
275275
// Timeout specifies how long to wait after sending a SIGTERM and before sending a SIGKILL.
276276
// If it's nil, the default is 10 seconds.
277277
Timeout *time.Duration
278+
279+
// singal to send to the container, before sending sigkill
280+
Signal string
278281
}
279282

280283
// ContainerRestartOptions specifies options for `nerdctl (container) restart`.

pkg/cmd/container/restart.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func Restart(ctx context.Context, client *containerd.Client, containers []string
3535
if found.MatchCount > 1 {
3636
return fmt.Errorf("multiple IDs found with provided prefix: %s", found.Req)
3737
}
38-
if err := containerutil.Stop(ctx, found.Container, options.Timeout); err != nil {
38+
if err := containerutil.Stop(ctx, found.Container, options.Timeout, "SIGTERM"); err != nil {
3939
return err
4040
}
4141
if err := containerutil.Start(ctx, found.Container, false, client, ""); err != nil {

pkg/cmd/container/stop.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func Stop(ctx context.Context, client *containerd.Client, reqs []string, opt typ
3939
if err := cleanupNetwork(ctx, found.Container, opt.GOptions); err != nil {
4040
return fmt.Errorf("unable to cleanup network for container: %s", found.Req)
4141
}
42-
if err := containerutil.Stop(ctx, found.Container, opt.Timeout); err != nil {
42+
if err := containerutil.Stop(ctx, found.Container, opt.Timeout, opt.Signal); err != nil {
4343
if errdefs.IsNotFound(err) {
4444
fmt.Fprintf(opt.Stderr, "No such container: %s\n", found.Req)
4545
return nil

pkg/containerutil/containerutil.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"path/filepath"
2727
"strconv"
2828
"strings"
29+
"syscall"
2930
"time"
3031

3132
dockercliopts "github.com/docker/cli/opts"
@@ -336,7 +337,7 @@ func Start(ctx context.Context, container containerd.Container, flagA bool, clie
336337
}
337338

338339
// Stop stops `container` by sending SIGTERM. If the container is not stopped after `timeout`, it sends a SIGKILL.
339-
func Stop(ctx context.Context, container containerd.Container, timeout *time.Duration) (err error) {
340+
func Stop(ctx context.Context, container containerd.Container, timeout *time.Duration, signalValue string) (err error) {
340341
// defer the storage of stop error in the dedicated label
341342
defer func() {
342343
if err != nil {
@@ -409,16 +410,10 @@ func Stop(ctx context.Context, container containerd.Container, timeout *time.Dur
409410
}
410411

411412
if *timeout > 0 {
412-
sig, err := signal.ParseSignal("SIGTERM")
413+
sig, err := getSignal(signalValue, l)
413414
if err != nil {
414415
return err
415416
}
416-
if stopSignal, ok := l[containerd.StopSignalLabel]; ok {
417-
sig, err = signal.ParseSignal(stopSignal)
418-
if err != nil {
419-
return err
420-
}
421-
}
422417

423418
if err := task.Kill(ctx, sig); err != nil {
424419
return err
@@ -465,6 +460,18 @@ func Stop(ctx context.Context, container containerd.Container, timeout *time.Dur
465460
return waitContainerStop(ctx, exitCh, container.ID())
466461
}
467462

463+
func getSignal(signalValue string, containerLabels map[string]string) (syscall.Signal, error) {
464+
if signalValue != "" {
465+
return signal.ParseSignal(signalValue)
466+
}
467+
468+
if stopSignal, ok := containerLabels[containerd.StopSignalLabel]; ok {
469+
return signal.ParseSignal(stopSignal)
470+
}
471+
472+
return signal.ParseSignal("SIGTERM")
473+
}
474+
468475
func waitContainerStop(ctx context.Context, exitCh <-chan containerd.ExitStatus, id string) error {
469476
select {
470477
case <-ctx.Done():

0 commit comments

Comments
 (0)