tests: add tests for rootless multi-mapping configurations

Enable several previously disabled tests (for the idmap execution mode)
for rootless containers, in addition to making all tests use the
additional mappings. At the moment there's no strong need to add any
additional tests purely for rootless_idmap.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
Aleksa Sarai 2017-09-07 09:54:46 +10:00
parent d0aec23c7e
commit eb5bd4fa6a
No known key found for this signature in database
GPG Key ID: 9E18AA267DDB8DB4
8 changed files with 88 additions and 23 deletions

View File

@ -22,6 +22,7 @@ RUN apt-get update && apt-get install -y \
protobuf-c-compiler \
protobuf-compiler \
python-minimal \
uidmap \
--no-install-recommends \
&& apt-get clean

View File

@ -100,8 +100,8 @@ function teardown() {
}
@test "runc exec --user" {
# --user can't work in rootless containers
requires root
# --user can't work in rootless containers that don't have idmap.
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
@ -110,5 +110,5 @@ function teardown() {
runc exec --user 1000:1000 test_busybox id
[ "$status" -eq 0 ]
[[ ${output} == "uid=1000 gid=1000" ]]
[[ "${output}" == "uid=1000 gid=1000"* ]]
}

View File

@ -58,15 +58,41 @@ function __runc() {
"$RUNC" --log /proc/self/fd/2 --root "$ROOT" "$@"
}
# Wrapper for runc spec.
# Wrapper for runc spec, which takes only one argument (the bundle path).
function runc_spec() {
local args=""
! [[ "$#" > 1 ]]
local args=()
local bundle=""
if [ "$ROOTLESS" -ne 0 ]; then
args+="--rootless"
args+=("--rootless")
fi
if [ "$#" -ne 0 ]; then
bundle="$1"
args+=("--bundle" "$bundle")
fi
runc spec $args "$@"
runc spec "${args[@]}"
# Always add additional mappings if we have idmaps.
if [[ "$ROOTLESS" -ne 0 ]] && [[ "$ROOTLESS_FEATURES" == *"idmap"* ]]; then
runc_rootless_idmap "$bundle"
fi
}
# Shortcut to add additional uids and gids, based on the values set as part of
# a rootless configuration.
function runc_rootless_idmap() {
bundle="${1:-.}"
cat "$bundle/config.json" \
| jq '.mounts |= map((select(.type == "devpts") | .options += ["gid=5"]) // .)' \
| jq '.linux.uidMappings |= .+ [{"hostID": '"$ROOTLESS_UIDMAP_START"', "containerID": 1000, "size": '"$ROOTLESS_UIDMAP_LENGTH"'}]' \
| jq '.linux.gidMappings |= .+ [{"hostID": '"$ROOTLESS_GIDMAP_START"', "containerID": 100, "size": 1}]' \
| jq '.linux.gidMappings |= .+ [{"hostID": '"$(($ROOTLESS_GIDMAP_START+10))"', "containerID": 1, "size": 20}]' \
| jq '.linux.gidMappings |= .+ [{"hostID": '"$(($ROOTLESS_GIDMAP_START+100))"', "containerID": 1000, "size": '"$(($ROOTLESS_GIDMAP_LENGTH-1000))"'}]' \
>"$bundle/config.json.tmp"
mv "$bundle/config.json"{.tmp,}
}
# Fails the current test, providing the error given.
@ -90,14 +116,19 @@ function requires() {
skip "test requires ${var}"
fi
;;
rootless_idmap)
if [[ "$ROOTLESS_FEATURES" != *"idmap"* ]]; then
skip "test requires ${var}"
fi
;;
cgroups_kmem)
if [ ! -e "$KMEM" ]; then
skip "Test requires ${var}."
skip "Test requires ${var}"
fi
;;
cgroups_rt)
if [ ! -e "$RT_PERIOD" ]; then
skip "Test requires ${var}."
skip "Test requires ${var}"
fi
;;
*)

View File

@ -51,7 +51,7 @@ function teardown() {
[ ! -e "$HELLO_BUNDLE"/config.json ]
# test generation of spec does not return an error
runc_spec --bundle "$HELLO_BUNDLE"
runc_spec "$HELLO_BUNDLE"
[ "$status" -eq 0 ]
# test generation of spec created our config.json (spec)

View File

@ -21,8 +21,8 @@ function teardown() {
}
@test "runc run detached ({u,g}id != 0)" {
# cannot start containers as another user in rootless setup
requires root
# cannot start containers as another user in rootless setup without idmap
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.

View File

@ -21,8 +21,8 @@ function teardown() {
}
@test "runc run ({u,g}id != 0)" {
# cannot start containers as another user in rootless setup
requires root
# cannot start containers as another user in rootless setup without idmap
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.

View File

@ -24,9 +24,9 @@ function teardown() {
}
@test "runc run [tty owner]" {
# tty chmod is not doable in rootless containers.
# tty chmod is not doable in rootless containers without idmap.
# TODO: this can be made as a change to the gid test.
requires root
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
# Replace sh script with stat.
sed -i 's/"sh"/"sh", "-c", "stat -c %u:%g $(tty) | tr : \\\\\\\\n"/' config.json
@ -40,8 +40,8 @@ function teardown() {
}
@test "runc run [tty owner] ({u,g}id != 0)" {
# tty chmod is not doable in rootless containers.
requires root
# tty chmod is not doable in rootless containers without idmap.
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
@ -76,9 +76,9 @@ function teardown() {
}
@test "runc exec [tty owner]" {
# tty chmod is not doable in rootless containers.
# tty chmod is not doable in rootless containers without idmap.
# TODO: this can be made as a change to the gid test.
requires root
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
@ -95,8 +95,8 @@ function teardown() {
}
@test "runc exec [tty owner] ({u,g}id != 0)" {
# tty chmod is not doable in rootless containers.
requires root
# tty chmod is not doable in rootless containers without idmap.
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.

View File

@ -19,9 +19,42 @@
# a new feature, please match the existing style. Add an entry to $ALL_FEATURES,
# and add an enable_* and disable_* hook.
ALL_FEATURES=()
ALL_FEATURES=("idmap")
ROOT="$(readlink -f "$(dirname "${BASH_SOURCE}")/..")"
# FEATURE: Opportunistic new{uid,gid}map support, allowing a rootless container
# to be set up with the usage of helper setuid binaries.
function enable_idmap() {
export ROOTLESS_UIDMAP_START=100000 ROOTLESS_UIDMAP_LENGTH=65536
export ROOTLESS_GIDMAP_START=200000 ROOTLESS_GIDMAP_LENGTH=65536
# Set up sub{uid,gid} mappings.
[ -e /etc/subuid.tmp ] && mv /etc/subuid{.tmp,}
( grep -v '^rootless' /etc/subuid ; echo "rootless:$ROOTLESS_UIDMAP_START:$ROOTLESS_UIDMAP_LENGTH" ) > /etc/subuid.tmp
mv /etc/subuid{.tmp,}
[ -e /etc/subgid.tmp ] && mv /etc/subgid{.tmp,}
( grep -v '^rootless' /etc/subgid ; echo "rootless:$ROOTLESS_GIDMAP_START:$ROOTLESS_GIDMAP_LENGTH" ) > /etc/subgid.tmp
mv /etc/subgid{.tmp,}
# Reactivate new{uid,gid}map helpers if applicable.
[ -e /usr/bin/unused-newuidmap ] && mv /usr/bin/{unused-,}newuidmap
[ -e /usr/bin/unused-newgidmap ] && mv /usr/bin/{unused-,}newgidmap
}
function disable_idmap() {
export ROOTLESS_UIDMAP_START ROOTLESS_UIDMAP_LENGTH
export ROOTLESS_GIDMAP_START ROOTLESS_GIDMAP_LENGTH
# Deactivate sub{uid,gid} mappings.
[ -e /etc/subuid ] && mv /etc/subuid{,.tmp}
[ -e /etc/subgid ] && mv /etc/subgid{,.tmp}
# Deactivate new{uid,gid}map helpers. setuid is preserved with mv(1).
[ -e /usr/bin/newuidmap ] && mv /usr/bin/{,unused-}newuidmap
[ -e /usr/bin/newgidmap ] && mv /usr/bin/{,unused-}newgidmap
}
# Create a powerset of $ALL_FEATURES (the set of all subsets of $ALL_FEATURES).
# We test all of the possible combinations (as long as we don't add too many
# feature knobs this shouldn't take too long -- but the number of tested