From 4fbfa7de6ecf7f6c3b377801d791eec23365b50e Mon Sep 17 00:00:00 2001 From: Misaki Kasumi Date: Tue, 20 Aug 2024 16:28:20 +0800 Subject: [PATCH] quadlet: support user mapping in pod unit Signed-off-by: Misaki Kasumi --- cmd/quadlet/main.go | 2 +- docs/source/markdown/podman-systemd.unit.5.md | 34 +++++++++++++++++++ pkg/systemd/quadlet/quadlet.go | 15 +++++++- test/e2e/quadlet/remap-auto.pod | 4 +++ test/e2e/quadlet/remap-auto2.pod | 9 +++++ test/e2e/quadlet/remap-keep-id.pod | 4 +++ test/e2e/quadlet/remap-manual.pod | 11 ++++++ test/e2e/quadlet_test.go | 12 ++++--- 8 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 test/e2e/quadlet/remap-auto.pod create mode 100644 test/e2e/quadlet/remap-auto2.pod create mode 100644 test/e2e/quadlet/remap-keep-id.pod create mode 100644 test/e2e/quadlet/remap-manual.pod diff --git a/cmd/quadlet/main.go b/cmd/quadlet/main.go index eef05d30ae..3d32707420 100644 --- a/cmd/quadlet/main.go +++ b/cmd/quadlet/main.go @@ -658,7 +658,7 @@ func process() error { case strings.HasSuffix(unit.Filename, ".build"): service, err = quadlet.ConvertBuild(unit, unitsInfoMap) case strings.HasSuffix(unit.Filename, ".pod"): - service, err = quadlet.ConvertPod(unit, unit.Filename, unitsInfoMap) + service, err = quadlet.ConvertPod(unit, unit.Filename, unitsInfoMap, isUserFlag) default: Logf("Unsupported file type %q", unit.Filename) continue diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index c16d46361c..b4a62b7ea2 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -867,6 +867,7 @@ Valid options for `[Pod]` are listed below: | **[Pod] options** | **podman container create equivalent** | |-------------------------------------|----------------------------------------| | ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf | +| GIDMap=0:10000:10 | --gidmap=0:10000:10 | | GlobalArgs=--log-level=debug | --log-level=debug | | Network=host | --network host | | NetworkAlias=name | --network-alias name | @@ -874,6 +875,10 @@ Valid options for `[Pod]` are listed below: | PodName=name | --name=name | | PublishPort=50-59 | --publish 50-59 | | ServiceName=name | Name the systemd unit `name.service` | +| SubGIDMap=gtest | --subgidname=gtest | +| SubUIDMap=utest | --subuidname=utest | +| UIDMap=0:10000:10 | --uidmap=0:10000:10 | +| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 | | Volume=/source:/dest | --volume /source:/dest | Supported keys in the `[Pod]` section are: @@ -884,6 +889,13 @@ Load the specified containers.conf(5) module. Equivalent to the Podman `--module This key can be listed multiple times. +### `GIDMap=` + +Create the pod in a new user namespace using the supplied GID mapping. +Equivalent to the Podman `--gidmap` option. + +This key can be listed multiple times. + ### `GlobalArgs=` This key contains a list of arguments passed directly between `podman` and `pod` @@ -966,6 +978,28 @@ Setting this key overrides this behavior by instructing Quadlet to use the provi Note, the name should not include the `.service` file extension +### `SubGIDMap=` + +Create the pod in a new user namespace using the map with name in the /etc/subgid file. +Equivalent to the Podman `--subgidname` option. + +### `SubUIDMap=` + +Create the pod in a new user namespace using the map with name in the /etc/subuid file. +Equivalent to the Podman `--subuidname` option. + +### `UIDMap=` + +Create the pod in a new user namespace using the supplied UID mapping. +Equivalent to the Podman `--uidmap` option. + +This key can be listed multiple times. + +### `UserNS=` + +Set the user namespace mode for the pod. This is equivalent to the Podman `--userns` option and +generally has the form `MODE[:OPTIONS,...]`. + ### `Volume=` Mount a volume in the pod. This is equivalent to the Podman `--volume` option, and diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 2509259d3d..21cc82ada2 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -380,13 +380,22 @@ var ( supportedPodKeys = map[string]bool{ KeyContainersConfModule: true, + KeyGIDMap: true, KeyGlobalArgs: true, KeyNetwork: true, KeyNetworkAlias: true, KeyPodName: true, KeyPodmanArgs: true, KeyPublishPort: true, + KeyRemapGid: true, + KeyRemapUid: true, + KeyRemapUidSize: true, + KeyRemapUsers: true, KeyServiceName: true, + KeySubGIDMap: true, + KeySubUIDMap: true, + KeyUIDMap: true, + KeyUserNS: true, KeyVolume: true, } ) @@ -1570,7 +1579,7 @@ func getServiceName(quadletUnitFile *parser.UnitFile, groupName string, defaultE return removeExtension(quadletUnitFile.Filename, "", defaultExtraSuffix) } -func ConvertPod(podUnit *parser.UnitFile, name string, unitsInfoMap map[string]*UnitInfo) (*parser.UnitFile, error) { +func ConvertPod(podUnit *parser.UnitFile, name string, unitsInfoMap map[string]*UnitInfo, isUser bool) (*parser.UnitFile, error) { unitInfo, ok := unitsInfoMap[podUnit.Filename] if !ok { return nil, fmt.Errorf("internal error while processing pod %s", podUnit.Filename) @@ -1639,6 +1648,10 @@ func ConvertPod(podUnit *parser.UnitFile, name string, unitsInfoMap map[string]* "--replace", ) + if err := handleUserMappings(podUnit, PodGroup, execStartPre, isUser, true); err != nil { + return nil, err + } + if err := handlePublishPorts(podUnit, PodGroup, execStartPre); err != nil { return nil, err } diff --git a/test/e2e/quadlet/remap-auto.pod b/test/e2e/quadlet/remap-auto.pod new file mode 100644 index 0000000000..1e3073eb6f --- /dev/null +++ b/test/e2e/quadlet/remap-auto.pod @@ -0,0 +1,4 @@ +## assert-podman-pre-args --userns=auto + +[Pod] +RemapUsers=auto diff --git a/test/e2e/quadlet/remap-auto2.pod b/test/e2e/quadlet/remap-auto2.pod new file mode 100644 index 0000000000..884f73b6ce --- /dev/null +++ b/test/e2e/quadlet/remap-auto2.pod @@ -0,0 +1,9 @@ +## assert-podman-pre-args "--userns=auto:uidmapping=0:10000:10,uidmapping=10:20000:10,gidmapping=0:10000:10,gidmapping=10:20000:10,size=20" + +[Pod] +RemapUsers=auto +RemapUid=0:10000:10 +RemapUid=10:20000:10 +RemapGid=0:10000:10 +RemapGid=10:20000:10 +RemapUidSize=20 diff --git a/test/e2e/quadlet/remap-keep-id.pod b/test/e2e/quadlet/remap-keep-id.pod new file mode 100644 index 0000000000..eff1f7e610 --- /dev/null +++ b/test/e2e/quadlet/remap-keep-id.pod @@ -0,0 +1,4 @@ +## assert-podman-pre-args --userns=keep-id + +[Pod] +RemapUsers=keep-id diff --git a/test/e2e/quadlet/remap-manual.pod b/test/e2e/quadlet/remap-manual.pod new file mode 100644 index 0000000000..ac06962b7f --- /dev/null +++ b/test/e2e/quadlet/remap-manual.pod @@ -0,0 +1,11 @@ +## assert-podman-pre-args "--uidmap=0:10000:10" +## assert-podman-pre-args "--uidmap=10:20000:10" +## assert-podman-pre-args "--gidmap=0:10000:10" +## assert-podman-pre-args "--gidmap=10:20000:10" + +[Pod] +RemapUsers=manual +RemapUid=0:10000:10 +RemapUid=10:20000:10 +RemapGid=0:10000:10 +RemapGid=10:20000:10 diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index d3d9ad1a7d..bbfc515be6 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -998,11 +998,15 @@ BOGUS=foo Entry("Build - TLSVerify Key", "tls-verify.build"), Entry("Build - Variant Key", "variant.build"), - Entry("basic.pod", "basic.pod"), - Entry("name.pod", "name.pod"), - Entry("network.pod", "network.pod"), - Entry("podmanargs.pod", "podmanargs.pod"), + Entry("Pod - Basic", "basic.pod"), + Entry("Pod - Name", "name.pod"), + Entry("Pod - Network", "network.pod"), + Entry("Pod - PodmanArgs", "podmanargs.pod"), Entry("Pod - NetworkAlias", "network-alias.pod"), + Entry("Pod - Remap auto", "remap-auto.pod"), + Entry("Pod - Remap auto2", "remap-auto2.pod"), + Entry("Pod - Remap keep-id", "remap-keep-id.pod"), + Entry("Pod - Remap manual", "remap-manual.pod"), ) DescribeTable("Running expected warning quadlet test case",