mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
Merge pull request #3425 from adrianreber/restore-mount-label
Set correct SELinux label on restored containers
This commit is contained in:
@ -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
|
||||
|
@ -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"} {
|
||||
|
@ -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}
|
||||
|
@ -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")
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user