summaryrefslogtreecommitdiff
path: root/pkg
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
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')
-rw-r--r--pkg/namespaces/namespaces.go54
-rw-r--r--pkg/spec/namespaces.go4
-rw-r--r--pkg/util/utils.go12
3 files changed, 67 insertions, 3 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
diff --git a/pkg/spec/namespaces.go b/pkg/spec/namespaces.go
index 838d95c54..aebc90f68 100644
--- a/pkg/spec/namespaces.go
+++ b/pkg/spec/namespaces.go
@@ -277,7 +277,7 @@ func (c *UserConfig) ConfigureGenerator(g *generate.Generator) error {
}
func (c *UserConfig) getPostConfigureNetNS() bool {
- hasUserns := c.UsernsMode.IsContainer() || c.UsernsMode.IsNS() || len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0
+ hasUserns := c.UsernsMode.IsContainer() || c.UsernsMode.IsNS() || c.UsernsMode.IsAuto() || len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0
postConfigureNetNS := hasUserns && !c.UsernsMode.IsHost()
return postConfigureNetNS
}
@@ -285,7 +285,7 @@ func (c *UserConfig) getPostConfigureNetNS() bool {
// InNS returns true if the UserConfig indicates to be in a dedicated user
// namespace.
func (c *UserConfig) InNS(isRootless bool) bool {
- hasUserns := c.UsernsMode.IsContainer() || c.UsernsMode.IsNS() || len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0
+ hasUserns := c.UsernsMode.IsContainer() || c.UsernsMode.IsNS() || c.UsernsMode.IsAuto() || len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0
return isRootless || (hasUserns && !c.UsernsMode.IsHost())
}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 0c055745d..372c7c53b 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -327,6 +327,18 @@ func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []strin
HostGIDMapping: true,
}
+ if mode.IsAuto() {
+ var err error
+ options.HostUIDMapping = false
+ options.HostGIDMapping = false
+ options.AutoUserNs = true
+ opts, err := mode.GetAutoOptions()
+ if err != nil {
+ return nil, err
+ }
+ options.AutoUserNsOpts = *opts
+ return &options, nil
+ }
if mode.IsKeepID() {
if len(uidMapSlice) > 0 || len(gidMapSlice) > 0 {
return nil, errors.New("cannot specify custom mappings with --userns=keep-id")