mirror of
https://github.com/containers/podman.git
synced 2025-06-01 09:06:44 +08:00
quadlet: add UserNS
option key
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>
This commit is contained in:
@ -110,10 +110,6 @@ Valid options for `[Container]` are listed below:
|
|||||||
| PodmanArgs=--add-host foobar | --add-host foobar |
|
| PodmanArgs=--add-host foobar | --add-host foobar |
|
||||||
| PublishPort=true | --publish |
|
| PublishPort=true | --publish |
|
||||||
| ReadOnly=true | --read-only |
|
| 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 |
|
| RunInit=true | --init |
|
||||||
| SeccompProfile=/tmp/s.json | --security-opt seccomp=/tmp/s.json |
|
| SeccompProfile=/tmp/s.json | --security-opt seccomp=/tmp/s.json |
|
||||||
| SecurityLabelDisable=true | --security-opt label=disable |
|
| SecurityLabelDisable=true | --security-opt label=disable |
|
||||||
@ -123,6 +119,7 @@ Valid options for `[Container]` are listed below:
|
|||||||
| Timezone=local | --tz local |
|
| Timezone=local | --tz local |
|
||||||
| Tmpfs=/work | --tmpfs /work |
|
| Tmpfs=/work | --tmpfs /work |
|
||||||
| User=bin | --user bin |
|
| User=bin | --user bin |
|
||||||
|
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
||||||
| VolatileTmp=true | --tmpfs /tmp |
|
| VolatileTmp=true | --tmpfs /tmp |
|
||||||
| Volume=/source:/dest | --volume /source:/dest |
|
| Volume=/source:/dest | --volume /source:/dest |
|
||||||
|
|
||||||
@ -206,7 +203,7 @@ This key can be listed multiple times.
|
|||||||
### `Group=`
|
### `Group=`
|
||||||
|
|
||||||
The (numeric) gid to run as inside the container. This does not need to match the gid on the host,
|
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=`
|
### `HealthCmd=`
|
||||||
@ -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
|
**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`)
|
### `RunInit=` (default to `no`)
|
||||||
|
|
||||||
If enabled, the container will have a minimal init process inside the
|
If enabled, the container will have a minimal init process inside the
|
||||||
@ -465,7 +426,12 @@ The timezone to run the container in.
|
|||||||
### `User=`
|
### `User=`
|
||||||
|
|
||||||
The (numeric) uid to run as inside the container. This does not need to match the uid on the host,
|
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)
|
### `VolatileTmp=` (default to `no`, or `yes` if `ReadOnly` enabled)
|
||||||
|
|
||||||
@ -505,10 +471,7 @@ Valid options for `[Kube]` are listed below:
|
|||||||
| LogDriver=journald | --log-driver journald |
|
| LogDriver=journald | --log-driver journald |
|
||||||
| Network=host | --net host |
|
| Network=host | --net host |
|
||||||
| PublishPort=59-60 | --publish=59-60 |
|
| PublishPort=59-60 | --publish=59-60 |
|
||||||
| RemapGid=0:20000:400 | --gidmap 0:20000:400 |
|
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
||||||
| RemapUid=0:100000:2000 | --uidmap 0:100000:2000 |
|
|
||||||
| RemapUidSize=6000 | --userns auto:6000 |
|
|
||||||
| RemapUsers=auto | --userns auto |
|
|
||||||
| Yaml=/tmp/kube.yaml | podman kube play /tmp/kube.yaml |
|
| Yaml=/tmp/kube.yaml | podman kube play /tmp/kube.yaml |
|
||||||
|
|
||||||
Supported keys in the `[Kube]` section are:
|
Supported keys in the `[Kube]` section are:
|
||||||
@ -558,40 +521,10 @@ entry from the unit file will take precedence
|
|||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
### `RemapGid=`
|
### `UserNS=`
|
||||||
|
|
||||||
If `RemapUsers` is enabled, this specifies a gid mapping.
|
Set the user namespace mode for the container. This is equivalent to the Podman `--userns` option and
|
||||||
If `RemapUsers` is set to `keep-id` the value should be a single GID and should appear only once.
|
generally has the form `MODE[:OPTIONS,...]`.
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
### `Yaml=`
|
### `Yaml=`
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ const (
|
|||||||
KeyTmpfs = "Tmpfs"
|
KeyTmpfs = "Tmpfs"
|
||||||
KeyType = "Type"
|
KeyType = "Type"
|
||||||
KeyUser = "User"
|
KeyUser = "User"
|
||||||
|
KeyUserNS = "UserNS"
|
||||||
KeyVolatileTmp = "VolatileTmp"
|
KeyVolatileTmp = "VolatileTmp"
|
||||||
KeyVolume = "Volume"
|
KeyVolume = "Volume"
|
||||||
KeyYaml = "Yaml"
|
KeyYaml = "Yaml"
|
||||||
@ -156,6 +157,7 @@ var (
|
|||||||
KeyTmpfs: true,
|
KeyTmpfs: true,
|
||||||
KeyTimezone: true,
|
KeyTimezone: true,
|
||||||
KeyUser: true,
|
KeyUser: true,
|
||||||
|
KeyUserNS: true,
|
||||||
KeyVolatileTmp: true,
|
KeyVolatileTmp: true,
|
||||||
KeyVolume: true,
|
KeyVolume: true,
|
||||||
}
|
}
|
||||||
@ -195,6 +197,7 @@ var (
|
|||||||
KeyRemapUID: true,
|
KeyRemapUID: true,
|
||||||
KeyRemapUIDSize: true,
|
KeyRemapUIDSize: true,
|
||||||
KeyRemapUsers: true,
|
KeyRemapUsers: true,
|
||||||
|
KeyUserNS: true,
|
||||||
KeyYaml: true,
|
KeyYaml: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -476,6 +479,8 @@ func ConvertContainer(container *parser.UnitFile, isUser bool) (*parser.UnitFile
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleUserNS(container, ContainerGroup, podman)
|
||||||
|
|
||||||
tmpfsValues := container.LookupAll(ContainerGroup, KeyTmpfs)
|
tmpfsValues := container.LookupAll(ContainerGroup, KeyTmpfs)
|
||||||
for _, tmpfs := range tmpfsValues {
|
for _, tmpfs := range tmpfsValues {
|
||||||
if strings.Count(tmpfs, ":") > 1 {
|
if strings.Count(tmpfs, ":") > 1 {
|
||||||
@ -877,6 +882,8 @@ func ConvertKube(kube *parser.UnitFile, isUser bool) (*parser.UnitFile, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleUserNS(kube, KubeGroup, execStart)
|
||||||
|
|
||||||
addNetworks(kube, KubeGroup, service, execStart)
|
addNetworks(kube, KubeGroup, service, execStart)
|
||||||
|
|
||||||
configMaps := kube.LookupAllStrv(KubeGroup, KeyConfigMap)
|
configMaps := kube.LookupAllStrv(KubeGroup, KeyConfigMap)
|
||||||
@ -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 {
|
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)
|
uidMaps := unitFile.LookupAllStrv(groupName, KeyRemapUID)
|
||||||
gidMaps := unitFile.LookupAllStrv(groupName, KeyRemapGID)
|
gidMaps := unitFile.LookupAllStrv(groupName, KeyRemapGID)
|
||||||
remapUsers, _ := unitFile.LookupLast(groupName, KeyRemapUsers)
|
remapUsers, _ := unitFile.LookupLast(groupName, KeyRemapUsers)
|
||||||
@ -968,6 +980,12 @@ func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *Podman
|
|||||||
return nil
|
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) {
|
func addNetworks(quadletUnitFile *parser.UnitFile, groupName string, serviceUnitFile *parser.UnitFile, podman *PodmanCmdline) {
|
||||||
networks := quadletUnitFile.LookupAll(groupName, KeyNetwork)
|
networks := quadletUnitFile.LookupAll(groupName, KeyNetwork)
|
||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
|
@ -607,4 +607,22 @@ EOF
|
|||||||
service_cleanup $QUADLET_SERVICE_NAME failed
|
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
|
# vim: filetype=sh
|
||||||
|
Reference in New Issue
Block a user