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
|
// being checkpointed. If requestedIP is set it will be used instead
|
||||||
// of config.StaticIP.
|
// of config.StaticIP.
|
||||||
requestedIP net.IP
|
requestedIP net.IP
|
||||||
|
|
||||||
|
// This is true if a container is restored from a checkpoint.
|
||||||
|
restoreFromCheckpoint bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerState contains the current state of the container
|
// ContainerState contains the current state of the container
|
||||||
|
@ -352,6 +352,16 @@ func (c *Container) setupStorage(ctx context.Context) error {
|
|||||||
},
|
},
|
||||||
LabelOpts: c.config.LabelOpts,
|
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 {
|
if c.config.Privileged {
|
||||||
privOpt := func(opt string) bool {
|
privOpt := func(opt string) bool {
|
||||||
for _, privopt := range []string{"nodev", "nosuid", "noexec"} {
|
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 {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error initializing container variables")
|
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) {
|
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
|
ctr.config.ShmSize = DefaultShmSize
|
||||||
} else {
|
} else {
|
||||||
// This is a restore from an imported checkpoint
|
// This is a restore from an imported checkpoint
|
||||||
|
ctr.restoreFromCheckpoint = true
|
||||||
if err := JSONDeepCopy(config, ctr.config); err != nil {
|
if err := JSONDeepCopy(config, ctr.config); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error copying container config for restore")
|
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 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
|
// Allocate a lock for the container
|
||||||
lock, err := r.lockManager.AllocateLock()
|
lock, err := r.lockManager.AllocateLock()
|
||||||
if err != nil {
|
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)
|
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
|
// Remove information about bind mount
|
||||||
// for new container from imported checkpoint
|
// for new container from imported checkpoint
|
||||||
g := generate.Generator{Config: ctr.config.Spec}
|
g := generate.Generator{Config: ctr.config.Spec}
|
||||||
|
@ -392,4 +392,43 @@ var _ = Describe("Podman checkpoint", func() {
|
|||||||
// Remove exported checkpoint
|
// Remove exported checkpoint
|
||||||
os.Remove("/tmp/checkpoint.tar.gz")
|
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