From 10d969ff1a15e8f53eb5a2fa7eb8cfb321609b55 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Fri, 14 Jan 2022 14:33:01 -0500 Subject: [PATCH] Use PODMAN_USERNS environment variable when running as a service Fixes: https://github.com/containers/podman/issues/11350#issuecomment-1011562526 Also add inspect information about the idmappings if they exists. Signed-off-by: Daniel J Walsh --- libpod/container_inspect.go | 16 +++++++++++++++- libpod/define/container_inspect.go | 8 ++++++++ pkg/specgenutil/specgen.go | 8 ++++++-- test/e2e/run_userns_test.go | 29 +++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 792dfc58ee..5e63db0f26 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -9,6 +9,7 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/driver" "github.com/containers/podman/v3/pkg/util" + "github.com/containers/storage/types" units "github.com/docker/go-units" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" @@ -403,6 +404,17 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp return ctrConfig } +func generateIDMappings(idMappings types.IDMappingOptions) *define.InspectIDMappings { + var inspectMappings define.InspectIDMappings + for _, uid := range idMappings.UIDMap { + inspectMappings.UIDMap = append(inspectMappings.UIDMap, fmt.Sprintf("%d:%d:%d", uid.ContainerID, uid.HostID, uid.Size)) + } + for _, gid := range idMappings.GIDMap { + inspectMappings.GIDMap = append(inspectMappings.GIDMap, fmt.Sprintf("%d:%d:%d", gid.ContainerID, gid.HostID, gid.Size)) + } + return &inspectMappings +} + // Generate the InspectContainerHostConfig struct for the HostConfig field of // Inspect. func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, namedVolumes []*ContainerNamedVolume, mounts []spec.Mount) (*define.InspectContainerHostConfig, error) { @@ -815,7 +827,9 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named } } hostConfig.UsernsMode = usernsMode - + if c.config.IDMappings.UIDMap != nil && c.config.IDMappings.GIDMap != nil { + hostConfig.IDMappings = generateIDMappings(c.config.IDMappings) + } // Devices // Do not include if privileged - assumed that all devices will be // included. diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index ba73e41966..a61f9e6159 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -6,6 +6,11 @@ import ( "github.com/containers/image/v5/manifest" ) +type InspectIDMappings struct { + UIDMap []string `json:"UidMap"` + GIDMap []string `json:"GidMap"` +} + // InspectContainerConfig holds further data about how a container was initially // configured. type InspectContainerConfig struct { @@ -401,7 +406,10 @@ type InspectContainerHostConfig struct { // TODO Rootless has an additional 'keep-id' option, presently not // reflected here. UsernsMode string `json:"UsernsMode"` + // IDMappings is the UIDMapping and GIDMapping used within the container + IDMappings *InspectIDMappings `json:"IDMappings,omitempty"` // ShmSize is the size of the container's SHM device. + ShmSize int64 `json:"ShmSize"` // Runtime is provided purely for Docker compatibility. // It is set unconditionally to "oci" as Podman does not presently diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 8e43cc50e9..70b6abff50 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -205,9 +205,13 @@ func setNamespaces(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) return err } } - // userns must be treated differently + userns := os.Getenv("PODMAN_USERNS") if c.UserNS != "" { - s.UserNS, err = specgen.ParseUserNamespace(c.UserNS) + userns = c.UserNS + } + // userns must be treated differently + if userns != "" { + s.UserNS, err = specgen.ParseUserNamespace(userns) if err != nil { return err } diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go index c1645af06e..e8ba42cf03 100644 --- a/test/e2e/run_userns_test.go +++ b/test/e2e/run_userns_test.go @@ -301,5 +301,34 @@ var _ = Describe("Podman UserNS support", func() { Expect(inspectGID).Should(Exit(0)) Expect(inspectGID.OutputToString()).To(Equal(tt.gid)) } + + }) + It("podman PODMAN_USERNS", func() { + SkipIfNotRootless("keep-id only works in rootless mode") + + podmanUserns, podmanUserusSet := os.LookupEnv("PODMAN_USERNS") + os.Setenv("PODMAN_USERNS", "keep-id") + defer func() { + if podmanUserusSet { + os.Setenv("PODMAN_USERNS", podmanUserns) + } else { + os.Unsetenv("PODMAN_USERNS") + } + }() + if IsRemote() { + podmanTest.RestartRemoteService() + } + + result := podmanTest.Podman([]string{"create", ALPINE, "true"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + + inspect := podmanTest.Podman([]string{"inspect", "--format", "{{ .HostConfig.IDMappings }}", result.OutputToString()}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.OutputToString()).To(Not(Equal(""))) + + if IsRemote() { + podmanTest.RestartRemoteService() + } }) })