diff --git a/integration-cli/docker_cli_daemon_experimental_test.go b/integration-cli/docker_cli_daemon_experimental_test.go index 30e993ecfb..46ce156a48 100644 --- a/integration-cli/docker_cli_daemon_experimental_test.go +++ b/integration-cli/docker_cli_daemon_experimental_test.go @@ -1,155 +1,54 @@ -// +build daemon,!windows,experimental +// +build linux, experimental package main import ( - "io/ioutil" - "os" - "os/exec" - "strings" - "time" - + "github.com/docker/docker/pkg/integration/checker" "github.com/go-check/check" ) -// TestDaemonRestartWithKilledRunningContainer requires live restore of running containers -func (s *DockerDaemonSuite) TestDaemonRestartWithKilledRunningContainer(t *check.C) { - // TODO(mlaventure): Not sure what would the exit code be on windows - testRequires(t, DaemonIsLinux) - if err := s.d.StartWithBusybox(); err != nil { - t.Fatal(err) - } +var pluginName = "tiborvass/no-remove" - cid, err := s.d.Cmd("run", "-d", "--name", "test", "busybox", "top") - defer s.d.Stop() - if err != nil { - t.Fatal(cid, err) - } - cid = strings.TrimSpace(cid) - - // Kill the daemon - if err := s.d.Kill(); err != nil { - t.Fatal(err) - } - - // kill the container - runCmd := exec.Command(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", cid) - if out, ec, err := runCommandWithOutput(runCmd); err != nil { - t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid) - } - - // Give time to containerd to process the command if we don't - // the exit event might be received after we do the inspect - time.Sleep(3 * time.Second) - - // restart the daemon +// TestDaemonRestartWithPluginEnabled tests state restore for an enabled plugin +func (s *DockerDaemonSuite) TestDaemonRestartWithPluginEnabled(c *check.C) { if err := s.d.Start(); err != nil { - t.Fatal(err) + c.Fatalf("Could not start daemon: %v", err) } - // Check that we've got the correct exit code - out, err := s.d.Cmd("inspect", "-f", "{{.State.ExitCode}}", cid) - t.Assert(err, check.IsNil) - - out = strings.TrimSpace(out) - if out != "143" { - t.Fatalf("Expected exit code '%s' got '%s' for container '%s'\n", "143", out, cid) + if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pluginName); err != nil { + c.Fatalf("Could not install plugin: %v %s", err, out) } -} - -// os.Kill should kill daemon ungracefully, leaving behind live containers. -// The live containers should be known to the restarted daemon. Stopping -// them now, should remove the mounts. -func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonCrash(c *check.C) { - testRequires(c, DaemonIsLinux) - c.Assert(s.d.StartWithBusybox("--live-restore"), check.IsNil) - - out, err := s.d.Cmd("run", "-d", "busybox", "top") - c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) - id := strings.TrimSpace(out) - - c.Assert(s.d.cmd.Process.Signal(os.Kill), check.IsNil) - mountOut, err := ioutil.ReadFile("/proc/self/mountinfo") - c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut)) - - // container mounts should exist even after daemon has crashed. - comment := check.Commentf("%s should stay mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.folder, mountOut) - c.Assert(strings.Contains(string(mountOut), id), check.Equals, true, comment) - - // restart daemon. - if err := s.d.Restart("--live-restore"); err != nil { - c.Fatal(err) + if err := s.d.Restart(); err != nil { + c.Fatalf("Could not restart daemon: %v", err) } - // container should be running. - out, err = s.d.Cmd("inspect", "--format='{{.State.Running}}'", id) - c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) - out = strings.TrimSpace(out) - if out != "true" { - c.Fatalf("Container %s expected to stay alive after daemon restart", id) - } - - // 'docker stop' should work. - out, err = s.d.Cmd("stop", id) - c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) - - // Now, container mounts should be gone. - mountOut, err = ioutil.ReadFile("/proc/self/mountinfo") - c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut)) - comment = check.Commentf("%s is still mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.folder, mountOut) - c.Assert(strings.Contains(string(mountOut), id), check.Equals, false, comment) -} - -// TestDaemonRestartWithUnpausedRunningContainer requires live restore of running containers. -func (s *DockerDaemonSuite) TestDaemonRestartWithUnpausedRunningContainer(t *check.C) { - // TODO(mlaventure): Not sure what would the exit code be on windows - testRequires(t, DaemonIsLinux) - if err := s.d.StartWithBusybox("--live-restore"); err != nil { - t.Fatal(err) - } - - cid, err := s.d.Cmd("run", "-d", "--name", "test", "busybox", "top") - defer s.d.Stop() + out, err := s.d.Cmd("plugin", "ls") if err != nil { - t.Fatal(cid, err) - } - cid = strings.TrimSpace(cid) - - // pause the container - if _, err := s.d.Cmd("pause", cid); err != nil { - t.Fatal(cid, err) - } - - // Kill the daemon - if err := s.d.Kill(); err != nil { - t.Fatal(err) - } - - // resume the container - runCmd := exec.Command(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "resume", cid) - if out, ec, err := runCommandWithOutput(runCmd); err != nil { - t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid) - } - - // Give time to containerd to process the command if we don't - // the resume event might be received after we do the inspect - time.Sleep(3 * time.Second) - - // restart the daemon - if err := s.d.Start("--live-restore"); err != nil { - t.Fatal(err) - } - - // Check that we've got the correct status - out, err := s.d.Cmd("inspect", "-f", "{{.State.Status}}", cid) - t.Assert(err, check.IsNil) - - out = strings.TrimSpace(out) - if out != "running" { - t.Fatalf("Expected exit code '%s' got '%s' for container '%s'\n", "running", out, cid) - } - if _, err := s.d.Cmd("kill", cid); err != nil { - t.Fatal(err) + c.Fatalf("Could not list plugins: %v %s", err, out) } + c.Assert(out, checker.Contains, pluginName) + c.Assert(out, checker.Contains, "true") +} + +// TestDaemonRestartWithPluginEnabled tests state restore for a disabled plugin +func (s *DockerDaemonSuite) TestDaemonRestartWithPluginDisabled(c *check.C) { + if err := s.d.Start(); err != nil { + c.Fatalf("Could not start daemon: %v", err) + } + + if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pluginName, "--disable"); err != nil { + c.Fatalf("Could not install plugin: %v %s", err, out) + } + + if err := s.d.Restart(); err != nil { + c.Fatalf("Could not restart daemon: %v", err) + } + + out, err := s.d.Cmd("plugin", "ls") + if err != nil { + c.Fatalf("Could not list plugins: %v %s", err, out) + } + c.Assert(out, checker.Contains, pluginName) + c.Assert(out, checker.Contains, "false") } diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index a719764af9..5f47eb96af 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -1,4 +1,4 @@ -// +build !windows +// +build linux package main @@ -2091,6 +2091,158 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithNames(c *check.C) { c.Assert(test3validated, check.Equals, true) } +// TestDaemonRestartWithKilledRunningContainer requires live restore of running containers +func (s *DockerDaemonSuite) TestDaemonRestartWithKilledRunningContainer(t *check.C) { + // TODO(mlaventure): Not sure what would the exit code be on windows + testRequires(t, DaemonIsLinux) + if err := s.d.StartWithBusybox(); err != nil { + t.Fatal(err) + } + + cid, err := s.d.Cmd("run", "-d", "--name", "test", "busybox", "top") + defer s.d.Stop() + if err != nil { + t.Fatal(cid, err) + } + cid = strings.TrimSpace(cid) + + // Kill the daemon + if err := s.d.Kill(); err != nil { + t.Fatal(err) + } + + // kill the container + runCmd := exec.Command(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", cid) + if out, ec, err := runCommandWithOutput(runCmd); err != nil { + t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid) + } + + // Give time to containerd to process the command if we don't + // the exit event might be received after we do the inspect + pidCmd := exec.Command("pidof", "top") + _, ec, _ := runCommandWithOutput(pidCmd) + for ec == 0 { + time.Sleep(3 * time.Second) + _, ec, _ = runCommandWithOutput(pidCmd) + } + + // restart the daemon + if err := s.d.Start(); err != nil { + t.Fatal(err) + } + + // Check that we've got the correct exit code + out, err := s.d.Cmd("inspect", "-f", "{{.State.ExitCode}}", cid) + t.Assert(err, check.IsNil) + + out = strings.TrimSpace(out) + if out != "143" { + t.Fatalf("Expected exit code '%s' got '%s' for container '%s'\n", "143", out, cid) + } + +} + +// os.Kill should kill daemon ungracefully, leaving behind live containers. +// The live containers should be known to the restarted daemon. Stopping +// them now, should remove the mounts. +func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonCrash(c *check.C) { + testRequires(c, DaemonIsLinux) + c.Assert(s.d.StartWithBusybox("--live-restore"), check.IsNil) + + out, err := s.d.Cmd("run", "-d", "busybox", "top") + c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) + id := strings.TrimSpace(out) + + c.Assert(s.d.cmd.Process.Signal(os.Kill), check.IsNil) + mountOut, err := ioutil.ReadFile("/proc/self/mountinfo") + c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut)) + + // container mounts should exist even after daemon has crashed. + comment := check.Commentf("%s should stay mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.folder, mountOut) + c.Assert(strings.Contains(string(mountOut), id), check.Equals, true, comment) + + // restart daemon. + if err := s.d.Restart("--live-restore"); err != nil { + c.Fatal(err) + } + + // container should be running. + out, err = s.d.Cmd("inspect", "--format='{{.State.Running}}'", id) + c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) + out = strings.TrimSpace(out) + if out != "true" { + c.Fatalf("Container %s expected to stay alive after daemon restart", id) + } + + // 'docker stop' should work. + out, err = s.d.Cmd("stop", id) + c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) + + // Now, container mounts should be gone. + mountOut, err = ioutil.ReadFile("/proc/self/mountinfo") + c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut)) + comment = check.Commentf("%s is still mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.folder, mountOut) + c.Assert(strings.Contains(string(mountOut), id), check.Equals, false, comment) +} + +// TestDaemonRestartWithUnpausedRunningContainer requires live restore of running containers. +func (s *DockerDaemonSuite) TestDaemonRestartWithUnpausedRunningContainer(t *check.C) { + // TODO(mlaventure): Not sure what would the exit code be on windows + testRequires(t, DaemonIsLinux) + if err := s.d.StartWithBusybox("--live-restore"); err != nil { + t.Fatal(err) + } + + cid, err := s.d.Cmd("run", "-d", "--name", "test", "busybox", "top") + defer s.d.Stop() + if err != nil { + t.Fatal(cid, err) + } + cid = strings.TrimSpace(cid) + + // pause the container + if _, err := s.d.Cmd("pause", cid); err != nil { + t.Fatal(cid, err) + } + + // Kill the daemon + if err := s.d.Kill(); err != nil { + t.Fatal(err) + } + + // resume the container + runCmd := exec.Command(ctrBinary, "--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock", "containers", "resume", cid) + if out, ec, err := runCommandWithOutput(runCmd); err != nil { + t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid) + } + + // Give time to containerd to process the command if we don't + // the resume event might be received after we do the inspect + pidCmd := exec.Command("pidof", "top") + _, ec, _ := runCommandWithOutput(pidCmd) + for ec == 0 { + time.Sleep(3 * time.Second) + _, ec, _ = runCommandWithOutput(pidCmd) + } + + // restart the daemon + if err := s.d.Start("--live-restore"); err != nil { + t.Fatal(err) + } + + // Check that we've got the correct status + out, err := s.d.Cmd("inspect", "-f", "{{.State.Status}}", cid) + t.Assert(err, check.IsNil) + + out = strings.TrimSpace(out) + if out != "running" { + t.Fatalf("Expected exit code '%s' got '%s' for container '%s'\n", "running", out, cid) + } + if _, err := s.d.Cmd("kill", cid); err != nil { + t.Fatal(err) + } +} + // TestRunLinksChanged checks that creating a new container with the same name does not update links // this ensures that the old, pre gh#16032 functionality continues on func (s *DockerDaemonSuite) TestRunLinksChanged(c *check.C) {