mirror of
https://github.com/containers/podman.git
synced 2025-06-21 01:19:15 +08:00
Quadlet - add support for UID and GID Mapping
Support UIDMap, GIDMap, SubUIDMap and SubGIDMap If any of them are set disregard the deprecated Remap keys Add tests and man Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
This commit is contained in:
@ -159,6 +159,7 @@ Valid options for `[Container]` are listed below:
|
|||||||
| EnvironmentHost=true | --env-host |
|
| EnvironmentHost=true | --env-host |
|
||||||
| Exec=/usr/bin/command | Command after image specification - /usr/bin/command |
|
| Exec=/usr/bin/command | Command after image specification - /usr/bin/command |
|
||||||
| ExposeHostPort=50-59 | --expose 50-59 |
|
| ExposeHostPort=50-59 | --expose 50-59 |
|
||||||
|
| GIDMap=0:10000:10 | --gidmap=0:10000:10 |
|
||||||
| Group=1234 | --user UID:1234 |
|
| Group=1234 | --user UID:1234 |
|
||||||
| GlobalArgs=--log-level=debug | --log-level=debug |
|
| GlobalArgs=--log-level=debug | --log-level=debug |
|
||||||
| HealthCmd="/usr/bin/command" | --health-cmd="/usr/bin/command" |
|
| HealthCmd="/usr/bin/command" | --health-cmd="/usr/bin/command" |
|
||||||
@ -197,9 +198,12 @@ Valid options for `[Container]` are listed below:
|
|||||||
| SecurityLabelNested=true | --security-opt label=nested |
|
| SecurityLabelNested=true | --security-opt label=nested |
|
||||||
| SecurityLabelType=spc_t | --security-opt label=type:spc_t |
|
| SecurityLabelType=spc_t | --security-opt label=type:spc_t |
|
||||||
| ShmSize=100m | --shm-size=100m |
|
| ShmSize=100m | --shm-size=100m |
|
||||||
|
| SubGIDMap=gtest | --subgidname=gtest |
|
||||||
|
| SubUIDMap=utest | --subuidname=utest |
|
||||||
| Sysctl=name=value | --sysctl=name=value |
|
| Sysctl=name=value | --sysctl=name=value |
|
||||||
| Timezone=local | --tz local |
|
| Timezone=local | --tz local |
|
||||||
| Tmpfs=/work | --tmpfs /work |
|
| Tmpfs=/work | --tmpfs /work |
|
||||||
|
| UIDMap=0:10000:10 | --uidmap=0:10000:10 |
|
||||||
| Ulimit=nofile:1000:10000 | --ulimit nofile:1000:10000 |
|
| Ulimit=nofile:1000:10000 | --ulimit nofile:1000:10000 |
|
||||||
| User=bin | --user bin |
|
| User=bin | --user bin |
|
||||||
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
||||||
@ -315,6 +319,13 @@ to the Podman `--expose` option.
|
|||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
|
### `GIDMap=`
|
||||||
|
|
||||||
|
Run the container in a new user namespace using the supplied GID mapping.
|
||||||
|
Equivalent to the Podman `--gidmap` option.
|
||||||
|
|
||||||
|
This key can be listed multiple times.
|
||||||
|
|
||||||
### `GlobalArgs=`
|
### `GlobalArgs=`
|
||||||
|
|
||||||
This key contains a list of arguments passed directly between `podman` and `run`
|
This key contains a list of arguments passed directly between `podman` and `run`
|
||||||
@ -569,6 +580,16 @@ Size of /dev/shm.
|
|||||||
|
|
||||||
This is equivalent to the Podman `--shm-size` option and generally has the form `number[unit]`
|
This is equivalent to the Podman `--shm-size` option and generally has the form `number[unit]`
|
||||||
|
|
||||||
|
### `SubGIDMap=`
|
||||||
|
|
||||||
|
Run the container in a new user namespace using the map with name in the /etc/subgid file.
|
||||||
|
Equivalent to the Podman `--subgidname` option.
|
||||||
|
|
||||||
|
### `SubUIDMap=`
|
||||||
|
|
||||||
|
Run the container in a new user namespace using the map with name in the /etc/subuid file.
|
||||||
|
Equivalent to the Podman `--subuidname` option.
|
||||||
|
|
||||||
### `Sysctl=`
|
### `Sysctl=`
|
||||||
|
|
||||||
Configures namespaced kernel parameters for the container. The format is `Sysctl=name=value`.
|
Configures namespaced kernel parameters for the container. The format is `Sysctl=name=value`.
|
||||||
@ -591,6 +612,13 @@ This key can be listed multiple times.
|
|||||||
|
|
||||||
The timezone to run the container in.
|
The timezone to run the container in.
|
||||||
|
|
||||||
|
### `UIDMap=`
|
||||||
|
|
||||||
|
Run the container in a new user namespace using the supplied UID mapping.
|
||||||
|
Equivalent to the Podman `--uidmap` option.
|
||||||
|
|
||||||
|
This key can be listed multiple times.
|
||||||
|
|
||||||
### `Ulimit=`
|
### `Ulimit=`
|
||||||
|
|
||||||
Ulimit options. Sets the ulimits values inside of the container.
|
Ulimit options. Sets the ulimits values inside of the container.
|
||||||
|
@ -73,6 +73,7 @@ const (
|
|||||||
KeyExec = "Exec"
|
KeyExec = "Exec"
|
||||||
KeyExitCodePropagation = "ExitCodePropagation"
|
KeyExitCodePropagation = "ExitCodePropagation"
|
||||||
KeyExposeHostPort = "ExposeHostPort"
|
KeyExposeHostPort = "ExposeHostPort"
|
||||||
|
KeyGIDMap = "GIDMap"
|
||||||
KeyGlobalArgs = "GlobalArgs"
|
KeyGlobalArgs = "GlobalArgs"
|
||||||
KeyGroup = "Group"
|
KeyGroup = "Group"
|
||||||
KeyHealthCmd = "HealthCmd"
|
KeyHealthCmd = "HealthCmd"
|
||||||
@ -132,11 +133,14 @@ const (
|
|||||||
KeySecurityLabelType = "SecurityLabelType"
|
KeySecurityLabelType = "SecurityLabelType"
|
||||||
KeySetWorkingDirectory = "SetWorkingDirectory"
|
KeySetWorkingDirectory = "SetWorkingDirectory"
|
||||||
KeyShmSize = "ShmSize"
|
KeyShmSize = "ShmSize"
|
||||||
|
KeySubGIDMap = "SubGIDMap"
|
||||||
|
KeySubUIDMap = "SubUIDMap"
|
||||||
KeySysctl = "Sysctl"
|
KeySysctl = "Sysctl"
|
||||||
KeyTimezone = "Timezone"
|
KeyTimezone = "Timezone"
|
||||||
KeyTLSVerify = "TLSVerify"
|
KeyTLSVerify = "TLSVerify"
|
||||||
KeyTmpfs = "Tmpfs"
|
KeyTmpfs = "Tmpfs"
|
||||||
KeyType = "Type"
|
KeyType = "Type"
|
||||||
|
KeyUIDMap = "UIDMap"
|
||||||
KeyUlimit = "Ulimit"
|
KeyUlimit = "Ulimit"
|
||||||
KeyUnmask = "Unmask"
|
KeyUnmask = "Unmask"
|
||||||
KeyUser = "User"
|
KeyUser = "User"
|
||||||
@ -169,6 +173,7 @@ var (
|
|||||||
KeyEnvironmentHost: true,
|
KeyEnvironmentHost: true,
|
||||||
KeyExec: true,
|
KeyExec: true,
|
||||||
KeyExposeHostPort: true,
|
KeyExposeHostPort: true,
|
||||||
|
KeyGIDMap: true,
|
||||||
KeyGlobalArgs: true,
|
KeyGlobalArgs: true,
|
||||||
KeyGroup: true,
|
KeyGroup: true,
|
||||||
KeyHealthCmd: true,
|
KeyHealthCmd: true,
|
||||||
@ -213,9 +218,12 @@ var (
|
|||||||
KeySecurityLabelNested: true,
|
KeySecurityLabelNested: true,
|
||||||
KeySecurityLabelType: true,
|
KeySecurityLabelType: true,
|
||||||
KeyShmSize: true,
|
KeyShmSize: true,
|
||||||
|
KeySubGIDMap: true,
|
||||||
|
KeySubUIDMap: true,
|
||||||
KeySysctl: true,
|
KeySysctl: true,
|
||||||
KeyTimezone: true,
|
KeyTimezone: true,
|
||||||
KeyTmpfs: true,
|
KeyTmpfs: true,
|
||||||
|
KeyUIDMap: true,
|
||||||
KeyUlimit: true,
|
KeyUlimit: true,
|
||||||
KeyUnmask: true,
|
KeyUnmask: true,
|
||||||
KeyUser: true,
|
KeyUser: true,
|
||||||
@ -625,12 +633,10 @@ func ConvertContainer(container *parser.UnitFile, names map[string]string, isUse
|
|||||||
podman.addf("-w=%s", workdir)
|
podman.addf("-w=%s", workdir)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := handleUserRemap(container, ContainerGroup, podman, isUser, true); err != nil {
|
if err := handleUserMappings(container, ContainerGroup, podman, isUser, true); err != nil {
|
||||||
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 {
|
||||||
@ -1091,12 +1097,10 @@ func ConvertKube(kube *parser.UnitFile, names map[string]string, isUser bool) (*
|
|||||||
|
|
||||||
handleLogDriver(kube, KubeGroup, execStart)
|
handleLogDriver(kube, KubeGroup, execStart)
|
||||||
|
|
||||||
if err := handleUserRemap(kube, KubeGroup, execStart, isUser, false); err != nil {
|
if err := handleUserMappings(kube, KubeGroup, execStart, isUser, false); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUserNS(kube, KubeGroup, execStart)
|
|
||||||
|
|
||||||
addNetworks(kube, KubeGroup, service, names, execStart)
|
addNetworks(kube, KubeGroup, service, names, execStart)
|
||||||
|
|
||||||
updateMaps := kube.LookupAllStrv(KubeGroup, KeyAutoUpdate)
|
updateMaps := kube.LookupAllStrv(KubeGroup, KeyAutoUpdate)
|
||||||
@ -1245,12 +1249,50 @@ func handleUser(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdli
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline, isUser, supportManual bool) error {
|
func handleUserMappings(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline, isUser, supportManual bool) error {
|
||||||
// ignore Remap keys if UserNS is set
|
mappingsDefined := false
|
||||||
|
|
||||||
if userns, ok := unitFile.Lookup(groupName, KeyUserNS); ok && len(userns) > 0 {
|
if userns, ok := unitFile.Lookup(groupName, KeyUserNS); ok && len(userns) > 0 {
|
||||||
|
podman.add("--userns", userns)
|
||||||
|
mappingsDefined = true
|
||||||
|
}
|
||||||
|
|
||||||
|
uidMaps := unitFile.LookupAllStrv(groupName, KeyUIDMap)
|
||||||
|
mappingsDefined = mappingsDefined || len(uidMaps) > 0
|
||||||
|
for _, uidMap := range uidMaps {
|
||||||
|
podman.addf("--uidmap=%s", uidMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
gidMaps := unitFile.LookupAllStrv(groupName, KeyGIDMap)
|
||||||
|
mappingsDefined = mappingsDefined || len(gidMaps) > 0
|
||||||
|
for _, gidMap := range gidMaps {
|
||||||
|
podman.addf("--gidmap=%s", gidMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
if subUIDMap, ok := unitFile.Lookup(groupName, KeySubUIDMap); ok && len(subUIDMap) > 0 {
|
||||||
|
podman.add("--subuidname", subUIDMap)
|
||||||
|
mappingsDefined = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if subGIDMap, ok := unitFile.Lookup(groupName, KeySubGIDMap); ok && len(subGIDMap) > 0 {
|
||||||
|
podman.add("--subgidname", subGIDMap)
|
||||||
|
mappingsDefined = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if mappingsDefined {
|
||||||
|
_, hasRemapUID := unitFile.Lookup(groupName, KeyRemapUID)
|
||||||
|
_, hasRemapGID := unitFile.Lookup(groupName, KeyRemapGID)
|
||||||
|
_, RemapUsers := unitFile.LookupLast(groupName, KeyRemapUsers)
|
||||||
|
if hasRemapUID || hasRemapGID || RemapUsers {
|
||||||
|
return fmt.Errorf("deprecated Remap keys are set along with explicit mapping keys")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return handleUserRemap(unitFile, groupName, podman, isUser, supportManual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline, isUser, supportManual bool) error {
|
||||||
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)
|
||||||
@ -1315,12 +1357,6 @@ 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, names map[string]string, podman *PodmanCmdline) {
|
func addNetworks(quadletUnitFile *parser.UnitFile, groupName string, serviceUnitFile *parser.UnitFile, names map[string]string, podman *PodmanCmdline) {
|
||||||
networks := quadletUnitFile.LookupAll(groupName, KeyNetwork)
|
networks := quadletUnitFile.LookupAll(groupName, KeyNetwork)
|
||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
|
10
test/e2e/quadlet/idmapping-with-remap.container
Normal file
10
test/e2e/quadlet/idmapping-with-remap.container
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
## assert-failed
|
||||||
|
## assert-stderr-contains "deprecated Remap keys are set along with explicit mapping keys"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
UIDMap=0:10000:10
|
||||||
|
UIDMap=10:20000:10
|
||||||
|
GIDMap=0:10000:10
|
||||||
|
GIDMap=10:20000:10
|
||||||
|
RemapUsers=auto
|
11
test/e2e/quadlet/idmapping.container
Normal file
11
test/e2e/quadlet/idmapping.container
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
## assert-podman-args "--uidmap=0:10000:10"
|
||||||
|
## assert-podman-args "--uidmap=10:20000:10"
|
||||||
|
## assert-podman-args "--gidmap=0:10000:10"
|
||||||
|
## assert-podman-args "--gidmap=10:20000:10"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
UIDMap=0:10000:10
|
||||||
|
UIDMap=10:20000:10
|
||||||
|
GIDMap=0:10000:10
|
||||||
|
GIDMap=10:20000:10
|
8
test/e2e/quadlet/subidmapping-with-remap.container
Normal file
8
test/e2e/quadlet/subidmapping-with-remap.container
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
## assert-failed
|
||||||
|
## assert-stderr-contains "deprecated Remap keys are set along with explicit mapping keys"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
SubUIDMap=utest
|
||||||
|
SubGIDMap=gtest
|
||||||
|
RemapUsers=auto
|
7
test/e2e/quadlet/subidmapping.container
Normal file
7
test/e2e/quadlet/subidmapping.container
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
## assert-podman-args "--subuidname" "utest"
|
||||||
|
## assert-podman-args "--subgidname" "gtest"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
SubUIDMap=utest
|
||||||
|
SubGIDMap=gtest
|
7
test/e2e/quadlet/userns-with-remap.container
Normal file
7
test/e2e/quadlet/userns-with-remap.container
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
## assert-failed
|
||||||
|
## assert-stderr-contains "deprecated Remap keys are set along with explicit mapping keys"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
RemapUsers=auto
|
||||||
|
UserNS=keep-id
|
5
test/e2e/quadlet/userns.container
Normal file
5
test/e2e/quadlet/userns.container
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## assert-podman-args "--userns" "keep-id"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
UserNS=keep-id
|
@ -690,6 +690,8 @@ BOGUS=foo
|
|||||||
Entry("exec.container", "exec.container", 0, ""),
|
Entry("exec.container", "exec.container", 0, ""),
|
||||||
Entry("health.container", "health.container", 0, ""),
|
Entry("health.container", "health.container", 0, ""),
|
||||||
Entry("hostname.container", "hostname.container", 0, ""),
|
Entry("hostname.container", "hostname.container", 0, ""),
|
||||||
|
Entry("idmapping.container", "idmapping.container", 0, ""),
|
||||||
|
Entry("idmapping-with-remap.container", "idmapping-with-remap.container", 1, "converting \"idmapping-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
|
||||||
Entry("image.container", "image.container", 0, ""),
|
Entry("image.container", "image.container", 0, ""),
|
||||||
Entry("install.container", "install.container", 0, ""),
|
Entry("install.container", "install.container", 0, ""),
|
||||||
Entry("ip.container", "ip.container", 0, ""),
|
Entry("ip.container", "ip.container", 0, ""),
|
||||||
@ -726,10 +728,14 @@ BOGUS=foo
|
|||||||
Entry("selinux.container", "selinux.container", 0, ""),
|
Entry("selinux.container", "selinux.container", 0, ""),
|
||||||
Entry("shmsize.container", "shmsize.container", 0, ""),
|
Entry("shmsize.container", "shmsize.container", 0, ""),
|
||||||
Entry("shortname.container", "shortname.container", 0, "Warning: shortname.container specifies the image \"shortname\" which not a fully qualified image name. This is not ideal for performance and security reasons. See the podman-pull manpage discussion of short-name-aliases.conf for details."),
|
Entry("shortname.container", "shortname.container", 0, "Warning: shortname.container specifies the image \"shortname\" which not a fully qualified image name. This is not ideal for performance and security reasons. See the podman-pull manpage discussion of short-name-aliases.conf for details."),
|
||||||
|
Entry("subidmapping.container", "subidmapping.container", 0, ""),
|
||||||
|
Entry("subidmapping-with-remap.container", "subidmapping-with-remap.container", 1, "converting \"subidmapping-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
|
||||||
Entry("sysctl.container", "sysctl.container", 0, ""),
|
Entry("sysctl.container", "sysctl.container", 0, ""),
|
||||||
Entry("timezone.container", "timezone.container", 0, ""),
|
Entry("timezone.container", "timezone.container", 0, ""),
|
||||||
Entry("unmask.container", "unmask.container", 0, ""),
|
Entry("unmask.container", "unmask.container", 0, ""),
|
||||||
Entry("user.container", "user.container", 0, ""),
|
Entry("user.container", "user.container", 0, ""),
|
||||||
|
Entry("userns.container", "userns.container", 0, ""),
|
||||||
|
Entry("userns-with-remap.container", "userns-with-remap.container", 1, "converting \"userns-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
|
||||||
Entry("volume.container", "volume.container", 0, ""),
|
Entry("volume.container", "volume.container", 0, ""),
|
||||||
Entry("workingdir.container", "workingdir.container", 0, ""),
|
Entry("workingdir.container", "workingdir.container", 0, ""),
|
||||||
Entry("Container - global args", "globalargs.container", 0, ""),
|
Entry("Container - global args", "globalargs.container", 0, ""),
|
||||||
|
Reference in New Issue
Block a user