Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add timeout to pod stop #1953

Merged
merged 1 commit into from Dec 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions API.md
Expand Up @@ -113,7 +113,7 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in

[func StopContainer(name: string, timeout: int) string](#StopContainer)

[func StopPod(name: string) string](#StopPod)
[func StopPod(name: string, timeout: int) string](#StopPod)

[func TagImage(name: string, tagged: string) string](#TagImage)

Expand Down Expand Up @@ -741,8 +741,8 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.StopContainer '{"name": "
### <a name="StopPod"></a>func StopPod
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">

method StopPod(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
StopPod stops containers in a pod. It takes the name or ID of a pod.
method StopPod(name: [string](https://godoc.org/builtin#string), timeout: [int](https://godoc.org/builtin#int)) [string](https://godoc.org/builtin#string)</div>
StopPod stops containers in a pod. It takes the name or ID of a pod and a timeout.
If the pod cannot be found, a [PodNotFound](#PodNotFound) error will be returned instead.
Containers in a pod are stopped independently. If there is an error stopping one container, the ID of those containers
will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError).
Expand Down
11 changes: 9 additions & 2 deletions cmd/podman/pod_stop.go
Expand Up @@ -2,7 +2,6 @@ package main

import (
"fmt"

"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand All @@ -16,6 +15,10 @@ var (
Usage: "stop all running pods",
},
LatestPodFlag,
cli.UintFlag{
Name: "timeout, time, t",
Usage: "Seconds to wait for pod stop before killing the container",
},
}
podStopDescription = `
podman pod stop
Expand All @@ -35,6 +38,7 @@ var (
)

func podStopCmd(c *cli.Context) error {
timeout := -1
if err := checkMutuallyExclusiveFlags(c); err != nil {
return err
}
Expand All @@ -52,9 +56,12 @@ func podStopCmd(c *cli.Context) error {

ctx := getContext()

if c.IsSet("timeout") {
timeout = int(c.Uint("timeout"))
}
for _, pod := range pods {
// set cleanup to true to clean mounts and namespaces
ctr_errs, err := pod.Stop(ctx, true)
ctr_errs, err := pod.StopWithTimeout(ctx, true, timeout)
if ctr_errs != nil {
for ctr, err := range ctr_errs {
if lastError != nil {
Expand Down
4 changes: 2 additions & 2 deletions cmd/podman/varlink/io.podman.varlink
Expand Up @@ -715,7 +715,7 @@ method InspectPod(name: string) -> (pod: string)
# ~~~
method StartPod(name: string) -> (pod: string)

# StopPod stops containers in a pod. It takes the name or ID of a pod.
# StopPod stops containers in a pod. It takes the name or ID of a pod and a timeout.
# If the pod cannot be found, a [PodNotFound](#PodNotFound) error will be returned instead.
# Containers in a pod are stopped independently. If there is an error stopping one container, the ID of those containers
# will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError).
Expand All @@ -728,7 +728,7 @@ method StartPod(name: string) -> (pod: string)
# "pod": "135d71b9495f7c3967f536edad57750bfdb569336cd107d8aabab45565ffcfb6"
# }
# ~~~
method StopPod(name: string) -> (pod: string)
method StopPod(name: string, timeout: int) -> (pod: string)

# RestartPod will restart containers in a pod given a pod name or ID. Containers in
# the pod that are running will be stopped, then all stopped containers will be run.
Expand Down
2 changes: 2 additions & 0 deletions completions/bash/podman
Expand Up @@ -2451,6 +2451,8 @@ _podman_pod_start() {

_podman_pod_stop() {
local options_with_args="
-t
--timeout
"

local boolean_options="
Expand Down
34 changes: 28 additions & 6 deletions docs/podman-pod-stop.1.md
Expand Up @@ -19,26 +19,48 @@ Stops all pods

Instead of providing the pod name or ID, stop the last created pod.

**--timeout, --time, t**

Timeout to wait before forcibly stopping the containers in the pod.

## EXAMPLE

podman pod stop mywebserverpod
Stop a pod called *mywebserverpod*
```
$ podman pod stop mywebserverpod
cc8f0bea67b1a1a11aec1ecd38102a1be4b145577f21fc843c7c83b77fc28907
```

podman pod stop 490eb 3557fb
Stop two pods by their short IDs.
```
$ podman pod stop 490eb 3557fb
490eb241aaf704d4dd2629904410fe4aa31965d9310a735f8755267f4ded1de5
3557fbea6ad61569de0506fe037479bd9896603c31d3069a6677f23833916fab
```

Stop the most recent pod
```
$ podman pod stop --latest
3557fbea6ad61569de0506fe037479bd9896603c31d3069a6677f23833916fab
```

podman pod stop --latest
3557fbea6ad61569de0506fe037479bd9896603c31d3069a6677f23833916fab

podman pod stop --all
Stop all pods
```
$ podman pod stop --all
19456b4cd557eaf9629825113a552681a6013f8c8cad258e36ab825ef536e818
3557fbea6ad61569de0506fe037479bd9896603c31d3069a6677f23833916fab
490eb241aaf704d4dd2629904410fe4aa31965d9310a735f8755267f4ded1de5
70c358daecf71ef9be8f62404f926080ca0133277ef7ce4f6aa2d5af6bb2d3e9
cc8f0bea67b1a1a11aec1ecd38102a1be4b145577f21fc843c7c83b77fc28907
```
baude marked this conversation as resolved.
Show resolved Hide resolved

Stop all pods with a timeout of 1 second.
```
$ podman pod stop -a -t 1
3557fbea6ad61569de0506fe037479bd9896603c31d3069a6677f23833916fab
490eb241aaf704d4dd2629904410fe4aa31965d9310a735f8755267f4ded1de5
70c358daecf71ef9be8f62404f926080ca0133277ef7ce4f6aa2d5af6bb2d3e9
```

## SEE ALSO
podman-pod(1), podman-pod-start(1), podman-stop(1)
Expand Down
17 changes: 13 additions & 4 deletions libpod/pod_api.go
Expand Up @@ -62,7 +62,13 @@ func (p *Pod) Start(ctx context.Context) (map[string]error, error) {
return nil, nil
}

// Stop stops all containers within a pod that are not already stopped
// Stop stops all containers within a pod without a timeout. It assumes -1 for
// a timeout.
func (p *Pod) Stop(ctx context.Context, cleanup bool) (map[string]error, error) {
return p.StopWithTimeout(ctx, cleanup, -1)
}

// StopWithTimeout stops all containers within a pod that are not already stopped
// Each container will use its own stop timeout
// Only running containers will be stopped. Paused, stopped, or created
// containers will be ignored.
Expand All @@ -77,7 +83,7 @@ func (p *Pod) Start(ctx context.Context) (map[string]error, error) {
// containers. The container ID is mapped to the error encountered. The error is
// set to ErrCtrExists
// If both error and the map are nil, all containers were stopped without error
func (p *Pod) Stop(ctx context.Context, cleanup bool) (map[string]error, error) {
func (p *Pod) StopWithTimeout(ctx context.Context, cleanup bool, timeout int) (map[string]error, error) {
p.lock.Lock()
defer p.lock.Unlock()

Expand Down Expand Up @@ -110,8 +116,11 @@ func (p *Pod) Stop(ctx context.Context, cleanup bool) (map[string]error, error)
ctr.lock.Unlock()
continue
}

if err := ctr.stop(ctr.config.StopTimeout); err != nil {
stopTimeout := ctr.config.StopTimeout
if timeout > -1 {
stopTimeout = uint(timeout)
}
if err := ctr.stop(stopTimeout); err != nil {
ctr.lock.Unlock()
ctrErrors[ctr.ID()] = err
continue
Expand Down
4 changes: 2 additions & 2 deletions pkg/varlinkapi/pods.go
Expand Up @@ -120,12 +120,12 @@ func (i *LibpodAPI) StartPod(call iopodman.VarlinkCall, name string) error {
}

// StopPod ...
func (i *LibpodAPI) StopPod(call iopodman.VarlinkCall, name string) error {
func (i *LibpodAPI) StopPod(call iopodman.VarlinkCall, name string, timeout int64) error {
pod, err := i.Runtime.LookupPod(name)
if err != nil {
return call.ReplyPodNotFound(name)
}
ctrErrs, err := pod.Stop(getContext(), true)
ctrErrs, err := pod.StopWithTimeout(getContext(), true, int(timeout))
callErr := handlePodCall(call, pod, ctrErrs, err)
if callErr != nil {
return err
Expand Down