diff options
Diffstat (limited to 'pkg/specgen/namespaces.go')
-rw-r--r-- | pkg/specgen/namespaces.go | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go index 76fa66bc7..2f4c48811 100644 --- a/pkg/specgen/namespaces.go +++ b/pkg/specgen/namespaces.go @@ -1,10 +1,16 @@ package specgen import ( + "fmt" + "os" "strings" "github.com/containers/podman/v3/pkg/cgroups" "github.com/containers/podman/v3/pkg/rootless" + "github.com/containers/podman/v3/pkg/util" + "github.com/containers/storage" + spec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/runtime-tools/generate" "github.com/pkg/errors" ) @@ -103,6 +109,13 @@ func (n *Namespace) IsKeepID() bool { return n.NSMode == KeepID } +func (n *Namespace) String() string { + if n.Value != "" { + return fmt.Sprintf("%s:%s", n.NSMode, n.Value) + } + return string(n.NSMode) +} + func validateUserNS(n *Namespace) error { if n == nil { return nil @@ -323,3 +336,48 @@ func ParseNetworkString(network string) (Namespace, []string, map[string][]strin } return ns, cniNets, networkOptions, nil } + +func SetupUserNS(idmappings *storage.IDMappingOptions, userns Namespace, g *generate.Generator) (string, error) { + // User + var user string + switch userns.NSMode { + case Path: + if _, err := os.Stat(userns.Value); err != nil { + return user, errors.Wrap(err, "cannot find specified user namespace path") + } + if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), userns.Value); err != nil { + return user, err + } + // runc complains if no mapping is specified, even if we join another ns. So provide a dummy mapping + g.AddLinuxUIDMapping(uint32(0), uint32(0), uint32(1)) + g.AddLinuxGIDMapping(uint32(0), uint32(0), uint32(1)) + case Host: + if err := g.RemoveLinuxNamespace(string(spec.UserNamespace)); err != nil { + return user, err + } + case KeepID: + mappings, uid, gid, err := util.GetKeepIDMapping() + if err != nil { + return user, err + } + idmappings = mappings + g.SetProcessUID(uint32(uid)) + g.SetProcessGID(uint32(gid)) + user = fmt.Sprintf("%d:%d", uid, gid) + fallthrough + case Private: + if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), ""); err != nil { + return user, err + } + if idmappings == nil || (len(idmappings.UIDMap) == 0 && len(idmappings.GIDMap) == 0) { + return user, errors.Errorf("must provide at least one UID or GID mapping to configure a user namespace") + } + for _, uidmap := range idmappings.UIDMap { + g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size)) + } + for _, gidmap := range idmappings.GIDMap { + g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size)) + } + } + return user, nil +} |