From 9727a43f5a1c05310d2487e4ac0a093ce5674d67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brauner?= Date: Tue, 10 Feb 2026 17:00:39 +0100 Subject: [PATCH] Added setting UID and GID for volumes in quadlet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related: https://issues.redhat.com/browse/RHEL-145863 Signed-off-by: Šimon Brauner --- docs/source/markdown/podman-systemd.unit.5.md | 14 ++++++++-- pkg/systemd/quadlet/quadlet.go | 14 ++++++++++ test/e2e/quadlet/volume-uid-gid.volume | 6 +++++ test/e2e/quadlet_test.go | 1 + test/system/252-quadlet.bats | 26 +++++++++++++++++++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 test/e2e/quadlet/volume-uid-gid.volume diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index 3a0ab08c95..5e337cfd31 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -1601,6 +1601,7 @@ Valid options for `[Volume]` are listed below: | Copy=true | --opt copy | | Device=tmpfs | --opt device=tmpfs | | Driver=image | --driver=image | +| GID=5678 | --gid 5678 | | GlobalArgs=--log-level=debug | --log-level=debug | | Group=192 | --opt "o=group=192" | | Image=quay.io/centos/centos\:latest | --opt image=quay.io/centos/centos\:latest | @@ -1608,6 +1609,7 @@ Valid options for `[Volume]` are listed below: | Options=XYZ | --opt "o=XYZ" | | PodmanArgs=--driver=image | --driver=image | | Type=type | Filesystem type of Device | +| UID=1234 | --uid 1234 | | User=123 | --opt "o=uid=123" | | VolumeName=foo | podman volume create foo | @@ -1634,6 +1636,10 @@ Specify the volume driver name. When set to `image`, the `Image` key must also b This is equivalent to the Podman `--driver` option. +### `GID=` + +The GID that the volume will be created as. Differently than `Group=`, the specified value is not passed to the mount operation. The specified GID will own the volume's mount point directory and affects the volume chown operation. + ### `GlobalArgs=` This key contains a list of arguments passed directly between `podman` and `volume` @@ -1648,7 +1654,7 @@ This key can be listed multiple times. ### `Group=` -The host (numeric) GID, or group name to use as the group for the volume +The host (numeric) GID, or group name to use as the group for the volume. Differently than `GID`, the specified value is passed to the mount operation. ### `Image=` @@ -1692,9 +1698,13 @@ This key can be listed multiple times. The filesystem type of `Device` as used by the **mount(8)** commands `-t` option. +### `UID=` + +The UID that the volume will be created as. Differently than `User`, the specified value is not passed to the mount operation. The specified UID will own the volume's mount point directory and affects the volume chown operation. + ### `User=` -The host (numeric) UID, or user name to use as the owner for the volume +The host (numeric) UID, or user name to use as the owner for the volume. Differently than `UID`, the specified value is passed to the mount operation. ### `VolumeName=` diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 29508bb796..5c4a59488a 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -95,6 +95,7 @@ const ( KeyFile = "File" KeyForceRM = "ForceRM" KeyGateway = "Gateway" + KeyGID = "GID" KeyGIDMap = "GIDMap" KeyGlobalArgs = "GlobalArgs" KeyGroup = "Group" @@ -182,6 +183,7 @@ const ( KeyTLSVerify = "TLSVerify" KeyTmpfs = "Tmpfs" KeyType = "Type" + KeyUID = "UID" KeyUIDMap = "UIDMap" KeyUlimit = "Ulimit" KeyUnmask = "Unmask" @@ -359,6 +361,8 @@ var ( KeyType: true, KeyUser: true, KeyVolumeName: true, + KeyUID: true, + KeyGID: true, }, }, NetworkGroup: { @@ -1102,6 +1106,16 @@ func ConvertVolume(volume *parser.UnitFile, unitsInfoMap map[string]*UnitInfo, i podman.add("volume", "create", "--ignore") + uid, ok := volume.Lookup(VolumeGroup, KeyUID) + if ok { + podman.add("--uid", uid) + } + + gid, ok := volume.Lookup(VolumeGroup, KeyGID) + if ok { + podman.add("--gid", gid) + } + driver, ok := volume.Lookup(VolumeGroup, KeyDriver) if ok { podman.add("--driver", driver) diff --git a/test/e2e/quadlet/volume-uid-gid.volume b/test/e2e/quadlet/volume-uid-gid.volume new file mode 100644 index 0000000000..8e6d3fa329 --- /dev/null +++ b/test/e2e/quadlet/volume-uid-gid.volume @@ -0,0 +1,6 @@ +## assert-last-key-contains Service ExecStart " --uid 1234 " +## assert-last-key-contains Service ExecStart " --gid 5678 " + +[Volume] +UID=1234 +GID=5678 diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index b45c4d7730..9ecc6be4ca 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -1012,6 +1012,7 @@ BOGUS=foo Entry("name.volume", "name.volume"), Entry("podmanargs.volume", "podmanargs.volume"), Entry("uid.volume", "uid.volume"), + Entry("volume-uid-gid.volume", "volume-uid-gid.volume"), Entry("image.volume", "image.volume"), Entry("Volume - global args", "globalargs.volume"), Entry("Volume - Containers Conf Modules", "containersconfmodule.volume"), diff --git a/test/system/252-quadlet.bats b/test/system/252-quadlet.bats index bbcf502c81..519a331986 100644 --- a/test/system/252-quadlet.bats +++ b/test/system/252-quadlet.bats @@ -405,6 +405,32 @@ EOF run_podman volume rm $volume_name } +@test "quadlet - volume - uid - gid" { + local quadlet_file=$PODMAN_TMPDIR/basic_$(safename).volume + cat > $quadlet_file <