summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/common.go17
-rw-r--r--cmd/podman/create.go71
-rw-r--r--cmd/podman/inspect.go2
-rw-r--r--cmd/podman/libpodruntime/runtime.go37
-rw-r--r--cmd/podman/run.go16
-rw-r--r--cmd/podman/run_test.go3
-rw-r--r--cmd/podman/spec.go17
7 files changed, 117 insertions, 46 deletions
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 68d22b629..635869609 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -200,6 +200,10 @@ var createFlags = []cli.Flag{
Usage: "Expose a port or a range of ports (default [])",
},
cli.StringSliceFlag{
+ Name: "gidmap",
+ Usage: "GID map to use for the user namespace",
+ },
+ cli.StringSliceFlag{
Name: "group-add",
Usage: "Add additional groups to join (default [])",
},
@@ -341,6 +345,15 @@ var createFlags = []cli.Flag{
Name: "storage-opt",
Usage: "Storage driver options per container (default [])",
},
+ cli.StringFlag{
+ Name: "subgidname",
+ Usage: "Name of range listed in /etc/subgid for use in user namespace",
+ },
+ cli.StringFlag{
+ Name: "subuidname",
+ Usage: "Name of range listed in /etc/subuid for use in user namespace",
+ },
+
cli.StringSliceFlag{
Name: "sysctl",
Usage: "Sysctl options (default [])",
@@ -354,6 +367,10 @@ var createFlags = []cli.Flag{
Usage: "Allocate a pseudo-TTY for container",
},
cli.StringSliceFlag{
+ Name: "uidmap",
+ Usage: "UID map to use for the user namespace",
+ },
+ cli.StringSliceFlag{
Name: "ulimit",
Usage: "Ulimit options (default [])",
},
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index 54a542ee5..7740da8e1 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -1,6 +1,7 @@
package main
import (
+ "context"
"encoding/json"
"fmt"
"net"
@@ -9,6 +10,7 @@ import (
"strings"
"syscall"
+ "github.com/containers/storage"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/signal"
"github.com/docker/go-connections/nat"
@@ -92,7 +94,8 @@ type createConfig struct {
Hostname string //hostname
Image string
ImageID string
- BuiltinImgVolumes map[string]struct{} // volumes defined in the image config
+ BuiltinImgVolumes map[string]struct{} // volumes defined in the image config
+ IDMappings *storage.IDMappingOptions
ImageVolumeType string // how to handle the image volume, either bind, tmpfs, or ignore
Interactive bool //interactive
IpcMode container.IpcMode //ipc
@@ -108,8 +111,7 @@ type createConfig struct {
Network string //network
NetworkAlias []string //network-alias
PidMode container.PidMode //pid
- NsUser string
- Pod string //pod
+ Pod string //pod
PortBindings nat.PortMap
Privileged bool //privileged
Publish []string //publish
@@ -119,20 +121,21 @@ type createConfig struct {
Resources createResourceConfig
Rm bool //rm
ShmDir string
- StopSignal syscall.Signal // stop-signal
- StopTimeout uint // stop-timeout
- Sysctl map[string]string //sysctl
- Tmpfs []string // tmpfs
- Tty bool //tty
- User string //user
- UtsMode container.UTSMode //uts
- Volumes []string //volume
- WorkDir string //workdir
- MountLabel string //SecurityOpts
- ProcessLabel string //SecurityOpts
- NoNewPrivs bool //SecurityOpts
- ApparmorProfile string //SecurityOpts
- SeccompProfilePath string //SecurityOpts
+ StopSignal syscall.Signal // stop-signal
+ StopTimeout uint // stop-timeout
+ Sysctl map[string]string //sysctl
+ Tmpfs []string // tmpfs
+ Tty bool //tty
+ UsernsMode container.UsernsMode //userns
+ User string //user
+ UtsMode container.UTSMode //uts
+ Volumes []string //volume
+ WorkDir string //workdir
+ MountLabel string //SecurityOpts
+ ProcessLabel string //SecurityOpts
+ NoNewPrivs bool //SecurityOpts
+ ApparmorProfile string //SecurityOpts
+ SeccompProfilePath string //SecurityOpts
SecurityOpts []string
}
@@ -174,7 +177,15 @@ func createCmd(c *cli.Context) error {
return errors.Errorf("image name or ID is required")
}
- runtime, err := libpodruntime.GetRuntime(c)
+ mappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidmap"), c.String("subgidmap"))
+ if err != nil {
+ return err
+ }
+ storageOpts := storage.DefaultStoreOptions
+ storageOpts.UIDMap = mappings.UIDMap
+ storageOpts.GIDMap = mappings.GIDMap
+
+ runtime, err := libpodruntime.GetRuntimeWithStorageOpts(c, &storageOpts)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
@@ -188,7 +199,7 @@ func createCmd(c *cli.Context) error {
return err
}
data, err := newImage.Inspect(ctx)
- createConfig, err := parseCreateOpts(c, runtime, newImage.Names()[0], data)
+ createConfig, err := parseCreateOpts(ctx, c, runtime, newImage.Names()[0], data)
if err != nil {
return err
}
@@ -211,6 +222,7 @@ func createCmd(c *cli.Context) error {
options = append(options, libpod.WithShmDir(createConfig.ShmDir))
options = append(options, libpod.WithShmSize(createConfig.Resources.ShmSize))
options = append(options, libpod.WithGroups(createConfig.GroupAdd))
+ options = append(options, libpod.WithIDMappings(*createConfig.IDMappings))
ctr, err := runtime.NewContainer(ctx, runtimeSpec, options...)
if err != nil {
return err
@@ -414,10 +426,16 @@ func getRandomPort() (int, error) {
// Parses CLI options related to container creation into a config which can be
// parsed into an OCI runtime spec
-func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*createConfig, error) {
- var inputCommand, command []string
- var memoryLimit, memoryReservation, memorySwap, memoryKernel int64
- var blkioWeight uint16
+func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*createConfig, error) {
+ var (
+ inputCommand, command []string
+ memoryLimit, memoryReservation, memorySwap, memoryKernel int64
+ blkioWeight uint16
+ )
+ idmappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidname"), c.String("subgidname"))
+ if err != nil {
+ return nil, err
+ }
imageID := data.ID
@@ -473,6 +491,11 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime, imageName string,
return nil, errors.Errorf("--pid %q is not valid", c.String("pid"))
}
+ usernsMode := container.UsernsMode(c.String("userns"))
+ if !usernsMode.Valid() {
+ return nil, errors.Errorf("--userns %q is not valid", c.String("userns"))
+ }
+
if c.Bool("detach") && c.Bool("rm") {
return nil, errors.Errorf("--rm and --detach can not be specified together")
}
@@ -653,6 +676,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime, imageName string,
GroupAdd: c.StringSlice("group-add"),
Hostname: c.String("hostname"),
HostAdd: c.StringSlice("add-host"),
+ IDMappings: idmappings,
Image: imageName,
ImageID: imageID,
Interactive: c.Bool("interactive"),
@@ -712,6 +736,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime, imageName string,
Tmpfs: c.StringSlice("tmpfs"),
Tty: tty,
User: user,
+ UsernsMode: usernsMode,
Volumes: c.StringSlice("volume"),
WorkDir: workDir,
}
diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go
index f54eb6d10..0fd1760a9 100644
--- a/cmd/podman/inspect.go
+++ b/cmd/podman/inspect.go
@@ -225,7 +225,7 @@ func getCtrInspectInfo(ctr *libpod.Container, ctrInspectData *inspect.ContainerI
IpcMode: string(createArtifact.IpcMode),
Cgroup: cgroup,
UTSMode: string(createArtifact.UtsMode),
- UsernsMode: createArtifact.NsUser,
+ UsernsMode: string(createArtifact.UsernsMode),
GroupAdd: spec.Process.User.AdditionalGids,
ContainerIDFile: createArtifact.CidFile,
AutoRemove: createArtifact.Rm,
diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go
index f9c14f6e7..d1657325d 100644
--- a/cmd/podman/libpodruntime/runtime.go
+++ b/cmd/podman/libpodruntime/runtime.go
@@ -8,27 +8,28 @@ import (
// GetRuntime generates a new libpod runtime configured by command line options
func GetRuntime(c *cli.Context) (*libpod.Runtime, error) {
+ storageOpts := storage.DefaultStoreOptions
+ return GetRuntimeWithStorageOpts(c, &storageOpts)
+}
+
+// GetRuntime generates a new libpod runtime configured by command line options
+func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions) (*libpod.Runtime, error) {
options := []libpod.RuntimeOption{}
- if c.GlobalIsSet("root") || c.GlobalIsSet("runroot") ||
- c.GlobalIsSet("storage-opt") || c.GlobalIsSet("storage-driver") {
- storageOpts := storage.DefaultStoreOptions
-
- if c.GlobalIsSet("root") {
- storageOpts.GraphRoot = c.GlobalString("root")
- }
- if c.GlobalIsSet("runroot") {
- storageOpts.RunRoot = c.GlobalString("runroot")
- }
- if c.GlobalIsSet("storage-driver") {
- storageOpts.GraphDriverName = c.GlobalString("storage-driver")
- }
- if c.GlobalIsSet("storage-opt") {
- storageOpts.GraphDriverOptions = c.GlobalStringSlice("storage-opt")
- }
-
- options = append(options, libpod.WithStorageConfig(storageOpts))
+ if c.GlobalIsSet("root") {
+ storageOpts.GraphRoot = c.GlobalString("root")
+ }
+ if c.GlobalIsSet("runroot") {
+ storageOpts.RunRoot = c.GlobalString("runroot")
}
+ if c.GlobalIsSet("storage-driver") {
+ storageOpts.GraphDriverName = c.GlobalString("storage-driver")
+ }
+ if c.GlobalIsSet("storage-opt") {
+ storageOpts.GraphDriverOptions = c.GlobalStringSlice("storage-opt")
+ }
+
+ options = append(options, libpod.WithStorageConfig(*storageOpts))
// TODO CLI flags for image config?
// TODO CLI flag for signature policy?
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index 5f0034e90..06bc0e9df 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -9,10 +9,12 @@ import (
"strconv"
"strings"
+ "github.com/containers/storage"
"github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/image"
+ "github.com/projectatomic/libpod/pkg/util"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
@@ -50,7 +52,15 @@ func runCmd(c *cli.Context) error {
}
}
- runtime, err := libpodruntime.GetRuntime(c)
+ storageOpts := storage.DefaultStoreOptions
+ mappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidmap"), c.String("subgidmap"))
+ if err != nil {
+ return err
+ }
+ storageOpts.UIDMap = mappings.UIDMap
+ storageOpts.GIDMap = mappings.GIDMap
+
+ runtime, err := libpodruntime.GetRuntimeWithStorageOpts(c, &storageOpts)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
@@ -60,7 +70,6 @@ func runCmd(c *cli.Context) error {
}
ctx := getContext()
-
rtc := runtime.GetConfig()
newImage, err := runtime.ImageRuntime().New(ctx, c.Args()[0], rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{}, false, false)
if err != nil {
@@ -76,7 +85,7 @@ func runCmd(c *cli.Context) error {
} else {
imageName = newImage.Names()[0]
}
- createConfig, err := parseCreateOpts(c, runtime, imageName, data)
+ createConfig, err := parseCreateOpts(ctx, c, runtime, imageName, data)
if err != nil {
return err
}
@@ -101,6 +110,7 @@ func runCmd(c *cli.Context) error {
options = append(options, libpod.WithShmDir(createConfig.ShmDir))
options = append(options, libpod.WithShmSize(createConfig.Resources.ShmSize))
options = append(options, libpod.WithGroups(createConfig.GroupAdd))
+ options = append(options, libpod.WithIDMappings(*createConfig.IDMappings))
// Default used if not overridden on command line
diff --git a/cmd/podman/run_test.go b/cmd/podman/run_test.go
index 3baee4615..bbcdcc60a 100644
--- a/cmd/podman/run_test.go
+++ b/cmd/podman/run_test.go
@@ -75,7 +75,8 @@ func getRuntimeSpec(c *cli.Context) (*spec.Spec, error) {
}
createConfig, err := parseCreateOpts(c, runtime, "alpine", generateAlpineImageData())
*/
- createConfig, err := parseCreateOpts(c, nil, "alpine", generateAlpineImageData())
+ ctx := getContext()
+ createConfig, err := parseCreateOpts(ctx, c, nil, "alpine", generateAlpineImageData())
if err != nil {
return nil, err
}
diff --git a/cmd/podman/spec.go b/cmd/podman/spec.go
index fc2ab267d..15dab6c4d 100644
--- a/cmd/podman/spec.go
+++ b/cmd/podman/spec.go
@@ -66,6 +66,13 @@ func addPidNS(config *createConfig, g *generate.Generator) error {
return nil
}
+func addUserNS(config *createConfig, g *generate.Generator) error {
+ if (len(config.IDMappings.UIDMap) > 0 || len(config.IDMappings.GIDMap) > 0) && !config.UsernsMode.IsHost() {
+ g.AddOrReplaceLinuxNamespace(spec.UserNamespace, "")
+ }
+ return nil
+}
+
func addNetNS(config *createConfig, g *generate.Generator) error {
netMode := config.NetMode
if netMode.IsHost() {
@@ -257,6 +264,12 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) {
}
}
+ for _, uidmap := range config.IDMappings.UIDMap {
+ g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size))
+ }
+ for _, gidmap := range config.IDMappings.GIDMap {
+ g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size))
+ }
// SECURITY OPTS
g.SetProcessNoNewPrivileges(config.NoNewPrivs)
g.SetProcessApparmorProfile(config.ApparmorProfile)
@@ -300,6 +313,10 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) {
return nil, err
}
+ if err := addUserNS(config, &g); err != nil {
+ return nil, err
+ }
+
if err := addNetNS(config, &g); err != nil {
return nil, err
}