summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile12
-rw-r--r--test/e2e/checkpoint_test.go129
-rw-r--r--test/e2e/libpod_suite_test.go37
3 files changed, 178 insertions, 0 deletions
diff --git a/Dockerfile b/Dockerfile
index 749c5edb9..2c43cb046 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -18,6 +18,8 @@ RUN apt-get update && apt-get install -y \
libaio-dev \
libcap-dev \
libfuse-dev \
+ libnet-dev \
+ libnl-3-dev \
libostree-dev \
libprotobuf-dev \
libprotobuf-c0-dev \
@@ -110,6 +112,16 @@ RUN set -x \
&& go get -u github.com/mailru/easyjson/... \
&& install -D -m 755 "$GOPATH"/bin/easyjson /usr/bin/
+# Install criu
+ENV CRIU_COMMIT 584cbe4643c3fc7dc901ff08bf923ca0fe7326f9
+RUN set -x \
+ && cd /tmp \
+ && git clone https://github.com/checkpoint-restore/criu.git \
+ && cd criu \
+ && make \
+ && install -D -m 755 criu/criu /usr/sbin/ \
+ && rm -rf /tmp/criu
+
# Install cni config
#RUN make install.cni
RUN mkdir -p /etc/cni/net.d/
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
new file mode 100644
index 000000000..6c5d891a0
--- /dev/null
+++ b/test/e2e/checkpoint_test.go
@@ -0,0 +1,129 @@
+package integration
+
+import (
+ "fmt"
+ "os"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("Podman checkpoint", func() {
+ var (
+ tempdir string
+ err error
+ podmanTest PodmanTest
+ )
+
+ BeforeEach(func() {
+ tempdir, err = CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest = PodmanCreate(tempdir)
+ podmanTest.RestoreAllArtifacts()
+ // At least CRIU 3.11 is needed
+ skip, err := podmanTest.isCriuAtLeast(31100)
+ if err != nil || skip {
+ Skip("CRIU missing or too old.")
+ }
+ })
+
+ AfterEach(func() {
+ podmanTest.Cleanup()
+ f := CurrentGinkgoTestDescription()
+ timedResult := fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds())
+ GinkgoWriter.Write([]byte(timedResult))
+ })
+
+ It("podman checkpoint bogus container", func() {
+ session := podmanTest.Podman([]string{"container", "checkpoint", "foobar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+ })
+
+ It("podman restore bogus container", func() {
+ session := podmanTest.Podman([]string{"container", "restore", "foobar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+ })
+
+ 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"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ cid := session.OutputToString()
+
+ result := podmanTest.Podman([]string{"container", "checkpoint", cid})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
+
+ result = podmanTest.Podman([]string{"container", "restore", cid})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
+ })
+
+ 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"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
+
+ result = podmanTest.Podman([]string{"container", "restore", "test_name"})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
+ })
+
+ It("podman pause a checkpointed container by id", func() {
+ session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ cid := session.OutputToString()
+
+ result := podmanTest.Podman([]string{"container", "checkpoint", cid})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
+
+ result = podmanTest.Podman([]string{"pause", cid})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result.ExitCode()).To(Equal(125))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
+
+ result = podmanTest.Podman([]string{"container", "restore", cid})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
+
+ result = podmanTest.Podman([]string{"rm", cid})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(125))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
+
+ result = podmanTest.Podman([]string{"rm", "-f", cid})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+
+ })
+})
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
index d521632d7..a032b0e88 100644
--- a/test/e2e/libpod_suite_test.go
+++ b/test/e2e/libpod_suite_test.go
@@ -2,6 +2,7 @@ package integration
import (
"bufio"
+ "bytes"
"context"
"encoding/json"
"fmt"
@@ -64,6 +65,7 @@ type PodmanTest struct {
TempDir string
CgroupManager string
Host HostOS
+ CriuBinary string
}
// HostOS is a simple struct for the test os
@@ -164,6 +166,7 @@ func PodmanCreate(tempDir string) PodmanTest {
runCBinary = "/usr/bin/runc"
}
+ criuBinary := "/usr/sbin/criu"
CNIConfigDir := "/etc/cni/net.d"
p := PodmanTest{
@@ -179,6 +182,7 @@ func PodmanCreate(tempDir string) PodmanTest {
TempDir: tempDir,
CgroupManager: cgroupManager,
Host: host,
+ CriuBinary: criuBinary,
}
// Setup registries.conf ENV variable
@@ -678,6 +682,39 @@ func (p *PodmanTest) setRegistriesConfigEnv(b []byte) {
ioutil.WriteFile(outfile, b, 0644)
}
+func (p *PodmanTest) isCriuAtLeast(version int) (bool, error) {
+ cmd := exec.Command(p.CriuBinary, "-V")
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ err := cmd.Run()
+ if err != nil {
+ return false, err
+ }
+
+ var x int
+ var y int
+ var z int
+
+ fmt.Sscanf(out.String(), "Version: %d.%d.%d", &x, &y, &z)
+
+ if strings.Contains(out.String(), "GitID") {
+ // If CRIU is built from git it contains a git ID.
+ // If that is the case, increase minor by one as this
+ // could mean we are running a development version.
+ y = y + 1
+ }
+
+ parsed_version := x*10000 + y*100 + z
+
+ fmt.Println(parsed_version)
+
+ if parsed_version >= version {
+ return false, nil
+ } else {
+ return true, nil
+ }
+}
+
func resetRegistriesConfigEnv() {
os.Setenv("REGISTRIES_CONFIG_PATH", "")
}