mirror of
https://github.com/containers/podman.git
synced 2025-12-11 17:27:19 +08:00
Begin wiring in USERNS Support into podman
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Closes: #690 Approved by: mheon
This commit is contained in:
committed by
Atomic Bot
parent
1f5debd438
commit
b51d737998
@@ -199,6 +199,10 @@ var createFlags = []cli.Flag{
|
||||
Name: "expose",
|
||||
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 [])",
|
||||
@@ -353,6 +366,10 @@ var createFlags = []cli.Flag{
|
||||
Name: "tty, t",
|
||||
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 [])",
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user