Skip to content

Commit

Permalink
tests: add tests for rootless multi-mapping configurations
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
cyphar committed Sep 9, 2017
1 parent d0aec23 commit eb5bd4f
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 23 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions tests/integration/exec.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"* ]]
}
43 changes: 37 additions & 6 deletions tests/integration/helpers.bash
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
;;
*)
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/spec.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/start_detached.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/start_hello.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
16 changes: 8 additions & 8 deletions tests/integration/tty.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down
35 changes: 34 additions & 1 deletion tests/rootless.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit eb5bd4f

Please sign in to comment.