diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2018-04-24 16:41:42 +0200 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-05-04 17:15:55 +0000 |
commit | 522a7197a88ab4e3730387df33f22e445f0f8f3c (patch) | |
tree | b9ff641842314b447296d18c072eb478d9742632 /libpod/container_internal.go | |
parent | 73078fabcfd2420c47e41843da71dd993f9a0a3e (diff) | |
download | podman-522a7197a88ab4e3730387df33f22e445f0f8f3c.tar.gz podman-522a7197a88ab4e3730387df33f22e445f0f8f3c.tar.bz2 podman-522a7197a88ab4e3730387df33f22e445f0f8f3c.zip |
podman, userNS: configure an intermediate mount namespace
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Closes: #690
Approved by: mheon
Diffstat (limited to 'libpod/container_internal.go')
-rw-r--r-- | libpod/container_internal.go | 101 |
1 files changed, 88 insertions, 13 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 18b56e23c..5417c8a4f 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -16,6 +16,7 @@ import ( "github.com/containers/storage" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/chrootarchive" + "github.com/containers/storage/pkg/idtools" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/stringid" spec "github.com/opencontainers/runtime-spec/specs-go" @@ -196,8 +197,33 @@ func (c *Container) setupStorage(ctx context.Context) error { return errors.Wrapf(err, "error creating container storage") } + if len(c.config.IDMappings.UIDMap) != 0 || len(c.config.IDMappings.GIDMap) != 0 { + info, err := os.Stat(c.runtime.config.TmpDir) + if err != nil { + return errors.Wrapf(err, "cannot stat `%s`", c.runtime.config.TmpDir) + } + if err := os.Chmod(c.runtime.config.TmpDir, info.Mode()|0111); err != nil { + return errors.Wrapf(err, "cannot chmod `%s`", c.runtime.config.TmpDir) + } + root := filepath.Join(c.runtime.config.TmpDir, "containers-root", c.ID()) + if err := os.MkdirAll(root, 0755); err != nil { + return errors.Wrapf(err, "error creating userNS tmpdir for container %s", c.ID()) + } + if err := os.Chown(root, c.RootUID(), c.RootGID()); err != nil { + return err + } + c.state.UserNSRoot, err = filepath.EvalSymlinks(root) + if err != nil { + return errors.Wrapf(err, "failed to eval symlinks for %s", root) + } + } + c.config.StaticDir = containerInfo.Dir c.state.RunDir = containerInfo.RunDir + c.state.DestinationRunDir = c.state.RunDir + if c.state.UserNSRoot != "" { + c.state.DestinationRunDir = filepath.Join(c.state.UserNSRoot, "rundir") + } // Set the default Entrypoint and Command c.config.Entrypoint = containerInfo.Config.Config.Entrypoint @@ -230,6 +256,12 @@ func (c *Container) teardownStorage() error { return errors.Wrapf(err, "failed to cleanup container %s storage", c.ID()) } + if c.state.UserNSRoot != "" { + if err := os.RemoveAll(c.state.UserNSRoot); err != nil { + return errors.Wrapf(err, "error removing userns root %q", c.state.UserNSRoot) + } + } + if err := c.runtime.storageService.DeleteContainer(c.ID()); err != nil { // If the container has already been removed, warn but do not // error - we wanted it gone, it is already gone. @@ -261,9 +293,35 @@ func (c *Container) refresh() error { if err != nil { return errors.Wrapf(err, "error retrieving temporary directory for container %s", c.ID()) } + + if len(c.config.IDMappings.UIDMap) != 0 || len(c.config.IDMappings.GIDMap) != 0 { + info, err := os.Stat(c.runtime.config.TmpDir) + if err != nil { + return errors.Wrapf(err, "cannot stat `%s`", c.runtime.config.TmpDir) + } + if err := os.Chmod(c.runtime.config.TmpDir, info.Mode()|0111); err != nil { + return errors.Wrapf(err, "cannot chmod `%s`", c.runtime.config.TmpDir) + } + root := filepath.Join(c.runtime.config.TmpDir, "containers-root", c.ID()) + if err := os.MkdirAll(root, 0755); err != nil { + return errors.Wrapf(err, "error creating userNS tmpdir for container %s", c.ID()) + } + if err := os.Chown(root, c.RootUID(), c.RootGID()); err != nil { + return err + } + c.state.UserNSRoot, err = filepath.EvalSymlinks(root) + if err != nil { + return errors.Wrapf(err, "failed to eval symlinks for %s", root) + } + } + c.state.RunDir = dir + c.state.DestinationRunDir = c.state.RunDir + if c.state.UserNSRoot != "" { + c.state.DestinationRunDir = filepath.Join(c.state.UserNSRoot, "rundir") + } - if err := c.runtime.state.SaveContainer(c); err != nil { + if err := c.save(); err != nil { return errors.Wrapf(err, "error refreshing state for container %s", c.ID()) } @@ -600,6 +658,10 @@ func (c *Container) mountStorage() (err error) { return errors.Wrapf(err, "unable to determine if %q is mounted", c.config.ShmDir) } + if err := os.Chown(c.config.ShmDir, c.RootUID(), c.RootGID()); err != nil { + return err + } + if !mounted { shmOptions := fmt.Sprintf("mode=1777,size=%d", c.config.ShmSize) if err := unix.Mount("shm", c.config.ShmDir, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, @@ -607,7 +669,7 @@ func (c *Container) mountStorage() (err error) { return errors.Wrapf(err, "failed to mount shm tmpfs %q", c.config.ShmDir) } if err := os.Chown(c.config.ShmDir, c.RootUID(), c.RootGID()); err != nil { - return err + return errors.Wrapf(err, "failed to chown %s", c.config.ShmDir) } } @@ -617,6 +679,11 @@ func (c *Container) mountStorage() (err error) { } c.state.Mounted = true c.state.Mountpoint = mountPoint + if c.state.UserNSRoot == "" { + c.state.RealMountpoint = c.state.Mountpoint + } else { + c.state.RealMountpoint = filepath.Join(c.state.UserNSRoot, "mountpoint") + } logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint) @@ -716,6 +783,10 @@ func (c *Container) cleanup() error { // Make standard bind mounts to include in the container func (c *Container) makeBindMounts() error { + if err := os.Chown(c.state.RunDir, c.RootUID(), c.RootGID()); err != nil { + return errors.Wrapf(err, "error chown %s", c.state.RunDir) + } + if c.state.BindMounts == nil { c.state.BindMounts = make(map[string]string) } @@ -724,11 +795,8 @@ func (c *Container) makeBindMounts() error { c.state.BindMounts["/dev/shm"] = c.config.ShmDir // Make /etc/resolv.conf - if path, ok := c.state.BindMounts["/etc/resolv.conf"]; ok { + if _, ok := c.state.BindMounts["/etc/resolv.conf"]; ok { // If it already exists, delete so we can recreate - if err := os.Remove(path); err != nil { - return errors.Wrapf(err, "error removing resolv.conf for container %s", c.ID()) - } delete(c.state.BindMounts, "/etc/resolv.conf") } newResolv, err := c.generateResolvConf() @@ -738,11 +806,8 @@ func (c *Container) makeBindMounts() error { c.state.BindMounts["/etc/resolv.conf"] = newResolv // Make /etc/hosts - if path, ok := c.state.BindMounts["/etc/hosts"]; ok { + if _, ok := c.state.BindMounts["/etc/hosts"]; ok { // If it already exists, delete so we can recreate - if err := os.Remove(path); err != nil { - return errors.Wrapf(err, "error removing hosts file for container %s", c.ID()) - } delete(c.state.BindMounts, "/etc/hosts") } newHosts, err := c.generateHosts() @@ -773,7 +838,7 @@ func (c *Container) makeBindMounts() error { } // Add Secret Mounts - secretMounts := secrets.SecretMountsWithUIDGID(c.config.MountLabel, c.state.RunDir, c.runtime.config.DefaultMountsFile, c.RootUID(), c.RootGID()) + secretMounts := secrets.SecretMountsWithUIDGID(c.config.MountLabel, c.state.RunDir, c.runtime.config.DefaultMountsFile, c.state.DestinationRunDir, c.RootUID(), c.RootGID()) for _, mount := range secretMounts { if _, ok := c.state.BindMounts[mount.Destination]; !ok { c.state.BindMounts[mount.Destination] = mount.Source @@ -786,6 +851,11 @@ func (c *Container) makeBindMounts() error { // writeStringToRundir copies the provided file to the runtimedir func (c *Container) writeStringToRundir(destFile, output string) (string, error) { destFileName := filepath.Join(c.state.RunDir, destFile) + + if err := os.Remove(destFileName); err != nil && !os.IsNotExist(err) { + return "", errors.Wrapf(err, "error removing %s for container %s", destFile, c.ID()) + } + f, err := os.Create(destFileName) if err != nil { return "", errors.Wrapf(err, "unable to create %s", destFileName) @@ -802,7 +872,8 @@ func (c *Container) writeStringToRundir(destFile, output string) (string, error) if err := label.Relabel(destFileName, c.config.MountLabel, false); err != nil { return "", err } - return destFileName, nil + + return filepath.Join(c.state.DestinationRunDir, destFile), nil } type resolvConf struct { @@ -1035,7 +1106,11 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } - g.SetRootPath(c.state.Mountpoint) + if err := idtools.MkdirAllAs(c.state.RealMountpoint, 0700, c.RootUID(), c.RootGID()); err != nil { + return nil, err + } + + g.SetRootPath(c.state.RealMountpoint) g.AddAnnotation(crioAnnotations.Created, c.config.CreatedTime.Format(time.RFC3339Nano)) g.AddAnnotation("org.opencontainers.image.stopSignal", fmt.Sprintf("%d", c.config.StopSignal)) |