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 |
|
||||
| Exec=/usr/bin/command | Command after image specification - /usr/bin/command |
|
||||
| ExposeHostPort=50-59 | --expose 50-59 |
|
||||
| GIDMap=0:10000:10 | --gidmap=0:10000:10 |
|
||||
| Group=1234 | --user UID:1234 |
|
||||
| GlobalArgs=--log-level=debug | --log-level=debug |
|
||||
| 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 |
|
||||
| SecurityLabelType=spc_t | --security-opt label=type:spc_t |
|
||||
| ShmSize=100m | --shm-size=100m |
|
||||
| SubGIDMap=gtest | --subgidname=gtest |
|
||||
| SubUIDMap=utest | --subuidname=utest |
|
||||
| Sysctl=name=value | --sysctl=name=value |
|
||||
| Timezone=local | --tz local |
|
||||
| Tmpfs=/work | --tmpfs /work |
|
||||
| UIDMap=0:10000:10 | --uidmap=0:10000:10 |
|
||||
| Ulimit=nofile:1000:10000 | --ulimit nofile:1000:10000 |
|
||||
| User=bin | --user bin |
|
||||
| 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.
|
||||
|
||||
### `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=`
|
||||
|
||||
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]`
|
||||
|
||||
### `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=`
|
||||
|
||||
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.
|
||||
|
||||
### `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 options. Sets the ulimits values inside of the container.
|
||||
|
@ -73,6 +73,7 @@ const (
|
||||
KeyExec = "Exec"
|
||||
KeyExitCodePropagation = "ExitCodePropagation"
|
||||
KeyExposeHostPort = "ExposeHostPort"
|
||||
KeyGIDMap = "GIDMap"
|
||||
KeyGlobalArgs = "GlobalArgs"
|
||||
KeyGroup = "Group"
|
||||
KeyHealthCmd = "HealthCmd"
|
||||
@ -132,11 +133,14 @@ const (
|
||||
KeySecurityLabelType = "SecurityLabelType"
|
||||
KeySetWorkingDirectory = "SetWorkingDirectory"
|
||||
KeyShmSize = "ShmSize"
|
||||
KeySubGIDMap = "SubGIDMap"
|
||||
KeySubUIDMap = "SubUIDMap"
|
||||
KeySysctl = "Sysctl"
|
||||
KeyTimezone = "Timezone"
|
||||
KeyTLSVerify = "TLSVerify"
|
||||
KeyTmpfs = "Tmpfs"
|
||||
KeyType = "Type"
|
||||
KeyUIDMap = "UIDMap"
|
||||
KeyUlimit = "Ulimit"
|
||||
KeyUnmask = "Unmask"
|
||||
KeyUser = "User"
|
||||
@ -169,6 +173,7 @@ var (
|
||||
KeyEnvironmentHost: true,
|
||||
KeyExec: true,
|
||||
KeyExposeHostPort: true,
|
||||
KeyGIDMap: true,
|
||||
KeyGlobalArgs: true,
|
||||
KeyGroup: true,
|
||||
KeyHealthCmd: true,
|
||||
@ -213,9 +218,12 @@ var (
|
||||
KeySecurityLabelNested: true,
|
||||
KeySecurityLabelType: true,
|
||||
KeyShmSize: true,
|
||||
KeySubGIDMap: true,
|
||||
KeySubUIDMap: true,
|
||||
KeySysctl: true,
|
||||
KeyTimezone: true,
|
||||
KeyTmpfs: true,
|
||||
KeyUIDMap: true,
|
||||
KeyUlimit: true,
|
||||
KeyUnmask: true,
|
||||
KeyUser: true,
|
||||
@ -625,12 +633,10 @@ func ConvertContainer(container *parser.UnitFile, names map[string]string, isUse
|
||||
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
|
||||
}
|
||||
|
||||
handleUserNS(container, ContainerGroup, podman)
|
||||
|
||||
tmpfsValues := container.LookupAll(ContainerGroup, KeyTmpfs)
|
||||
for _, tmpfs := range tmpfsValues {
|
||||
if strings.Count(tmpfs, ":") > 1 {
|
||||
@ -1091,12 +1097,10 @@ func ConvertKube(kube *parser.UnitFile, names map[string]string, isUser bool) (*
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
handleUserNS(kube, KubeGroup, execStart)
|
||||
|
||||
addNetworks(kube, KubeGroup, service, names, execStart)
|
||||
|
||||
updateMaps := kube.LookupAllStrv(KubeGroup, KeyAutoUpdate)
|
||||
@ -1245,12 +1249,50 @@ func handleUser(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdli
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline, isUser, supportManual bool) error {
|
||||
// ignore Remap keys if UserNS is set
|
||||
func handleUserMappings(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline, isUser, supportManual bool) error {
|
||||
mappingsDefined := false
|
||||
|
||||
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 handleUserRemap(unitFile, groupName, podman, isUser, supportManual)
|
||||
}
|
||||
|
||||
func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline, isUser, supportManual bool) error {
|
||||
uidMaps := unitFile.LookupAllStrv(groupName, KeyRemapUID)
|
||||
gidMaps := unitFile.LookupAllStrv(groupName, KeyRemapGID)
|
||||
remapUsers, _ := unitFile.LookupLast(groupName, KeyRemapUsers)
|
||||
@ -1315,12 +1357,6 @@ 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, names map[string]string, podman *PodmanCmdline) {
|
||||
networks := quadletUnitFile.LookupAll(groupName, KeyNetwork)
|
||||
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("health.container", "health.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("install.container", "install.container", 0, ""),
|
||||
Entry("ip.container", "ip.container", 0, ""),
|
||||
@ -726,10 +728,14 @@ BOGUS=foo
|
||||
Entry("selinux.container", "selinux.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("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("timezone.container", "timezone.container", 0, ""),
|
||||
Entry("unmask.container", "unmask.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("workingdir.container", "workingdir.container", 0, ""),
|
||||
Entry("Container - global args", "globalargs.container", 0, ""),
|
||||
|
Reference in New Issue
Block a user