Skip to content

Commit eb5bd4f

Browse files
committed
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 <[email protected]>
1 parent d0aec23 commit eb5bd4f

File tree

8 files changed

+88
-23
lines changed

8 files changed

+88
-23
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ RUN apt-get update && apt-get install -y \
2222
protobuf-c-compiler \
2323
protobuf-compiler \
2424
python-minimal \
25+
uidmap \
2526
--no-install-recommends \
2627
&& apt-get clean
2728

tests/integration/exec.bats

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ function teardown() {
100100
}
101101

102102
@test "runc exec --user" {
103-
# --user can't work in rootless containers
104-
requires root
103+
# --user can't work in rootless containers that don't have idmap.
104+
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
105105

106106
# run busybox detached
107107
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
@@ -110,5 +110,5 @@ function teardown() {
110110
runc exec --user 1000:1000 test_busybox id
111111
[ "$status" -eq 0 ]
112112

113-
[[ ${output} == "uid=1000 gid=1000" ]]
113+
[[ "${output}" == "uid=1000 gid=1000"* ]]
114114
}

tests/integration/helpers.bash

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,41 @@ function __runc() {
5858
"$RUNC" --log /proc/self/fd/2 --root "$ROOT" "$@"
5959
}
6060

61-
# Wrapper for runc spec.
61+
# Wrapper for runc spec, which takes only one argument (the bundle path).
6262
function runc_spec() {
63-
local args=""
63+
! [[ "$#" > 1 ]]
64+
65+
local args=()
66+
local bundle=""
6467

6568
if [ "$ROOTLESS" -ne 0 ]; then
66-
args+="--rootless"
69+
args+=("--rootless")
70+
fi
71+
if [ "$#" -ne 0 ]; then
72+
bundle="$1"
73+
args+=("--bundle" "$bundle")
6774
fi
6875

69-
runc spec $args "$@"
76+
runc spec "${args[@]}"
77+
78+
# Always add additional mappings if we have idmaps.
79+
if [[ "$ROOTLESS" -ne 0 ]] && [[ "$ROOTLESS_FEATURES" == *"idmap"* ]]; then
80+
runc_rootless_idmap "$bundle"
81+
fi
82+
}
83+
84+
# Shortcut to add additional uids and gids, based on the values set as part of
85+
# a rootless configuration.
86+
function runc_rootless_idmap() {
87+
bundle="${1:-.}"
88+
cat "$bundle/config.json" \
89+
| jq '.mounts |= map((select(.type == "devpts") | .options += ["gid=5"]) // .)' \
90+
| jq '.linux.uidMappings |= .+ [{"hostID": '"$ROOTLESS_UIDMAP_START"', "containerID": 1000, "size": '"$ROOTLESS_UIDMAP_LENGTH"'}]' \
91+
| jq '.linux.gidMappings |= .+ [{"hostID": '"$ROOTLESS_GIDMAP_START"', "containerID": 100, "size": 1}]' \
92+
| jq '.linux.gidMappings |= .+ [{"hostID": '"$(($ROOTLESS_GIDMAP_START+10))"', "containerID": 1, "size": 20}]' \
93+
| jq '.linux.gidMappings |= .+ [{"hostID": '"$(($ROOTLESS_GIDMAP_START+100))"', "containerID": 1000, "size": '"$(($ROOTLESS_GIDMAP_LENGTH-1000))"'}]' \
94+
>"$bundle/config.json.tmp"
95+
mv "$bundle/config.json"{.tmp,}
7096
}
7197

7298
# Fails the current test, providing the error given.
@@ -90,14 +116,19 @@ function requires() {
90116
skip "test requires ${var}"
91117
fi
92118
;;
119+
rootless_idmap)
120+
if [[ "$ROOTLESS_FEATURES" != *"idmap"* ]]; then
121+
skip "test requires ${var}"
122+
fi
123+
;;
93124
cgroups_kmem)
94125
if [ ! -e "$KMEM" ]; then
95-
skip "Test requires ${var}."
126+
skip "Test requires ${var}"
96127
fi
97128
;;
98129
cgroups_rt)
99130
if [ ! -e "$RT_PERIOD" ]; then
100-
skip "Test requires ${var}."
131+
skip "Test requires ${var}"
101132
fi
102133
;;
103134
*)

tests/integration/spec.bats

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function teardown() {
5151
[ ! -e "$HELLO_BUNDLE"/config.json ]
5252

5353
# test generation of spec does not return an error
54-
runc_spec --bundle "$HELLO_BUNDLE"
54+
runc_spec "$HELLO_BUNDLE"
5555
[ "$status" -eq 0 ]
5656

5757
# test generation of spec created our config.json (spec)

tests/integration/start_detached.bats

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ function teardown() {
2121
}
2222

2323
@test "runc run detached ({u,g}id != 0)" {
24-
# cannot start containers as another user in rootless setup
25-
requires root
24+
# cannot start containers as another user in rootless setup without idmap
25+
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
2626

2727
# replace "uid": 0 with "uid": 1000
2828
# and do a similar thing for gid.

tests/integration/start_hello.bats

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ function teardown() {
2121
}
2222

2323
@test "runc run ({u,g}id != 0)" {
24-
# cannot start containers as another user in rootless setup
25-
requires root
24+
# cannot start containers as another user in rootless setup without idmap
25+
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
2626

2727
# replace "uid": 0 with "uid": 1000
2828
# and do a similar thing for gid.

tests/integration/tty.bats

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ function teardown() {
2424
}
2525

2626
@test "runc run [tty owner]" {
27-
# tty chmod is not doable in rootless containers.
27+
# tty chmod is not doable in rootless containers without idmap.
2828
# TODO: this can be made as a change to the gid test.
29-
requires root
29+
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
3030

3131
# Replace sh script with stat.
3232
sed -i 's/"sh"/"sh", "-c", "stat -c %u:%g $(tty) | tr : \\\\\\\\n"/' config.json
@@ -40,8 +40,8 @@ function teardown() {
4040
}
4141

4242
@test "runc run [tty owner] ({u,g}id != 0)" {
43-
# tty chmod is not doable in rootless containers.
44-
requires root
43+
# tty chmod is not doable in rootless containers without idmap.
44+
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
4545

4646
# replace "uid": 0 with "uid": 1000
4747
# and do a similar thing for gid.
@@ -76,9 +76,9 @@ function teardown() {
7676
}
7777

7878
@test "runc exec [tty owner]" {
79-
# tty chmod is not doable in rootless containers.
79+
# tty chmod is not doable in rootless containers without idmap.
8080
# TODO: this can be made as a change to the gid test.
81-
requires root
81+
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
8282

8383
# run busybox detached
8484
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
@@ -95,8 +95,8 @@ function teardown() {
9595
}
9696

9797
@test "runc exec [tty owner] ({u,g}id != 0)" {
98-
# tty chmod is not doable in rootless containers.
99-
requires root
98+
# tty chmod is not doable in rootless containers without idmap.
99+
[[ "$ROOTLESS" -ne 0 ]] && requires rootless_idmap
100100

101101
# replace "uid": 0 with "uid": 1000
102102
# and do a similar thing for gid.

tests/rootless.sh

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,42 @@
1919
# a new feature, please match the existing style. Add an entry to $ALL_FEATURES,
2020
# and add an enable_* and disable_* hook.
2121

22-
ALL_FEATURES=()
22+
ALL_FEATURES=("idmap")
2323
ROOT="$(readlink -f "$(dirname "${BASH_SOURCE}")/..")"
2424

25+
# FEATURE: Opportunistic new{uid,gid}map support, allowing a rootless container
26+
# to be set up with the usage of helper setuid binaries.
27+
28+
function enable_idmap() {
29+
export ROOTLESS_UIDMAP_START=100000 ROOTLESS_UIDMAP_LENGTH=65536
30+
export ROOTLESS_GIDMAP_START=200000 ROOTLESS_GIDMAP_LENGTH=65536
31+
32+
# Set up sub{uid,gid} mappings.
33+
[ -e /etc/subuid.tmp ] && mv /etc/subuid{.tmp,}
34+
( grep -v '^rootless' /etc/subuid ; echo "rootless:$ROOTLESS_UIDMAP_START:$ROOTLESS_UIDMAP_LENGTH" ) > /etc/subuid.tmp
35+
mv /etc/subuid{.tmp,}
36+
[ -e /etc/subgid.tmp ] && mv /etc/subgid{.tmp,}
37+
( grep -v '^rootless' /etc/subgid ; echo "rootless:$ROOTLESS_GIDMAP_START:$ROOTLESS_GIDMAP_LENGTH" ) > /etc/subgid.tmp
38+
mv /etc/subgid{.tmp,}
39+
40+
# Reactivate new{uid,gid}map helpers if applicable.
41+
[ -e /usr/bin/unused-newuidmap ] && mv /usr/bin/{unused-,}newuidmap
42+
[ -e /usr/bin/unused-newgidmap ] && mv /usr/bin/{unused-,}newgidmap
43+
}
44+
45+
function disable_idmap() {
46+
export ROOTLESS_UIDMAP_START ROOTLESS_UIDMAP_LENGTH
47+
export ROOTLESS_GIDMAP_START ROOTLESS_GIDMAP_LENGTH
48+
49+
# Deactivate sub{uid,gid} mappings.
50+
[ -e /etc/subuid ] && mv /etc/subuid{,.tmp}
51+
[ -e /etc/subgid ] && mv /etc/subgid{,.tmp}
52+
53+
# Deactivate new{uid,gid}map helpers. setuid is preserved with mv(1).
54+
[ -e /usr/bin/newuidmap ] && mv /usr/bin/{,unused-}newuidmap
55+
[ -e /usr/bin/newgidmap ] && mv /usr/bin/{,unused-}newgidmap
56+
}
57+
2558
# Create a powerset of $ALL_FEATURES (the set of all subsets of $ALL_FEATURES).
2659
# We test all of the possible combinations (as long as we don't add too many
2760
# feature knobs this shouldn't take too long -- but the number of tested

0 commit comments

Comments
 (0)