API: add "signal" parameter to container stop and restart endpoints
Containers can have a default stop-signal (`--stop-signal` / `STOPSIGNAL`) and timeout (`--stop-timeout`). It is currently not possible to update either of these after the container is created (`docker update` does not allow updating them), and while either of these can be overridden through some commands, we currently do not have a command that can override *both*: command | stop-signal | stop-timeout | notes ----------------|-------------|--------------|---------------------------- docker kill | yes | DNA | only sends a single signal docker restart | no | yes | docker stop | no | yes | As a result, if a user wants to stop a container with a custom signal and timeout, the only option is to do this manually: docker kill -s <custom signal> mycontainer # wait <desired timeout> # press ^C to cancel the graceful stop # forcibly kill the container docker kill mycontainer This patch adds a new `signal` query parameter to the container "stop" and "restart" endpoints. This parameter can be added as a new flag on the CLI, which would allow stopping and restarting with a custom timeout and signal, for example: docker stop --signal=SIGWINCH --time=120 mycontainer docker restart --signal=SIGWINCH --time=120 mycontainer Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
90de570cfa
commit
83a185897d
5 changed files with 53 additions and 5 deletions
|
@ -221,7 +221,18 @@ func (s *containerRouter) postContainersStop(ctx context.Context, w http.Respons
|
|||
return err
|
||||
}
|
||||
|
||||
var options container.StopOptions
|
||||
var (
|
||||
options container.StopOptions
|
||||
version = httputils.VersionFromContext(ctx)
|
||||
)
|
||||
if versions.GreaterThanOrEqualTo(version, "1.42") {
|
||||
if sig := r.Form.Get("signal"); sig != "" {
|
||||
if _, err := signal.ParseSignal(sig); err != nil {
|
||||
return errdefs.InvalidParameter(err)
|
||||
}
|
||||
options.Signal = sig
|
||||
}
|
||||
}
|
||||
if tmpSeconds := r.Form.Get("t"); tmpSeconds != "" {
|
||||
valSeconds, err := strconv.Atoi(tmpSeconds)
|
||||
if err != nil {
|
||||
|
@ -233,8 +244,8 @@ func (s *containerRouter) postContainersStop(ctx context.Context, w http.Respons
|
|||
if err := s.backend.ContainerStop(ctx, vars["name"], options); err != nil {
|
||||
return err
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -278,7 +289,18 @@ func (s *containerRouter) postContainersRestart(ctx context.Context, w http.Resp
|
|||
return err
|
||||
}
|
||||
|
||||
var options container.StopOptions
|
||||
var (
|
||||
options container.StopOptions
|
||||
version = httputils.VersionFromContext(ctx)
|
||||
)
|
||||
if versions.GreaterThanOrEqualTo(version, "1.42") {
|
||||
if sig := r.Form.Get("signal"); sig != "" {
|
||||
if _, err := signal.ParseSignal(sig); err != nil {
|
||||
return errdefs.InvalidParameter(err)
|
||||
}
|
||||
options.Signal = sig
|
||||
}
|
||||
}
|
||||
if tmpSeconds := r.Form.Get("t"); tmpSeconds != "" {
|
||||
valSeconds, err := strconv.Atoi(tmpSeconds)
|
||||
if err != nil {
|
||||
|
@ -292,7 +314,6 @@ func (s *containerRouter) postContainersRestart(ctx context.Context, w http.Resp
|
|||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -6862,6 +6862,11 @@ paths:
|
|||
required: true
|
||||
description: "ID or name of the container"
|
||||
type: "string"
|
||||
- name: "signal"
|
||||
in: "query"
|
||||
description: |
|
||||
Signal to send to the container as an integer or string (e.g. `SIGINT`).
|
||||
type: "string"
|
||||
- name: "t"
|
||||
in: "query"
|
||||
description: "Number of seconds to wait before killing the container"
|
||||
|
@ -6891,6 +6896,11 @@ paths:
|
|||
required: true
|
||||
description: "ID or name of the container"
|
||||
type: "string"
|
||||
- name: "signal"
|
||||
in: "query"
|
||||
description: |
|
||||
Signal to send to the container as an integer or string (e.g. `SIGINT`).
|
||||
type: "string"
|
||||
- name: "t"
|
||||
in: "query"
|
||||
description: "Number of seconds to wait before killing the container"
|
||||
|
@ -6932,7 +6942,8 @@ paths:
|
|||
type: "string"
|
||||
- name: "signal"
|
||||
in: "query"
|
||||
description: "Signal to send to the container as an integer or string (e.g. `SIGINT`)"
|
||||
description: |
|
||||
Signal to send to the container as an integer or string (e.g. `SIGINT`).
|
||||
type: "string"
|
||||
default: "SIGKILL"
|
||||
tags: ["Container"]
|
||||
|
|
|
@ -15,6 +15,11 @@ const MinimumDuration = 1 * time.Millisecond
|
|||
|
||||
// StopOptions holds the options to stop or restart a container.
|
||||
type StopOptions struct {
|
||||
// Signal (optional) is the signal to send to the container to (gracefully)
|
||||
// stop it before forcibly terminating the container with SIGKILL after the
|
||||
// timeout expires. If not value is set, the default (SIGTERM) is used.
|
||||
Signal string `json:",omitempty"`
|
||||
|
||||
// Timeout (optional) is the timeout (in seconds) to wait for the container
|
||||
// to stop gracefully before forcibly terminating it with SIGKILL.
|
||||
//
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/moby/sys/signal"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
@ -44,6 +45,13 @@ func (daemon *Daemon) containerStop(ctx context.Context, ctr *container.Containe
|
|||
stopSignal = ctr.StopSignal()
|
||||
stopTimeout = ctr.StopTimeout()
|
||||
)
|
||||
if options.Signal != "" {
|
||||
sig, err := signal.ParseSignal(options.Signal)
|
||||
if err != nil {
|
||||
return errdefs.InvalidParameter(err)
|
||||
}
|
||||
stopSignal = int(sig)
|
||||
}
|
||||
if options.Timeout != nil {
|
||||
stopTimeout = *options.Timeout
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||
was introduced in API 1.31 as part of an experimental feature, and no longer
|
||||
used since API 1.40.
|
||||
Use field `BuildCache` instead to track storage used by the builder component.
|
||||
* `POST /containers/{id}/stop` and `POST /containers/{id}/restart` now accept a
|
||||
`signal` query parameter, which allows overriding the container's default stop-
|
||||
signal.
|
||||
* `GET /images/json` now accepts query parameter `shared-size`. When set `true`,
|
||||
images returned will include `SharedSize`, which provides the size on disk shared
|
||||
with other images present on the system.
|
||||
|
|
Loading…
Add table
Reference in a new issue