summaryrefslogtreecommitdiff
path: root/pkg/specgen/namespaces.go
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2020-12-01 16:23:40 -0500
committerUrvashi Mohnani <umohnani@redhat.com>2021-08-09 15:17:22 -0400
commit221b1add74e17ded10e8f2f832a53065578aa264 (patch)
tree499c89b26092c92026f3e7532b6bd633d920652f /pkg/specgen/namespaces.go
parent431707c72044154b956944d00b1ba40b303decb2 (diff)
downloadpodman-221b1add74e17ded10e8f2f832a53065578aa264.tar.gz
podman-221b1add74e17ded10e8f2f832a53065578aa264.tar.bz2
podman-221b1add74e17ded10e8f2f832a53065578aa264.zip
Add support for pod inside of user namespace.
Add the --userns flag to podman pod create and keep track of the userns setting that pod was created with so that all containers created within the pod will inherit that userns setting. Specifically we need to be able to launch a pod with --userns=keep-id Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
Diffstat (limited to 'pkg/specgen/namespaces.go')
-rw-r--r--pkg/specgen/namespaces.go58
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
+}