Skip to content

Commit 6fa8d06

Browse files
committed
integration: add mega-test for joining namespaces
Given we've had several bugs in this behaviour that have now been fixed, add an integration test that makes sure that you can start a container that joins all of the namespaces of a second container. The only namespace we do not join is the mount namespace, because joining a namespace that has been pivot_root'd leads to a bunch of errors. In principle, removing everything from config.json that requires a mount _should_ work, but the root.path configuration is mandatory and we cannot just ignore setting up the rootfs in the namespace joining scenario (if the user has configured a different rootfs, we need to use it or error out, and there's no reasonable way of checking if if the rootfs paths are the same that doesn't result in spaghetti logic). Signed-off-by: Aleksa Sarai <[email protected]>
1 parent e6fb7fe commit 6fa8d06

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

tests/integration/run.bats

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,73 @@ function teardown() {
160160
[[ "$output" = *"Hello World"* ]]
161161
[[ "$output" = *"runc-dmz: using /proc/self/exe clone"* ]]
162162
}
163+
164+
@test "runc run [joining existing container namespaces]" {
165+
requires timens
166+
167+
# Create a detached container with the namespaces we want. We notably want
168+
# to include both userns and timens, which require config-related
169+
# configuration.
170+
if [ $EUID -eq 0 ]; then
171+
update_config '.linux.namespaces += [{"type": "user"}]
172+
| .linux.uidMappings += [{"containerID": 0, "hostID": 100000, "size": 100}]
173+
| .linux.gidMappings += [{"containerID": 0, "hostID": 200000, "size": 200}]'
174+
mkdir -p rootfs/{proc,sys,tmp}
175+
fi
176+
update_config '.linux.namespaces += [{"type": "time"}]
177+
| .linux.timeOffsets = {
178+
"monotonic": { "secs": 7881, "nanosecs": 2718281 },
179+
"boottime": { "secs": 1337, "nanosecs": 3141519 }
180+
}'
181+
update_config '.process.args = ["sleep", "infinity"]'
182+
183+
runc run -d --console-socket "$CONSOLE_SOCKET" target_ctr
184+
[ "$status" -eq 0 ]
185+
186+
# Modify our container's configuration such that it is just going to
187+
# inherit all of the namespaces of the target container.
188+
#
189+
# NOTE: We cannot join the mount namespace of another container because of
190+
# some quirks of the runtime-spec. In particular, we MUST pivot_root into
191+
# root.path and root.path MUST be set in the config, so runc cannot just
192+
# ignore root.path when joining namespaces (and root.path doesn't exist
193+
# inside root.path, for obvious reasons).
194+
#
195+
# We could hack around this (create a copy of the rootfs inside the rootfs,
196+
# or use a simpler mount namespace target), but those wouldn't be similar
197+
# tests to the other namespace joining tests.
198+
target_pid="$(__runc state target_ctr | jq .pid)"
199+
update_config '.linux.namespaces |= map_values(.path = if .type == "mount" then "" else "/proc/'"$target_pid"'/ns/" + ({"network": "net", "mount": "mnt"}[.type] // .type) end)'
200+
# Remove the userns and timens configuration (they cannot be changed).
201+
update_config '.linux |= (del(.uidMappings) | del(.gidMappings) | del(.timeOffsets))'
202+
203+
runc run -d --console-socket "$CONSOLE_SOCKET" attached_ctr
204+
[ "$status" -eq 0 ]
205+
206+
# Make sure there are two sleep processes in our container.
207+
runc exec attached_ctr ps aux
208+
[ "$status" -eq 0 ]
209+
run -0 grep "sleep infinity" <<<"$output"
210+
[ "${#lines[@]}" -eq 2 ]
211+
212+
# ... that the userns mappings are the same...
213+
runc exec attached_ctr cat /proc/self/uid_map
214+
[ "$status" -eq 0 ]
215+
if [ $EUID -eq 0 ]; then
216+
grep -E '^\s+0\s+100000\s+100$' <<<"$output"
217+
else
218+
grep -E '^\s+0\s+'$EUID'\s+1$' <<<"$output"
219+
fi
220+
runc exec attached_ctr cat /proc/self/gid_map
221+
[ "$status" -eq 0 ]
222+
if [ $EUID -eq 0 ]; then
223+
grep -E '^\s+0\s+200000\s+200$' <<<"$output"
224+
else
225+
grep -E '^\s+0\s+'$EUID'\s+1$' <<<"$output"
226+
fi
227+
228+
# ... as well as the timens offsets.
229+
runc exec attached_ctr cat /proc/self/timens_offsets
230+
grep -E '^monotonic\s+7881\s+2718281$' <<<"$output"
231+
grep -E '^boottime\s+1337\s+3141519$' <<<"$output"
232+
}

0 commit comments

Comments
 (0)