summaryrefslogtreecommitdiff
path: root/pkg/namespaces
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2020-02-24 17:38:06 +0100
committerGiuseppe Scrivano <gscrivan@redhat.com>2020-04-06 16:32:36 +0200
commit3a0a727110c59332e1a0f5b4a5be311244668a8c (patch)
treeff1afd6d97f329718f15dd541aa95e721690fe65 /pkg/namespaces
parent5b853bb272a754a54fa78a3e619de0304864151f (diff)
downloadpodman-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')
-rw-r--r--pkg/namespaces/namespaces.go54
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