From 1bb02117db80e75f406f6c63d8d50680c1569019 Mon Sep 17 00:00:00 2001 From: cc272309126 Date: Fri, 28 Nov 2014 00:08:39 +0800 Subject: [PATCH] Fix the issue when docker exec a paused container, it will always hang. Add the test case of this issue. Docker-DCO-1.1-Signed-off-by: Chen Chao (github: cc272309126) --- daemon/exec.go | 4 ++- integration-cli/docker_cli_exec_test.go | 33 ++++++++++++++++++++ integration-cli/docker_utils.go | 40 +++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/daemon/exec.go b/daemon/exec.go index 7d6755118e..ecdbc58d85 100644 --- a/daemon/exec.go +++ b/daemon/exec.go @@ -98,7 +98,9 @@ func (d *Daemon) getActiveContainer(name string) (*Container, error) { if !container.IsRunning() { return nil, fmt.Errorf("Container %s is not running", name) } - + if container.IsPaused() { + return nil, fmt.Errorf("Container %s is paused, unpause the container before exec", name) + } return container, nil } diff --git a/integration-cli/docker_cli_exec_test.go b/integration-cli/docker_cli_exec_test.go index ebb5484f2e..82ad9afe7b 100644 --- a/integration-cli/docker_cli_exec_test.go +++ b/integration-cli/docker_cli_exec_test.go @@ -230,3 +230,36 @@ func TestExecExitStatus(t *testing.T) { logDone("exec - exec non-zero ExitStatus") } + +func TestExecPausedContainer(t *testing.T) { + + defer deleteAllContainers() + defer unpauseAllContainers() + + runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "top") + out, _, err := runCommandWithOutput(runCmd) + if err != nil { + t.Fatal(out, err) + } + + ContainerID := stripTrailingCharacters(out) + + pausedCmd := exec.Command(dockerBinary, "pause", "testing") + out, _, _, err = runCommandWithStdoutStderr(pausedCmd) + if err != nil { + t.Fatal(out, err) + } + + execCmd := exec.Command(dockerBinary, "exec", "-i", "-t", ContainerID, "echo", "hello") + out, _, err = runCommandWithOutput(execCmd) + if err == nil { + t.Fatal("container should fail to exec new command if it is paused") + } + + expected := ContainerID + " is paused, unpause the container before exec" + if !strings.Contains(out, expected) { + t.Fatal("container should not exec new command if it is paused") + } + + logDone("exec - exec should not exec a pause container") +} diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 2c66ce2d0c..031738df84 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -328,6 +328,46 @@ func deleteAllContainers() error { return nil } +func getPausedContainers() (string, error) { + getPausedContainersCmd := exec.Command(dockerBinary, "ps", "-f", "status=paused", "-q", "-a") + out, exitCode, err := runCommandWithOutput(getPausedContainersCmd) + if exitCode != 0 && err == nil { + err = fmt.Errorf("failed to get a list of paused containers: %v\n", out) + } + + return out, err +} + +func unpauseContainer(container string) error { + unpauseCmd := exec.Command(dockerBinary, "unpause", container) + exitCode, err := runCommand(unpauseCmd) + if exitCode != 0 && err == nil { + err = fmt.Errorf("failed to unpause container") + } + + return nil +} + +func unpauseAllContainers() error { + containers, err := getPausedContainers() + if err != nil { + fmt.Println(containers) + return err + } + + containers = strings.Replace(containers, "\n", " ", -1) + containers = strings.Trim(containers, " ") + containerList := strings.Split(containers, " ") + + for _, value := range containerList { + if err = unpauseContainer(value); err != nil { + return err + } + } + + return nil +} + func deleteImages(images ...string) error { args := make([]string, 1, 2) args[0] = "rmi"