Skip to content

Commit

Permalink
quadlet: add UserNS option key
Browse files Browse the repository at this point in the history
The `UserNS` key will replace the `RemapGid`, `RemapUid`, `RemapUidSize`
and `RemapUsers` options which are therefore marked as deprecated by
this commit.

Closes #17984

Signed-off-by: Cedric Staniewski <cedric@gmx.ca>
  • Loading branch information
xduugu committed Apr 7, 2023
1 parent 1946373 commit f6a5031
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 79 deletions.
91 changes: 12 additions & 79 deletions docs/source/markdown/podman-systemd.unit.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,6 @@ Valid options for `[Container]` are listed below:
| PodmanArgs=--add-host foobar | --add-host foobar |
| PublishPort=true | --publish |
| ReadOnly=true | --read-only |
| RemapGid=0:20000:400 | --gidmap 0:20000:400 |
| RemapUid=0:100000:2000 | --uidmap 0:100000:2000 |
| RemapUidSize=6000 | --userns auto:6000 |
| RemapUsers=auto | --userns auto |
| RunInit=true | --init |
| SeccompProfile=/tmp/s.json | --security-opt seccomp=/tmp/s.json |
| SecurityLabelDisable=true | --security-opt label=disable |
Expand All @@ -123,6 +119,7 @@ Valid options for `[Container]` are listed below:
| Timezone=local | --tz local |
| Tmpfs=/work | --tmpfs /work |
| User=bin | --user bin |
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
| VolatileTmp=true | --tmpfs /tmp |
| Volume=/source:/dest | --volume /source:/dest |

Expand Down Expand Up @@ -206,7 +203,7 @@ This key can be listed multiple times.
### `Group=`

The (numeric) gid to run as inside the container. This does not need to match the gid on the host,
which can be modified with `RemapUsers`, but if that is not specified, this gid is also used on the host.
which can be modified with `UsersNS`, but if that is not specified, this gid is also used on the host.


### `HealthCmd=`
Expand Down Expand Up @@ -384,42 +381,6 @@ If enabled, makes image read-only, with /var/tmp, /tmp and /run a tmpfs (unless

**NOTE:** Podman will automatically copy any content from the image onto the tmpfs

### `RemapGid=`

`RemapGid` key to force a particular host uid to be mapped to the container.

In `keep-id` mode, the value should be a single GID and should appear only once.
If no value is set, the running user is mapped to the same id in the container.
This is supported only on user systemd units.

If `RemapUsers` is enabled, this specifies a gid mapping of the form `container_gid:from_gid:amount`,
which will map `amount` number of gids on the host starting at `from_gid` into the container, starting
at `container_gid`.

### `RemapUid=`

If `RemapUsers` is enabled, this specifies a uid mapping.
If `RemapUsers` is set to `keep-id` the value should be a single UID and should appear only once.
Otherwise, the value takes the form `container_uid:from_uid:amount`,
which will map `amount` number of uids on the host starting at `from_uid` into the container, starting
at `container_uid`.

### `RemapUidSize=`

If `RemapUsers` is enabled and set to `auto`, this specifies the count of the ids to remap

### `RemapUsers=`

If this is set, then host user and group ids are remapped in the container. It currently
supports values: `auto`, `manual` and `keep-id`.

In `manual` mode, the `RemapUid` and `RemapGid` options can define an
exact mapping of uids from host to container. You must specify these.

In `auto` mode mode, the subuids and subgids allocated to the `containers` user is used to allocate
host uids/gids to use for the container. By default this will try to estimate a count of the ids
to remap, but `RemapUidSize` can be specified to use an explicit size. Use `RemapUid` and

### `RunInit=` (default to `no`)

If enabled, the container will have a minimal init process inside the
Expand Down Expand Up @@ -465,7 +426,12 @@ The timezone to run the container in.
### `User=`

The (numeric) uid to run as inside the container. This does not need to match the uid on the host,
which can be modified with `RemapUsers`, but if that is not specified, this uid is also used on the host.
which can be modified with `UserNS`, but if that is not specified, this uid is also used on the host.

### `UserNS=`

Set the user namespace mode for the container. This is equivalent to the Podman `--userns` option and
generally has the form `MODE[:OPTIONS,...]`.

### `VolatileTmp=` (default to `no`, or `yes` if `ReadOnly` enabled)

Expand Down Expand Up @@ -505,10 +471,7 @@ Valid options for `[Kube]` are listed below:
| LogDriver=journald | --log-driver journald |
| Network=host | --net host |
| PublishPort=59-60 | --publish=59-60 |
| RemapGid=0:20000:400 | --gidmap 0:20000:400 |
| RemapUid=0:100000:2000 | --uidmap 0:100000:2000 |
| RemapUidSize=6000 | --userns auto:6000 |
| RemapUsers=auto | --userns auto |
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
| Yaml=/tmp/kube.yaml | podman kube play /tmp/kube.yaml |

Supported keys in the `[Kube]` section are:
Expand Down Expand Up @@ -558,40 +521,10 @@ entry from the unit file will take precedence

This key can be listed multiple times.

### `RemapGid=`

If `RemapUsers` is enabled, this specifies a gid mapping.
If `RemapUsers` is set to `keep-id` the value should be a single GID and should appear only once.
Otherwise, the value takes the form `container_gid:from_gid:amount`,
which will map `amount` number of gids on the host starting at `from_gid` into the container, starting
at `container_gid`.

### `RemapUid=`

If `RemapUsers` is enabled, this specifies a uid mapping.
If `RemapUsers` is set to `keep-id` the value should be a single UID and should appear only once.
Otherwise, the value takes the form `container_uid:from_uid:amount`,
which will map `amount` number of uids on the host starting at `from_uid` into the container, starting
at `container_uid`.

### `RemapUidSize=`

If `RemapUsers` is enabled and set to `auto`, this specifies the count of the ids to remap.

### `RemapUsers=`

If this is set, then host user and group ids are remapped in the container. It currently
supports values: `auto`, and `keep-id`.

In `auto` mode mode, the subuids and subgids allocated to the `containers` user is used to allocate
host uids/gids to use for the container. By default this will try to estimate a count of the ids
to remap, but `RemapUidSize` can be specified to use an explicit size. Use `RemapUid` and
`RemapGid` key to force a particular host uid to be mapped to the container.
### `UserNS=`

In `keep-id` mode, if `RemapUid` or `RemapGid` are set the running user is mapped
to the corresponding ids in the container.
Otherwise, the user is mapped to the user's host machine ids in the container.
This is supported only on user systemd units.
Set the user namespace mode for the container. This is equivalent to the Podman `--userns` option and
generally has the form `MODE[:OPTIONS,...]`.

### `Yaml=`

Expand Down
18 changes: 18 additions & 0 deletions pkg/systemd/quadlet/quadlet.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const (
KeyTmpfs = "Tmpfs"
KeyType = "Type"
KeyUser = "User"
KeyUserNS = "UserNS"
KeyVolatileTmp = "VolatileTmp"
KeyVolume = "Volume"
KeyYaml = "Yaml"
Expand Down Expand Up @@ -156,6 +157,7 @@ var (
KeyTmpfs: true,
KeyTimezone: true,
KeyUser: true,
KeyUserNS: true,
KeyVolatileTmp: true,
KeyVolume: true,
}
Expand Down Expand Up @@ -195,6 +197,7 @@ var (
KeyRemapUID: true,
KeyRemapUIDSize: true,
KeyRemapUsers: true,
KeyUserNS: true,
KeyYaml: true,
}
)
Expand Down Expand Up @@ -476,6 +479,8 @@ func ConvertContainer(container *parser.UnitFile, isUser bool) (*parser.UnitFile
return nil, err
}

handleUserNS(container, ContainerGroup, podman)

tmpfsValues := container.LookupAll(ContainerGroup, KeyTmpfs)
for _, tmpfs := range tmpfsValues {
if strings.Count(tmpfs, ":") > 1 {
Expand Down Expand Up @@ -877,6 +882,8 @@ func ConvertKube(kube *parser.UnitFile, isUser bool) (*parser.UnitFile, error) {
return nil, err
}

handleUserNS(kube, KubeGroup, execStart)

addNetworks(kube, KubeGroup, service, execStart)

configMaps := kube.LookupAllStrv(KubeGroup, KeyConfigMap)
Expand Down Expand Up @@ -904,6 +911,11 @@ func ConvertKube(kube *parser.UnitFile, isUser bool) (*parser.UnitFile, error) {
}

func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline, isUser, supportManual bool) error {
// ignore Remap keys if UserNS is set
if userns, ok := unitFile.Lookup(groupName, KeyUserNS); ok && len(userns) > 0 {
return nil
}

uidMaps := unitFile.LookupAllStrv(groupName, KeyRemapUID)
gidMaps := unitFile.LookupAllStrv(groupName, KeyRemapGID)
remapUsers, _ := unitFile.LookupLast(groupName, KeyRemapUsers)
Expand Down Expand Up @@ -968,6 +980,12 @@ func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *Podman
return nil
}

func handleUserNS(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline) {
if userns, ok := unitFile.Lookup(groupName, KeyUserNS); ok && len(userns) > 0 {
podman.add("--userns", userns)
}
}

func addNetworks(quadletUnitFile *parser.UnitFile, groupName string, serviceUnitFile *parser.UnitFile, podman *PodmanCmdline) {
networks := quadletUnitFile.LookupAll(groupName, KeyNetwork)
for _, network := range networks {
Expand Down
18 changes: 18 additions & 0 deletions test/system/252-quadlet.bats
Original file line number Diff line number Diff line change
Expand Up @@ -607,4 +607,22 @@ EOF
service_cleanup $QUADLET_SERVICE_NAME failed
}

@test "quadlet - userns" {
local quadlet_file=$PODMAN_TMPDIR/basic_$(random_string).container
cat > $quadlet_file <<EOF
[Container]
Image=$IMAGE
Exec=top
UserNS=keep-id:uid=200,gid=210
EOF

run_quadlet "$quadlet_file"
service_setup $QUADLET_SERVICE_NAME

run_podman container inspect --format '{{.Config.CreateCommand}}' $QUADLET_CONTAINER_NAME
is "${output/* --userns keep-id:uid=200,gid=210 */found}" "found"

service_cleanup $QUADLET_SERVICE_NAME failed
}

# vim: filetype=sh

0 comments on commit f6a5031

Please sign in to comment.