Fixes #10457-Pause-and-unpause-accept-multi-containers

Applied multi parameters to pause and unpause.
Created a new test file dedicated for pause commands.
Created a new utility function to get a slice of paused containers.
Updated documentation

Signed-off-by: André Martins <martins@noironetworks.com>
This commit is contained in:
André Martins 2015-01-31 00:23:47 +00:00
parent 414a37f90a
commit 0ce42dcc96
7 changed files with 131 additions and 59 deletions

View File

@ -786,8 +786,8 @@ func (cli *DockerCli) CmdStart(args ...string) error {
} }
func (cli *DockerCli) CmdUnpause(args ...string) error { func (cli *DockerCli) CmdUnpause(args ...string) error {
cmd := cli.Subcmd("unpause", "CONTAINER", "Unpause all processes within a container", true) cmd := cli.Subcmd("unpause", "CONTAINER [CONTAINER...]", "Unpause all processes within a container", true)
cmd.Require(flag.Exact, 1) cmd.Require(flag.Min, 1)
utils.ParseFlags(cmd, args, false) utils.ParseFlags(cmd, args, false)
var encounteredError error var encounteredError error
@ -803,8 +803,8 @@ func (cli *DockerCli) CmdUnpause(args ...string) error {
} }
func (cli *DockerCli) CmdPause(args ...string) error { func (cli *DockerCli) CmdPause(args ...string) error {
cmd := cli.Subcmd("pause", "CONTAINER", "Pause all processes within a container", true) cmd := cli.Subcmd("pause", "CONTAINER [CONTAINER...]", "Pause all processes within a container", true)
cmd.Require(flag.Exact, 1) cmd.Require(flag.Min, 1)
utils.ParseFlags(cmd, args, false) utils.ParseFlags(cmd, args, false)
var encounteredError error var encounteredError error

View File

@ -6,7 +6,7 @@ docker-pause - Pause all processes within a container
# SYNOPSIS # SYNOPSIS
**docker pause** **docker pause**
CONTAINER CONTAINER [CONTAINER...]
# DESCRIPTION # DESCRIPTION

View File

@ -6,7 +6,7 @@ docker-unpause - Unpause all processes within a container
# SYNOPSIS # SYNOPSIS
**docker unpause** **docker unpause**
CONTAINER CONTAINER [CONTAINER...]
# DESCRIPTION # DESCRIPTION

View File

@ -1359,7 +1359,7 @@ nano-second part of the timestamp will be padded with zero when necessary.
## pause ## pause
Usage: docker pause CONTAINER Usage: docker pause CONTAINER [CONTAINER...]
Pause all processes within a container Pause all processes within a container
@ -1396,22 +1396,6 @@ just a specific mapping:
$ sudo docker port test 7890 $ sudo docker port test 7890
0.0.0.0:4321 0.0.0.0:4321
## pause
Usage: docker pause CONTAINER
Pause all processes within a container
The `docker pause` command uses the cgroups freezer to suspend all processes in
a container. Traditionally when suspending a process the `SIGSTOP` signal is
used, which is observable by the process being suspended. With the cgroups freezer
the process is unaware, and unable to capture, that it is being suspended,
and subsequently resumed.
See the
[cgroups freezer documentation](https://www.kernel.org/doc/Documentation/cgroups/freezer-subsystem.txt)
for further details.
## rename ## rename
Usage: docker rename OLD_NAME NEW_NAME Usage: docker rename OLD_NAME NEW_NAME
@ -2081,7 +2065,7 @@ them to [*Share Images via Repositories*](
## unpause ## unpause
Usage: docker unpause CONTAINER Usage: docker unpause CONTAINER [CONTAINER...]
Unpause all processes within a container Unpause all processes within a container

View File

@ -30,41 +30,6 @@ func TestEventsUntag(t *testing.T) {
logDone("events - untags are logged") logDone("events - untags are logged")
} }
func TestEventsPause(t *testing.T) {
name := "testeventpause"
out, _, _ := dockerCmd(t, "images", "-q")
image := strings.Split(out, "\n")[0]
dockerCmd(t, "run", "-d", "--name", name, image, "sleep", "2")
dockerCmd(t, "pause", name)
dockerCmd(t, "unpause", name)
defer deleteAllContainers()
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
out, _, _ = runCommandWithOutput(eventsCmd)
events := strings.Split(out, "\n")
if len(events) <= 1 {
t.Fatalf("Missing expected event")
}
pauseEvent := strings.Fields(events[len(events)-3])
unpauseEvent := strings.Fields(events[len(events)-2])
if pauseEvent[len(pauseEvent)-1] != "pause" {
t.Fatalf("event should be pause, not %#v", pauseEvent)
}
if unpauseEvent[len(unpauseEvent)-1] != "unpause" {
t.Fatalf("event should be unpause, not %#v", unpauseEvent)
}
waitCmd := exec.Command(dockerBinary, "wait", name)
if waitOut, _, err := runCommandWithOutput(waitCmd); err != nil {
t.Fatalf("error thrown while waiting for container: %s, %v", waitOut, err)
}
logDone("events - pause/unpause is logged")
}
func TestEventsContainerFailStartDie(t *testing.T) { func TestEventsContainerFailStartDie(t *testing.T) {
defer deleteAllContainers() defer deleteAllContainers()

View File

@ -0,0 +1,113 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
"time"
)
func TestPause(t *testing.T) {
defer deleteAllContainers()
defer unpauseAllContainers()
name := "testeventpause"
out, _, _ := dockerCmd(t, "images", "-q")
image := strings.Split(out, "\n")[0]
dockerCmd(t, "run", "-d", "--name", name, image, "sleep", "2")
dockerCmd(t, "pause", name)
pausedContainers, err := getSliceOfPausedContainers()
if err != nil {
t.Fatalf("error thrown while checking if containers were paused: %v", err)
}
if len(pausedContainers) != 1 {
t.Fatalf("there should be one paused container and not", len(pausedContainers))
}
dockerCmd(t, "unpause", name)
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
out, _, _ = runCommandWithOutput(eventsCmd)
events := strings.Split(out, "\n")
if len(events) <= 1 {
t.Fatalf("Missing expected event")
}
pauseEvent := strings.Fields(events[len(events)-3])
unpauseEvent := strings.Fields(events[len(events)-2])
if pauseEvent[len(pauseEvent)-1] != "pause" {
t.Fatalf("event should be pause, not %#v", pauseEvent)
}
if unpauseEvent[len(unpauseEvent)-1] != "unpause" {
t.Fatalf("event should be unpause, not %#v", unpauseEvent)
}
waitCmd := exec.Command(dockerBinary, "wait", name)
if waitOut, _, err := runCommandWithOutput(waitCmd); err != nil {
t.Fatalf("error thrown while waiting for container: %s, %v", waitOut, err)
}
logDone("pause - pause/unpause is logged")
}
func TestPauseMultipleContainers(t *testing.T) {
defer deleteAllContainers()
defer unpauseAllContainers()
containers := []string{
"testpausewithmorecontainers1",
"testpausewithmorecontainers2",
}
out, _, _ := dockerCmd(t, "images", "-q")
image := strings.Split(out, "\n")[0]
for _, name := range containers {
dockerCmd(t, "run", "-d", "--name", name, image, "sleep", "2")
}
dockerCmd(t, append([]string{"pause"}, containers...)...)
pausedContainers, err := getSliceOfPausedContainers()
if err != nil {
t.Fatalf("error thrown while checking if containers were paused: %v", err)
}
if len(pausedContainers) != len(containers) {
t.Fatalf("there should be %d paused container and not %d", len(containers), len(pausedContainers))
}
dockerCmd(t, append([]string{"unpause"}, containers...)...)
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
out, _, _ = runCommandWithOutput(eventsCmd)
events := strings.Split(out, "\n")
if len(events) <= len(containers)*3-2 {
t.Fatalf("Missing expected event")
}
pauseEvents := make([][]string, len(containers))
unpauseEvents := make([][]string, len(containers))
for i := range containers {
pauseEvents[i] = strings.Fields(events[len(events)-len(containers)*2-1+i])
unpauseEvents[i] = strings.Fields(events[len(events)-len(containers)-1+i])
}
for _, pauseEvent := range pauseEvents {
if pauseEvent[len(pauseEvent)-1] != "pause" {
t.Fatalf("event should be pause, not %#v", pauseEvent)
}
}
for _, unpauseEvent := range unpauseEvents {
if unpauseEvent[len(unpauseEvent)-1] != "unpause" {
t.Fatalf("event should be unpause, not %#v", unpauseEvent)
}
}
for _, name := range containers {
waitCmd := exec.Command(dockerBinary, "wait", name)
if waitOut, _, err := runCommandWithOutput(waitCmd); err != nil {
t.Fatalf("error thrown while waiting for container: %s, %v", waitOut, err)
}
}
logDone("pause - multi pause/unpause is logged")
}

View File

@ -380,6 +380,16 @@ func getPausedContainers() (string, error) {
return out, err return out, err
} }
func getSliceOfPausedContainers() ([]string, error) {
out, err := getPausedContainers()
if err == nil {
slice := strings.Split(strings.TrimSpace(out), "\n")
return slice, err
} else {
return []string{out}, err
}
}
func unpauseContainer(container string) error { func unpauseContainer(container string) error {
unpauseCmd := exec.Command(dockerBinary, "unpause", container) unpauseCmd := exec.Command(dockerBinary, "unpause", container)
exitCode, err := runCommand(unpauseCmd) exitCode, err := runCommand(unpauseCmd)