diff options
Diffstat (limited to 'test/e2e/checkpoint_test.go')
-rw-r--r-- | test/e2e/checkpoint_test.go | 260 |
1 files changed, 246 insertions, 14 deletions
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index c2f5a592c..b77c48c8e 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -3,9 +3,12 @@ package integration import ( + "math/rand" "net" "os" "os/exec" + "strconv" + "time" "github.com/containers/libpod/pkg/criu" . "github.com/containers/libpod/test/utils" @@ -13,6 +16,16 @@ import ( . "github.com/onsi/gomega" ) +func getRunString(input []string) []string { + // To avoid IP collisions of initialize random seed for random IP addresses + rand.Seed(time.Now().UnixNano()) + ip3 := strconv.Itoa(rand.Intn(230) + GinkgoParallelNode()) + ip4 := strconv.Itoa(rand.Intn(230) + GinkgoParallelNode()) + // CRIU does not work with seccomp correctly on RHEL7 : seccomp=unconfined + runString := []string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", "--ip", "10.88." + ip3 + "." + ip4} + return append(runString, input...) +} + var _ = Describe("Podman checkpoint", func() { var ( tempdir string @@ -28,7 +41,7 @@ var _ = Describe("Podman checkpoint", func() { } podmanTest = PodmanTestCreate(tempdir) podmanTest.Setup() - podmanTest.RestoreAllArtifacts() + podmanTest.SeedImages() // Check if the runtime implements checkpointing. Currently only // runc's checkpoint/restore implementation is supported. cmd := exec.Command(podmanTest.OCIRuntime, "checkpoint", "-h") @@ -49,7 +62,6 @@ var _ = Describe("Podman checkpoint", func() { if hostInfo.Distribution == "fedora" && hostInfo.Version < "29" { Skip("Checkpoint/Restore with SELinux only works on Fedora >= 29") } - }) AfterEach(func() { @@ -72,8 +84,8 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint a running container by id", func() { - // CRIU does not work with seccomp correctly on RHEL7 - session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", ALPINE, "top"}) + localRunString := getRunString([]string{ALPINE, "top"}) + session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() @@ -94,7 +106,8 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint a running container by name", func() { - session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--name", "test_name", "-d", ALPINE, "top"}) + localRunString := getRunString([]string{"--name", "test_name", ALPINE, "top"}) + session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -114,7 +127,8 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman pause a checkpointed container by id", func() { - session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", ALPINE, "top"}) + localRunString := getRunString([]string{ALPINE, "top"}) + session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() @@ -151,11 +165,13 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint latest running container", func() { - session1 := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--name", "first", "-d", ALPINE, "top"}) + localRunString := getRunString([]string{"--name", "first", ALPINE, "top"}) + session1 := podmanTest.Podman(localRunString) session1.WaitWithDefaultTimeout() Expect(session1.ExitCode()).To(Equal(0)) - session2 := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--name", "second", "-d", ALPINE, "top"}) + localRunString = getRunString([]string{"--name", "second", ALPINE, "top"}) + session2 := podmanTest.Podman(localRunString) session2.WaitWithDefaultTimeout() Expect(session2.ExitCode()).To(Equal(0)) @@ -186,11 +202,13 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint all running container", func() { - session1 := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--name", "first", "-d", ALPINE, "top"}) + localRunString := getRunString([]string{"--name", "first", ALPINE, "top"}) + session1 := podmanTest.Podman(localRunString) session1.WaitWithDefaultTimeout() Expect(session1.ExitCode()).To(Equal(0)) - session2 := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--name", "second", "-d", ALPINE, "top"}) + localRunString = getRunString([]string{"--name", "second", ALPINE, "top"}) + session2 := podmanTest.Podman(localRunString) session2.WaitWithDefaultTimeout() Expect(session2.ExitCode()).To(Equal(0)) @@ -221,8 +239,8 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint container with established tcp connections", func() { - podmanTest.RestoreArtifact(redis) - session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", redis}) + localRunString := getRunString([]string{redis}) + session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -276,7 +294,8 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint with --leave-running", func() { - session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", ALPINE, "top"}) + localRunString := getRunString([]string{ALPINE, "top"}) + session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() @@ -313,7 +332,8 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint and restore container with same IP", func() { - session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--name", "test_name", "-d", ALPINE, "top"}) + localRunString := getRunString([]string{"--name", "test_name", ALPINE, "top"}) + session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -348,4 +368,216 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) + // This test does the same steps which are necessary for migrating + // a container from one host to another + It("podman checkpoint container with export (migration)", func() { + // CRIU does not work with seccomp correctly on RHEL7 + session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + cid := session.OutputToString() + fileName := "/tmp/checkpoint-" + cid + ".tar.gz" + + result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) + + // Remove all containers to simulate migration + result = podmanTest.Podman([]string{"rm", "-fa"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + + result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + // Restore container a second time with different name + result = podmanTest.Podman([]string{"container", "restore", "-i", fileName, "-n", "restore_again"}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + result = podmanTest.Podman([]string{"rm", "-fa"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + + // Remove exported checkpoint + os.Remove(fileName) + }) + + It("podman checkpoint and restore container with root file-system changes", func() { + // Start the container + localRunString := getRunString([]string{"--rm", ALPINE, "top"}) + session := podmanTest.Podman(localRunString) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + cid := session.OutputToString() + fileName := "/tmp/checkpoint-" + cid + ".tar.gz" + + // Change the container's root file-system + result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + + // Checkpoint the container + result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + Expect(podmanTest.NumberOfContainers()).To(Equal(0)) + + // Restore the container + result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + // Verify the changes to the container's root file-system + result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(result.OutputToString()).To(ContainSubstring("test" + cid + "test")) + + // Remove exported checkpoint + os.Remove(fileName) + }) + It("podman checkpoint and restore container with root file-system changes using --ignore-rootfs during restore", func() { + // Start the container + localRunString := getRunString([]string{"--rm", ALPINE, "top"}) + session := podmanTest.Podman(localRunString) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + cid := session.OutputToString() + fileName := "/tmp/checkpoint-" + cid + ".tar.gz" + + // Change the container's root file-system + result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + + // Checkpoint the container + result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + Expect(podmanTest.NumberOfContainers()).To(Equal(0)) + + // Restore the container + result = podmanTest.Podman([]string{"container", "restore", "--ignore-rootfs", "-i", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + // Verify the changes to the container's root file-system + result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(1)) + Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) + + // Remove exported checkpoint + os.Remove(fileName) + }) + It("podman checkpoint and restore container with root file-system changes using --ignore-rootfs during checkpoint", func() { + // Start the container + localRunString := getRunString([]string{"--rm", ALPINE, "top"}) + session := podmanTest.Podman(localRunString) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + cid := session.OutputToString() + fileName := "/tmp/checkpoint-" + cid + ".tar.gz" + + // Change the container's root file-system + result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + + // Checkpoint the container + result = podmanTest.Podman([]string{"container", "checkpoint", "--ignore-rootfs", "-l", "-e", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + Expect(podmanTest.NumberOfContainers()).To(Equal(0)) + + // Restore the container + result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + // Verify the changes to the container's root file-system + result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(1)) + Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) + + // Remove exported checkpoint + os.Remove(fileName) + }) + + It("podman checkpoint and run exec in restored container", func() { + // Start the container + localRunString := getRunString([]string{"--rm", ALPINE, "top"}) + session := podmanTest.Podman(localRunString) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + cid := session.OutputToString() + fileName := "/tmp/checkpoint-" + cid + ".tar.gz" + + // Checkpoint the container + result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + Expect(podmanTest.NumberOfContainers()).To(Equal(0)) + + // Restore the container + result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) + result.WaitWithDefaultTimeout() + + Expect(result.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + // Exec in the container + result = podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /test.output"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + + result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(result.OutputToString()).To(ContainSubstring(cid)) + + // Remove exported checkpoint + os.Remove(fileName) + }) }) |