diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-02-24 17:38:06 +0100 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-04-06 16:32:36 +0200 |
commit | 3a0a727110c59332e1a0f5b4a5be311244668a8c (patch) | |
tree | ff1afd6d97f329718f15dd541aa95e721690fe65 /pkg/namespaces/namespaces.go | |
parent | 5b853bb272a754a54fa78a3e619de0304864151f (diff) | |
download | podman-3a0a727110c59332e1a0f5b4a5be311244668a8c.tar.gz podman-3a0a727110c59332e1a0f5b4a5be311244668a8c.tar.bz2 podman-3a0a727110c59332e1a0f5b4a5be311244668a8c.zip |
userns: support --userns=auto
automatically pick an empty range and create an user namespace for the
container.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/namespaces/namespaces.go')
-rw-r--r-- | pkg/namespaces/namespaces.go | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go index 14453e7f4..2cb3c3f20 100644 --- a/pkg/namespaces/namespaces.go +++ b/pkg/namespaces/namespaces.go @@ -1,7 +1,11 @@ package namespaces import ( + "fmt" + "strconv" "strings" + + "github.com/containers/storage" ) const ( @@ -92,6 +96,54 @@ func (n UsernsMode) IsKeepID() bool { return n == "keep-id" } +// IsAuto indicates whether container uses the "auto" userns mode. +func (n UsernsMode) IsAuto() bool { + parts := strings.Split(string(n), ":") + return parts[0] == "auto" +} + +// GetAutoOptions returns a AutoUserNsOptions with the settings to setup automatically +// a user namespace. +func (n UsernsMode) GetAutoOptions() (*storage.AutoUserNsOptions, error) { + parts := strings.SplitN(string(n), ":", 2) + if parts[0] != "auto" { + return nil, fmt.Errorf("wrong user namespace mode") + } + options := storage.AutoUserNsOptions{} + if len(parts) == 1 { + return &options, nil + } + for _, o := range strings.Split(parts[1], ",") { + v := strings.SplitN(o, "=", 2) + if len(v) != 2 { + return nil, fmt.Errorf("invalid option specified: %q", o) + } + switch v[0] { + case "size": + s, err := strconv.ParseUint(v[1], 10, 32) + if err != nil { + return nil, err + } + options.Size = uint32(s) + case "uidmapping": + mapping, err := storage.ParseIDMapping([]string{v[1]}, nil, "", "") + if err != nil { + return nil, err + } + options.AdditionalUIDMappings = append(options.AdditionalUIDMappings, mapping.UIDMap...) + case "gidmapping": + mapping, err := storage.ParseIDMapping(nil, []string{v[1]}, "", "") + if err != nil { + return nil, err + } + options.AdditionalGIDMappings = append(options.AdditionalGIDMappings, mapping.GIDMap...) + default: + return nil, fmt.Errorf("unknown option specified: %q", v[0]) + } + } + return &options, nil +} + // IsPrivate indicates whether the container uses the a private userns. func (n UsernsMode) IsPrivate() bool { return !(n.IsHost() || n.IsContainer()) @@ -101,7 +153,7 @@ func (n UsernsMode) IsPrivate() bool { func (n UsernsMode) Valid() bool { parts := strings.Split(string(n), ":") switch mode := parts[0]; mode { - case "", privateType, hostType, "keep-id", nsType: + case "", privateType, hostType, "keep-id", nsType, "auto": case containerType: if len(parts) != 2 || parts[1] == "" { return false |