summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/domain/infra/runtime_libpod.go51
-rw-r--r--pkg/machine/e2e/config_init_test.go10
-rw-r--r--pkg/machine/e2e/init_test.go20
-rw-r--r--pkg/namespaces/namespaces.go49
-rw-r--r--pkg/specgen/generate/namespaces.go11
-rw-r--r--pkg/specgen/namespaces.go15
-rw-r--r--pkg/util/utils.go8
7 files changed, 108 insertions, 56 deletions
diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go
index f76fab4ea..a23a23653 100644
--- a/pkg/domain/infra/runtime_libpod.go
+++ b/pkg/domain/infra/runtime_libpod.go
@@ -294,57 +294,6 @@ func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []strin
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")
- }
- if len(subUIDMap) > 0 || len(subGIDMap) > 0 {
- return nil, errors.New("cannot specify subuidmap or subgidmap with --userns=keep-id")
- }
- if !rootless.IsRootless() {
- return nil, errors.New("keep-id is only supported in rootless mode")
- }
- min := func(a, b int) int {
- if a < b {
- return a
- }
- return b
- }
-
- uid := rootless.GetRootlessUID()
- gid := rootless.GetRootlessGID()
-
- uids, gids, err := rootless.GetConfiguredMappings()
- if err != nil {
- return nil, fmt.Errorf("cannot read mappings: %w", err)
- }
- maxUID, maxGID := 0, 0
- for _, u := range uids {
- maxUID += u.Size
- }
- for _, g := range gids {
- maxGID += g.Size
- }
-
- options.UIDMap, options.GIDMap = nil, nil
-
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(uid, maxUID)})
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid, HostID: 0, Size: 1})
- if maxUID > uid {
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid + 1, HostID: uid + 1, Size: maxUID - uid})
- }
-
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(gid, maxGID)})
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid, HostID: 0, Size: 1})
- if maxGID > gid {
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid + 1, HostID: gid + 1, Size: maxGID - gid})
- }
-
- options.HostUIDMapping = false
- options.HostGIDMapping = false
- // Simply ignore the setting and do not set up an inner namespace for root as it is a no-op
- return &options, nil
- }
if subGIDMap == "" && subUIDMap != "" {
subGIDMap = subUIDMap
diff --git a/pkg/machine/e2e/config_init_test.go b/pkg/machine/e2e/config_init_test.go
index d6c7990b0..305d101a3 100644
--- a/pkg/machine/e2e/config_init_test.go
+++ b/pkg/machine/e2e/config_init_test.go
@@ -9,6 +9,7 @@ type initMachine struct {
--cpus uint Number of CPUs (default 1)
--disk-size uint Disk size in GB (default 100)
--ignition-path string Path to ignition file
+ --username string Username of the remote user (default "core" for FCOS, "user" for Fedora)
--image-path string Path to qcow image (default "testing")
-m, --memory uint Memory in MB (default 2048)
--now Start machine now
@@ -21,6 +22,7 @@ type initMachine struct {
cpus *uint
diskSize *uint
ignitionPath string
+ username string
imagePath string
memory *uint
now bool
@@ -42,6 +44,9 @@ func (i *initMachine) buildCmd(m *machineTestBuilder) []string {
if l := len(i.ignitionPath); l > 0 {
cmd = append(cmd, "--ignition-path", i.ignitionPath)
}
+ if l := len(i.username); l > 0 {
+ cmd = append(cmd, "--username", i.username)
+ }
if l := len(i.imagePath); l > 0 {
cmd = append(cmd, "--image-path", i.imagePath)
}
@@ -76,6 +81,11 @@ func (i *initMachine) withIgnitionPath(path string) *initMachine { //nolint:unus
return i
}
+func (i *initMachine) withUsername(username string) *initMachine {
+ i.username = username
+ return i
+}
+
func (i *initMachine) withImagePath(path string) *initMachine {
i.imagePath = path
return i
diff --git a/pkg/machine/e2e/init_test.go b/pkg/machine/e2e/init_test.go
index 859a3ca46..c298d3b14 100644
--- a/pkg/machine/e2e/init_test.go
+++ b/pkg/machine/e2e/init_test.go
@@ -77,6 +77,26 @@ var _ = Describe("podman machine init", func() {
Expect(inspectAfter[0].State).To(Equal(machine.Running))
})
+ It("simple init with username", func() {
+ i := new(initMachine)
+ remoteUsername := "remoteuser"
+ session, err := mb.setCmd(i.withImagePath(mb.imagePath).withUsername(remoteUsername)).run()
+ Expect(err).To(BeNil())
+ Expect(session).To(Exit(0))
+
+ inspectBefore, ec, err := mb.toQemuInspectInfo()
+ Expect(err).To(BeNil())
+ Expect(ec).To(BeZero())
+
+ Expect(len(inspectBefore)).To(BeNumerically(">", 0))
+ testMachine := inspectBefore[0]
+ Expect(testMachine.Name).To(Equal(mb.names[0]))
+ Expect(testMachine.Resources.CPUs).To(Equal(uint64(1)))
+ Expect(testMachine.Resources.Memory).To(Equal(uint64(2048)))
+ Expect(testMachine.SSHConfig.RemoteUsername).To((Equal(remoteUsername)))
+
+ })
+
It("machine init with cpus, disk size, memory, timezone", func() {
name := randomString()
i := new(initMachine)
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index 8eacb8da7..6dd576ea5 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -21,6 +21,14 @@ const (
slirpType = "slirp4netns"
)
+// KeepIDUserNsOptions defines how to keepIDmatically create a user namespace.
+type KeepIDUserNsOptions struct {
+ // UID is the target uid in the user namespace.
+ UID *uint32
+ // GID is the target uid in the user namespace.
+ GID *uint32
+}
+
// CgroupMode represents cgroup mode in the container.
type CgroupMode string
@@ -93,7 +101,8 @@ func (n UsernsMode) IsHost() bool {
// IsKeepID indicates whether container uses a mapping where the (uid, gid) on the host is kept inside of the namespace.
func (n UsernsMode) IsKeepID() bool {
- return n == "keep-id"
+ parts := strings.Split(string(n), ":")
+ return parts[0] == "keep-id"
}
// IsNoMap indicates whether container uses a mapping where the (uid, gid) on the host is not present in the namespace.
@@ -154,6 +163,44 @@ func (n UsernsMode) GetAutoOptions() (*types.AutoUserNsOptions, error) {
return &options, nil
}
+// GetKeepIDOptions returns a KeepIDUserNsOptions with the settings to keepIDmatically set up
+// a user namespace.
+func (n UsernsMode) GetKeepIDOptions() (*KeepIDUserNsOptions, error) {
+ parts := strings.SplitN(string(n), ":", 2)
+ if parts[0] != "keep-id" {
+ return nil, fmt.Errorf("wrong user namespace mode")
+ }
+ options := KeepIDUserNsOptions{}
+ 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 "uid":
+ s, err := strconv.ParseUint(v[1], 10, 32)
+ if err != nil {
+ return nil, err
+ }
+ v := uint32(s)
+ options.UID = &v
+ case "gid":
+ s, err := strconv.ParseUint(v[1], 10, 32)
+ if err != nil {
+ return nil, err
+ }
+ v := uint32(s)
+ options.GID = &v
+ 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())
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index f0d4e9153..e27a3abac 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
+ "github.com/containers/podman/v4/pkg/namespaces"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/podman/v4/pkg/specgen"
"github.com/containers/podman/v4/pkg/util"
@@ -198,12 +199,18 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
if !rootless.IsRootless() {
return nil, errors.New("keep-id is only supported in rootless mode")
}
- toReturn = append(toReturn, libpod.WithAddCurrentUserPasswdEntry())
+ opts, err := namespaces.UsernsMode(s.UserNS.String()).GetKeepIDOptions()
+ if err != nil {
+ return nil, err
+ }
+ if opts.UID == nil && opts.GID == nil {
+ toReturn = append(toReturn, libpod.WithAddCurrentUserPasswdEntry())
+ }
// If user is not overridden, set user in the container
// to user running Podman.
if s.User == "" {
- _, uid, gid, err := util.GetKeepIDMapping()
+ _, uid, gid, err := util.GetKeepIDMapping(opts)
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go
index 03a2049f6..8cc0fe6a9 100644
--- a/pkg/specgen/namespaces.go
+++ b/pkg/specgen/namespaces.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/common/pkg/cgroups"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
+ "github.com/containers/podman/v4/pkg/namespaces"
"github.com/containers/podman/v4/pkg/util"
"github.com/containers/storage"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -308,6 +309,14 @@ func ParseUserNamespace(ns string) (Namespace, error) {
case ns == "keep-id":
toReturn.NSMode = KeepID
return toReturn, nil
+ case strings.HasPrefix(ns, "keep-id:"):
+ split := strings.SplitN(ns, ":", 2)
+ if len(split) != 2 {
+ return toReturn, errors.New("invalid setting for keep-id: mode")
+ }
+ toReturn.NSMode = KeepID
+ toReturn.Value = split[1]
+ return toReturn, nil
case ns == "nomap":
toReturn.NSMode = NoMap
return toReturn, nil
@@ -490,7 +499,11 @@ func SetupUserNS(idmappings *storage.IDMappingOptions, userns Namespace, g *gene
return user, err
}
case KeepID:
- mappings, uid, gid, err := util.GetKeepIDMapping()
+ opts, err := namespaces.UsernsMode(userns.String()).GetKeepIDOptions()
+ if err != nil {
+ return user, err
+ }
+ mappings, uid, gid, err := util.GetKeepIDMapping(opts)
if err != nil {
return user, err
}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 33c11d611..87e403986 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -342,7 +342,7 @@ func ParseSignal(rawSignal string) (syscall.Signal, error) {
}
// GetKeepIDMapping returns the mappings and the user to use when keep-id is used
-func GetKeepIDMapping() (*stypes.IDMappingOptions, int, int, error) {
+func GetKeepIDMapping(opts *namespaces.KeepIDUserNsOptions) (*stypes.IDMappingOptions, int, int, error) {
if !rootless.IsRootless() {
return nil, -1, -1, errors.New("keep-id is only supported in rootless mode")
}
@@ -359,6 +359,12 @@ func GetKeepIDMapping() (*stypes.IDMappingOptions, int, int, error) {
uid := rootless.GetRootlessUID()
gid := rootless.GetRootlessGID()
+ if opts.UID != nil {
+ uid = int(*opts.UID)
+ }
+ if opts.GID != nil {
+ gid = int(*opts.GID)
+ }
uids, gids, err := rootless.GetConfiguredMappings()
if err != nil {