diff options
-rw-r--r-- | libpod/container.go | 3 | ||||
-rw-r--r-- | libpod/container_internal.go | 10 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 9 | ||||
-rw-r--r-- | test/e2e/checkpoint_test.go | 39 |
4 files changed, 57 insertions, 4 deletions
diff --git a/libpod/container.go b/libpod/container.go index bfbc47d76..a9b512de9 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -138,6 +138,9 @@ type Container struct { // being checkpointed. If requestedIP is set it will be used instead // of config.StaticIP. requestedIP net.IP + + // This is true if a container is restored from a checkpoint. + restoreFromCheckpoint bool } // ContainerState contains the current state of the container diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 1cac7b003..c409da96a 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -352,6 +352,16 @@ func (c *Container) setupStorage(ctx context.Context) error { }, LabelOpts: c.config.LabelOpts, } + if c.restoreFromCheckpoint { + // If restoring from a checkpoint, the root file-system + // needs to be mounted with the same SELinux labels as + // it was mounted previously. + if options.Flags == nil { + options.Flags = make(map[string]interface{}) + } + options.Flags["ProcessLabel"] = c.config.ProcessLabel + options.Flags["MountLabel"] = c.config.MountLabel + } if c.config.Privileged { privOpt := func(opt string) bool { for _, privopt := range []string{"nodev", "nosuid", "noexec"} { diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index d022478b1..633d26fe1 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -52,7 +52,7 @@ func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config if err != nil { return nil, errors.Wrapf(err, "error initializing container variables") } - return r.setupContainer(ctx, ctr, true) + return r.setupContainer(ctx, ctr) } func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConfig) (c *Container, err error) { @@ -68,6 +68,7 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf ctr.config.ShmSize = DefaultShmSize } else { // This is a restore from an imported checkpoint + ctr.restoreFromCheckpoint = true if err := JSONDeepCopy(config, ctr.config); err != nil { return nil, errors.Wrapf(err, "error copying container config for restore") } @@ -119,10 +120,10 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options .. return nil, errors.Wrapf(err, "error running container create option") } } - return r.setupContainer(ctx, ctr, false) + return r.setupContainer(ctx, ctr) } -func (r *Runtime) setupContainer(ctx context.Context, ctr *Container, restore bool) (c *Container, err error) { +func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Container, err error) { // Allocate a lock for the container lock, err := r.lockManager.AllocateLock() if err != nil { @@ -211,7 +212,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container, restore bo return nil, errors.Wrapf(config2.ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.CgroupManager) } - if restore { + if ctr.restoreFromCheckpoint { // Remove information about bind mount // for new container from imported checkpoint g := generate.Generator{Config: ctr.config.Spec} diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index d452a062b..c60a99386 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -392,4 +392,43 @@ var _ = Describe("Podman checkpoint", func() { // Remove exported checkpoint os.Remove("/tmp/checkpoint.tar.gz") }) + + It("podman checkpoint and run exec in restored container", func() { + // Start the container + session := podmanTest.Podman([]string{"run", "-it", "--rm", "-d", ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + cid := session.OutputToString() + + // Checkpoint the container + result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", "/tmp/checkpoint.tar.gz"}) + 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", "/tmp/checkpoint.tar.gz"}) + 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("/tmp/checkpoint.tar.gz") + }) }) |