From b51d7379987581da82902027fe91cdf298047bc0 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Mon, 23 Apr 2018 20:42:53 -0400 Subject: Begin wiring in USERNS Support into podman Signed-off-by: Daniel J Walsh Closes: #690 Approved by: mheon --- libpod/container.go | 28 +++++++++++++++++++++++++++- libpod/container_internal.go | 16 +++++++++++----- libpod/options.go | 12 ++++++++++++ libpod/storage.go | 16 +++++++++------- 4 files changed, 59 insertions(+), 13 deletions(-) (limited to 'libpod') diff --git a/libpod/container.go b/libpod/container.go index e7fe77498..fb1f83c29 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -173,7 +173,8 @@ type ContainerConfig struct { // TODO consider breaking these subsections up into smaller structs - // Storage Config + // UID/GID mappings used by the storage + IDMappings storage.IDMappingOptions `json:"idMappingsOptions,omitempty"` // Information on the image used for the root filesystem/ RootfsImageID string `json:"rootfsImageID,omitempty"` @@ -863,3 +864,28 @@ func (c *Container) RWSize() (int64, error) { } return c.rwSize() } + +// IDMappings returns the UID/GID mapping used for the container +func (c *Container) IDMappings() (storage.IDMappingOptions, error) { + return c.config.IDMappings, nil +} + +// RootUID returns the root user mapping from container +func (c *Container) RootUID() int { + for _, uidmap := range c.config.IDMappings.UIDMap { + if uidmap.ContainerID == 0 { + return uidmap.HostID + } + } + return 0 +} + +// RootGID returns the root user mapping from container +func (c *Container) RootGID() int { + for _, gidmap := range c.config.IDMappings.GIDMap { + if gidmap.ContainerID == 0 { + return gidmap.HostID + } + } + return 0 +} diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 614c6aca0..73095316e 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -190,7 +190,8 @@ func (c *Container) setupStorage(ctx context.Context) error { return errors.Wrapf(ErrInvalidArg, "must provide image ID and image name to use an image") } - containerInfo, err := c.runtime.storageService.CreateContainerStorage(ctx, c.runtime.imageContext, c.config.RootfsImageName, c.config.RootfsImageID, c.config.Name, c.config.ID, c.config.MountLabel) + options := storage.ContainerOptions{IDMappingOptions: c.config.IDMappings} + containerInfo, err := c.runtime.storageService.CreateContainerStorage(ctx, c.runtime.imageContext, c.config.RootfsImageName, c.config.RootfsImageID, c.config.Name, c.config.ID, c.config.MountLabel, &options) if err != nil { return errors.Wrapf(err, "error creating container storage") } @@ -591,6 +592,9 @@ func (c *Container) mountStorage() (err error) { label.FormatMountLabel(shmOptions, c.config.MountLabel)); err != nil { 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 + } } mountPoint, err := c.runtime.storageService.MountContainerImage(c.ID()) @@ -755,7 +759,7 @@ func (c *Container) makeBindMounts() error { } // Add Secret Mounts - secretMounts := secrets.SecretMounts(c.config.MountLabel, c.state.RunDir, c.runtime.config.DefaultMountsFile) + secretMounts := secrets.SecretMountsWithUIDGID(c.config.MountLabel, c.state.RunDir, c.runtime.config.DefaultMountsFile, c.RootUID(), c.RootGID()) for _, mount := range secretMounts { if _, ok := c.state.BindMounts[mount.Destination]; !ok { c.state.BindMounts[mount.Destination] = mount.Source @@ -772,10 +776,12 @@ func (c *Container) writeStringToRundir(destFile, output string) (string, error) if err != nil { return "", errors.Wrapf(err, "unable to create %s", destFileName) } - defer f.Close() - _, err = f.WriteString(output) - if err != nil { + if err := f.Chown(c.RootUID(), c.RootGID()); err != nil { + return "", err + } + + if _, err := f.WriteString(output); err != nil { return "", errors.Wrapf(err, "unable to write %s", destFileName) } // Relabel runDirResolv for the container diff --git a/libpod/options.go b/libpod/options.go index 101ff9833..eaca70afc 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -459,6 +459,18 @@ func WithStopTimeout(timeout uint) CtrCreateOption { } } +// WithIDMappings sets the idmappsings for the container +func WithIDMappings(idmappings storage.IDMappingOptions) CtrCreateOption { + return func(ctr *Container) error { + if ctr.valid { + return ErrCtrFinalized + } + + ctr.config.IDMappings = idmappings + return nil + } +} + // WithIPCNSFrom indicates the the container should join the IPC namespace of // the given container. // If the container has joined a pod, it can only join the namespaces of diff --git a/libpod/storage.go b/libpod/storage.go index 910db1970..c0391326c 100644 --- a/libpod/storage.go +++ b/libpod/storage.go @@ -59,7 +59,7 @@ func (metadata *RuntimeContainerMetadata) SetMountLabel(mountLabel string) { // CreateContainerStorage creates the storage end of things. We already have the container spec created // TO-DO We should be passing in an Image object in the future. -func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID, mountLabel string) (ContainerInfo, error) { +func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID, mountLabel string, options *storage.ContainerOptions) (ContainerInfo, error) { var ref types.ImageReference if imageName == "" && imageID == "" { return ContainerInfo{}, ErrEmptyID @@ -111,13 +111,15 @@ func (r *storageService) CreateContainerStorage(ctx context.Context, systemConte // Build the container. names := []string{containerName} - options := storage.ContainerOptions{ - IDMappingOptions: storage.IDMappingOptions{ - HostUIDMapping: true, - HostGIDMapping: true, - }, + if options == nil { + options = &storage.ContainerOptions{ + IDMappingOptions: storage.IDMappingOptions{ + HostUIDMapping: true, + HostGIDMapping: true, + }, + } } - container, err := r.store.CreateContainer(containerID, names, img.ID, "", string(mdata), &options) + container, err := r.store.CreateContainer(containerID, names, img.ID, "", string(mdata), options) if err != nil { logrus.Debugf("failed to create container %s(%s): %v", metadata.ContainerName, containerID, err) -- cgit v1.2.3-54-g00ecf