зеркало из https://github.com/microsoft/docker.git
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:
Родитель
414a37f90a
Коммит
0ce42dcc96
|
@ -786,8 +786,8 @@ func (cli *DockerCli) CmdStart(args ...string) error {
|
|||
}
|
||||
|
||||
func (cli *DockerCli) CmdUnpause(args ...string) error {
|
||||
cmd := cli.Subcmd("unpause", "CONTAINER", "Unpause all processes within a container", true)
|
||||
cmd.Require(flag.Exact, 1)
|
||||
cmd := cli.Subcmd("unpause", "CONTAINER [CONTAINER...]", "Unpause all processes within a container", true)
|
||||
cmd.Require(flag.Min, 1)
|
||||
utils.ParseFlags(cmd, args, false)
|
||||
|
||||
var encounteredError error
|
||||
|
@ -803,8 +803,8 @@ func (cli *DockerCli) CmdUnpause(args ...string) error {
|
|||
}
|
||||
|
||||
func (cli *DockerCli) CmdPause(args ...string) error {
|
||||
cmd := cli.Subcmd("pause", "CONTAINER", "Pause all processes within a container", true)
|
||||
cmd.Require(flag.Exact, 1)
|
||||
cmd := cli.Subcmd("pause", "CONTAINER [CONTAINER...]", "Pause all processes within a container", true)
|
||||
cmd.Require(flag.Min, 1)
|
||||
utils.ParseFlags(cmd, args, false)
|
||||
|
||||
var encounteredError error
|
||||
|
|
|
@ -6,7 +6,7 @@ docker-pause - Pause all processes within a container
|
|||
|
||||
# SYNOPSIS
|
||||
**docker pause**
|
||||
CONTAINER
|
||||
CONTAINER [CONTAINER...]
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ docker-unpause - Unpause all processes within a container
|
|||
|
||||
# SYNOPSIS
|
||||
**docker unpause**
|
||||
CONTAINER
|
||||
CONTAINER [CONTAINER...]
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
|
|
|
@ -1359,7 +1359,7 @@ nano-second part of the timestamp will be padded with zero when necessary.
|
|||
|
||||
## pause
|
||||
|
||||
Usage: docker pause CONTAINER
|
||||
Usage: docker pause CONTAINER [CONTAINER...]
|
||||
|
||||
Pause all processes within a container
|
||||
|
||||
|
@ -1396,22 +1396,6 @@ just a specific mapping:
|
|||
$ sudo docker port test 7890
|
||||
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
|
||||
|
||||
Usage: docker rename OLD_NAME NEW_NAME
|
||||
|
@ -2081,7 +2065,7 @@ them to [*Share Images via Repositories*](
|
|||
|
||||
## unpause
|
||||
|
||||
Usage: docker unpause CONTAINER
|
||||
Usage: docker unpause CONTAINER [CONTAINER...]
|
||||
|
||||
Unpause all processes within a container
|
||||
|
||||
|
|
|
@ -30,41 +30,6 @@ func TestEventsUntag(t *testing.T) {
|
|||
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) {
|
||||
defer deleteAllContainers()
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
|
@ -380,6 +380,16 @@ func getPausedContainers() (string, error) {
|
|||
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 {
|
||||
unpauseCmd := exec.Command(dockerBinary, "unpause", container)
|
||||
exitCode, err := runCommand(unpauseCmd)
|
||||
|
|
Загрузка…
Ссылка в новой задаче