+++ /dev/null
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-set -eu
-set -o pipefail
-
-root="${1:?Usage: $0 container-root}"
-mkdir -p "$root"
-mkdir -p "$root/usr/bin"
-
-# On openSUSE the static linked version of busybox is named "busybox-static".
-busybox="$(type -P busybox-static || type -P busybox)"
-cp "$busybox" "$root/usr/bin/busybox"
-
-mkdir "$root/var"
-mkdir -p "$root/usr/lib"
-touch "$root/usr/lib/os-release"
-
-ln -s busybox "$root/usr/bin/cat"
-ln -s busybox "$root/usr/bin/hostname"
-ln -s busybox "$root/usr/bin/ip"
-ln -s busybox "$root/usr/bin/md5sum"
-ln -s busybox "$root/usr/bin/mountpoint"
-ln -s busybox "$root/usr/bin/ps"
-ln -s busybox "$root/usr/bin/seq"
-ln -s busybox "$root/usr/bin/sh"
-ln -s busybox "$root/usr/bin/sleep"
-ln -s busybox "$root/usr/bin/stat"
-ln -s busybox "$root/usr/bin/test"
-ln -s busybox "$root/usr/bin/touch"
-ln -s busybox "$root/usr/bin/tr"
-ln -s busybox "$root/usr/bin/true"
-ln -s busybox "$root/usr/bin/usleep"
-
-# Mock the bare minimum of getent to make systemd-nspawn --user= "work"
-cat >"$root/usr/bin/getent" <<\EOF
-#!/bin/sh
-
-if [[ $# - eq 0 ]]; then
- :
-elif [[ $1 == passwd ]]; then
- echo "testuser:x:1000:1000:testuser:/:/bin/sh"
-elif [[ $1 == initgroups ]]; then
- echo "testuser"
-fi
-EOF
-chmod +x "$root/usr/bin/getent"
-
-mkdir -p "$root/usr/sbin"
-cat >"$root/usr/sbin/init" <<\EOF
-#!/bin/sh
-
-printf "ps aufx:\n"
-ps aufx
-
-printf "/proc/1/cmdline:\n"
-printf "%s\n\n" "$(tr '\0' ' ' </proc/1/cmdline)"
-
-printf "/proc/1/environ:\n"
-printf "%s\n\n" "$(tr '\0' '\n' </proc/1/environ)"
-
-printf "/proc/1/mountinfo:\n"
-cat /proc/self/mountinfo
-printf "\n"
-
-printf "/proc/1/cgroup:\n"
-printf "%s\n\n" "$(cat /proc/1/cgroup)"
-
-printf "/proc/1/uid_map:\n"
-printf "%s\n\n" "$(cat /proc/1/uid_map)"
-
-printf "/proc/1/setgroups:\n"
-printf "%s\n\n" "$(cat /proc/1/setgroups)"
-
-printf "/proc/1/gid_map:\n"
-printf "%s\n\n" "$(cat /proc/1/gid_map)"
-
-printf "ip link:\n"
-ip link
-EOF
-chmod +x "$root/usr/sbin/init"
-
-ln -srf "$root/usr/bin" "$root/bin"
-ln -srf "$root/usr/sbin" "$root/sbin"
-ln -srf "$root/usr/lib" "$root/lib"
set -eux
set -o pipefail
-export PAGER=
+# shellcheck source=test/units/util.sh
+. "$(dirname "$0")"/util.sh
-CREATE_BB_CONTAINER="/usr/lib/systemd/tests/testdata/create-busybox-container"
+export PAGER=
at_exit() {
set +e
# Create a couple of containers we can refer to in tests
for i in {0..4}; do
- "$CREATE_BB_CONTAINER" "/var/lib/machines/container$i"
+ create_dummy_container "/var/lib/machines/container$i"
machinectl start "container$i"
done
# Create one "long running" container with some basic signal handling
-"$CREATE_BB_CONTAINER" /var/lib/machines/long-running
+create_dummy_container /var/lib/machines/long-running
cat >/var/lib/machines/long-running/sbin/init <<\EOF
-#!/bin/sh -x
-#
+#!/usr/bin/bash -x
+
PID=0
-# sh doesn't recognize RTMIN+4, so we have to use the signal number directly
-trap "touch /poweroff" 38
+trap "touch /poweroff" RTMIN+4
trap "touch /reboot" INT
trap "touch /trap" TRAP
trap 'kill $PID' EXIT
test ! -L /etc/systemd/system/machines.target.wants/systemd-nspawn@long-running.service
machinectl disable long-running long-running long-running container1
-[[ "$(machinectl shell testuser@ /bin/sh -c 'echo -ne $FOO')" == "" ]]
-[[ "$(machinectl shell --setenv=FOO=bar testuser@ /bin/sh -c 'echo -ne $FOO')" == "bar" ]]
+[[ "$(machinectl shell testuser@ /usr/bin/bash -c 'echo -ne $FOO')" == "" ]]
+[[ "$(machinectl shell --setenv=FOO=bar testuser@ /usr/bin/bash -c 'echo -ne $FOO')" == "bar" ]]
[[ "$(machinectl show --property=State --value long-running)" == "running" ]]
# Equivalent to machinectl kill --signal=SIGRTMIN+4 --kill-whom=leader
rm -f /var/lib/machines/long-running/poweroff
machinectl poweroff long-running
-timeout 10 sh -c "while ! test -e /var/lib/machines/long-running/poweroff; do sleep .5; done"
+timeout 10 bash -c "while ! test -e /var/lib/machines/long-running/poweroff; do sleep .5; done"
machinectl poweroff long-running long-running long-running
# Equivalent to machinectl kill --signal=SIGINT --kill-whom=leader
rm -f /var/lib/machines/long-running/reboot
machinectl reboot long-running
-timeout 10 sh -c "while ! test -e /var/lib/machines/long-running/reboot; do sleep .5; done"
+timeout 10 bash -c "while ! test -e /var/lib/machines/long-running/reboot; do sleep .5; done"
machinectl reboot long-running long-running long-running
# Skip machinectl terminate for now, as it doesn't play well with our "init"
rm -f /var/lib/machines/long-running/trap
machinectl kill --signal=SIGTRAP --kill-whom=leader long-running
-timeout 10 sh -c "while ! test -e /var/lib/machines/long-running/trap; do sleep .5; done"
+timeout 10 bash -c "while ! test -e /var/lib/machines/long-running/trap; do sleep .5; done"
machinectl kill --signal=SIGTRAP --kill-whom=leader long-running long-running long-running
# All used signals should've been caught by a handler
[[ "$(machinectl show --property=State --value long-running)" == "running" ]]
machinectl start container-dir
rm -fr /tmp/container.dir
-timeout 10 sh -c "while ! machinectl clean --all; do sleep .5; done"
+timeout 10 bash -c "while ! machinectl clean --all; do sleep .5; done"
NSPAWN_FRAGMENT="machinectl-test-$RANDOM.nspawn"
cat >"/var/lib/machines/$NSPAWN_FRAGMENT" <<EOF
set -eux
set -o pipefail
+# shellcheck source=test/units/util.sh
+. "$(dirname "$0")"/util.sh
+
export SYSTEMD_LOG_LEVEL=debug
export SYSTEMD_LOG_TARGET=journal
-CREATE_BB_CONTAINER="/usr/lib/systemd/tests/testdata/create-busybox-container"
at_exit() {
set +e
# with enabled user namespaces support. By setting this value explicitly
# we can ensure the user namespaces support to be detected correctly.
sysctl -w user.max_user_namespaces=10000
-if unshare -U sh -c :; then
+if unshare -U bash -c :; then
IS_USERNS_SUPPORTED=yes
fi
tmpdir="$(mktemp -d)"
template="$(mktemp -d /tmp/nspawn-template.XXX)"
- "$CREATE_BB_CONTAINER" "$template"
+ create_dummy_container "$template"
# Create a simple image from the just created container template
image="$(mktemp /var/lib/machines/testsuite-13.image-XXX.img)"
dd if=/dev/zero of="$image" bs=1M count=32
# --template=
root="$(mktemp -u -d /var/lib/machines/testsuite-13.sanity.XXX)"
- (! systemd-nspawn --directory="$root" sh -xec 'echo hello')
+ (! systemd-nspawn --directory="$root" bash -xec 'echo hello')
# Initialize $root from $template (the $root directory must not exist, hence
# the `mktemp -u` above)
- systemd-nspawn --directory="$root" --template="$template" sh -xec 'echo hello'
- systemd-nspawn --directory="$root" sh -xec 'echo hello; touch /initialized'
+ systemd-nspawn --directory="$root" --template="$template" bash -xec 'echo hello'
+ systemd-nspawn --directory="$root" bash -xec 'echo hello; touch /initialized'
test -e "$root/initialized"
# Check if the $root doesn't get re-initialized once it's not empty
- systemd-nspawn --directory="$root" --template="$template" sh -xec 'echo hello'
+ systemd-nspawn --directory="$root" --template="$template" bash -xec 'echo hello'
test -e "$root/initialized"
- systemd-nspawn --directory="$root" --ephemeral sh -xec 'touch /ephemeral'
+ systemd-nspawn --directory="$root" --ephemeral bash -xec 'touch /ephemeral'
test ! -e "$root/ephemeral"
(! systemd-nspawn --directory="$root" \
--bind="${COVERAGE_BUILD_DIR:-$tmpdir}" \
--read-only \
- sh -xec 'touch /nope')
+ bash -xec 'touch /nope')
test ! -e "$root/nope"
- systemd-nspawn --image="$image" sh -xec 'echo hello'
+ systemd-nspawn --image="$image" bash -xec 'echo hello'
# --volatile=
touch "$root/usr/has-usr"
# volatile(=yes): rootfs is tmpfs, /usr/ from the OS tree is mounted read only
systemd-nspawn --directory="$root"\
--volatile \
- sh -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope'
+ bash -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope'
test ! -e "$root/nope"
test ! -e "$root/usr/read-only"
systemd-nspawn --directory="$root"\
--volatile=yes \
- sh -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope'
+ bash -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope'
test ! -e "$root/nope"
test ! -e "$root/usr/read-only"
# volatile=state: rootfs is read-only, /var/ is tmpfs
systemd-nspawn --directory="$root" \
--bind="${COVERAGE_BUILD_DIR:-$tmpdir}" \
--volatile=state \
- sh -xec 'test -e /usr/has-usr; mountpoint /var; touch /read-only && exit 1; touch /var/nope'
+ bash -xec 'test -e /usr/has-usr; mountpoint /var; touch /read-only && exit 1; touch /var/nope'
test ! -e "$root/read-only"
test ! -e "$root/var/nope"
# volatile=state: tmpfs overlay is mounted over rootfs
systemd-nspawn --directory="$root" \
--volatile=overlay \
- sh -xec 'test -e /usr/has-usr; touch /nope; touch /var/also-nope; touch /usr/nope-too'
+ bash -xec 'test -e /usr/has-usr; touch /nope; touch /var/also-nope; touch /usr/nope-too'
test ! -e "$root/nope"
test ! -e "$root/var/also-nope"
test ! -e "$root/usr/nope-too"
# --machine=, --hostname=
systemd-nspawn --directory="$root" \
--machine="foo-bar.baz" \
- sh -xec '[[ $(hostname) == foo-bar.baz ]]'
+ bash -xec '[[ $(hostname) == foo-bar.baz ]]'
systemd-nspawn --directory="$root" \
--hostname="hello.world.tld" \
- sh -xec '[[ $(hostname) == hello.world.tld ]]'
+ bash -xec '[[ $(hostname) == hello.world.tld ]]'
systemd-nspawn --directory="$root" \
--machine="foo-bar.baz" \
--hostname="hello.world.tld" \
- sh -xec '[[ $(hostname) == hello.world.tld ]]'
+ bash -xec '[[ $(hostname) == hello.world.tld ]]'
# --uuid=
rm -f "$root/etc/machine-id"
uuid="deadbeef-dead-dead-beef-000000000000"
systemd-nspawn --directory="$root" \
--uuid="$uuid" \
- sh -xec "[[ \$container_uuid == $uuid ]]"
+ bash -xec "[[ \$container_uuid == $uuid ]]"
# --as-pid2
- systemd-nspawn --directory="$root" sh -xec '[[ $$ -eq 1 ]]'
- systemd-nspawn --directory="$root" --as-pid2 sh -xec '[[ $$ -eq 2 ]]'
+ systemd-nspawn --directory="$root" bash -xec '[[ $$ -eq 1 ]]'
+ systemd-nspawn --directory="$root" --as-pid2 bash -xec '[[ $$ -eq 2 ]]'
# --user=
- systemd-nspawn --directory="$root" sh -xec '[[ $USER == root ]]'
- systemd-nspawn --directory="$root" --user=testuser sh -xec '[[ $USER == testuser ]]'
+ # "Fake" getent passwd's bare minimum, so we don't have to pull it in
+ # with all the DSO shenanigans
+ cat >"$root/bin/getent" <<\EOF
+#!/bin/bash
+
+if [[ $# -eq 0 ]]; then
+ :
+elif [[ $1 == passwd ]]; then
+ echo "testuser:x:1000:1000:testuser:/:/bin/sh"
+elif [[ $1 == initgroups ]]; then
+ echo "testuser"
+fi
+EOF
+ chmod +x "$root/bin/getent"
+ systemd-nspawn --directory="$root" bash -xec '[[ $USER == root ]]'
+ systemd-nspawn --directory="$root" --user=testuser bash -xec '[[ $USER == testuser ]]'
# --settings= + .nspawn files
mkdir -p /run/systemd/nspawn/
systemd-nspawn --directory="$root" \
--machine=foo-bar \
--settings=yes \
- sh -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
+ bash -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
systemd-nspawn --directory="$root" \
--machine=foo-bar \
--uuid="$uuid" \
--settings=yes \
- sh -xec "[[ \$container_uuid == $uuid ]]"
+ bash -xec "[[ \$container_uuid == $uuid ]]"
systemd-nspawn --directory="$root" \
--machine=foo-bar \
--uuid="$uuid" \
--settings=override \
- sh -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
+ bash -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
systemd-nspawn --directory="$root" \
--machine=foo-bar \
--uuid="$uuid" \
--settings=trusted \
- sh -xec "[[ \$container_uuid == $uuid ]]"
+ bash -xec "[[ \$container_uuid == $uuid ]]"
# Mounts
mkdir "$tmpdir"/{1,2,3}
# --bind=
systemd-nspawn --directory="$root" \
--bind="$tmpdir:/foo" \
- sh -xec 'test -e /foo/foo; touch /foo/bar'
+ bash -xec 'test -e /foo/foo; touch /foo/bar'
test -e "$tmpdir/bar"
# --bind-ro=
systemd-nspawn --directory="$root" \
--bind-ro="$tmpdir:/foo" \
- sh -xec 'test -e /foo/foo; touch /foo/baz && exit 1; true'
+ bash -xec 'test -e /foo/foo; touch /foo/baz && exit 1; true'
# --inaccessible=
systemd-nspawn --directory="$root" \
--inaccessible=/var \
- sh -xec 'touch /var/foo && exit 1; true'
+ bash -xec 'touch /var/foo && exit 1; true'
# --tmpfs=
systemd-nspawn --directory="$root" \
--tmpfs=/var:rw,nosuid,noexec \
- sh -xec 'touch /var/nope'
+ bash -xec 'touch /var/nope'
test ! -e "$root/var/nope"
# --overlay=
systemd-nspawn --directory="$root" \
--overlay="$tmpdir/1:$tmpdir/2:$tmpdir/3:/var" \
- sh -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/foo'
+ bash -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/foo'
test -e "$tmpdir/3/foo"
# --overlay-ro=
systemd-nspawn --directory="$root" \
--overlay-ro="$tmpdir/1:$tmpdir/2:$tmpdir/3:/var" \
- sh -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/nope && exit 1; true'
+ bash -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/nope && exit 1; true'
test ! -e "$tmpdir/3/nope"
rm -fr "$tmpdir"
# Assorted tests
- systemd-nspawn --directory="$root" --suppress-sync=yes sh -xec 'echo hello'
+ systemd-nspawn --directory="$root" --suppress-sync=yes bash -xec 'echo hello'
systemd-nspawn --capability=help
systemd-nspawn --resolv-conf=help
systemd-nspawn --timezone=help
local root
root="$(mktemp -d /var/lib/machines/testsuite-13.bind-tmp-path.XXX)"
- "$CREATE_BB_CONTAINER" "$root"
+ create_dummy_container "$root"
: >/tmp/bind
systemd-nspawn --register=no \
--directory="$root" \
--bind=/tmp/bind \
- /bin/sh -c 'test -e /tmp/bind'
+ bash -c 'test -e /tmp/bind'
rm -fr "$root" /tmp/bind
}
echo -n "outer" >/tmp/binddir/subdir/file
mount -t tmpfs tmpfs /tmp/binddir/subdir
echo -n "inner" >/tmp/binddir/subdir/file
- "$CREATE_BB_CONTAINER" "$root"
+ create_dummy_container "$root"
systemd-nspawn --register=no \
--directory="$root" \
--bind=/tmp/binddir:/mnt:norbind \
- /bin/sh -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; return 1; fi'
+ bash -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; exit 1; fi'
umount /tmp/binddir/subdir
rm -fr "$root" /tmp/binddir/
touch /tmp/rootidmap/bind/file
chown -R "$owner:$owner" /tmp/rootidmap/bind
- "$CREATE_BB_CONTAINER" "$root"
+ create_dummy_container "$root"
cmd='PERMISSIONS=$(stat -c "%u:%g" /mnt/file); if [[ $PERMISSIONS != "0:0" ]]; then echo "*** wrong permissions: $PERMISSIONS"; return 1; fi; touch /mnt/other_file'
if ! SYSTEMD_LOG_TARGET=console \
systemd-nspawn --register=no \
--directory="$root" \
--bind=/tmp/rootidmap/bind:/mnt:rootidmap \
- /bin/sh -c "$cmd" |& tee nspawn.out; then
+ bash -c "$cmd" |& tee nspawn.out; then
if grep -q "Failed to map ids for bind mount.*: Function not implemented" nspawn.out; then
echo "idmapped mounts are not supported, skipping the test..."
return 0
testcase_check_notification_socket() {
# https://github.com/systemd/systemd/issues/4944
- local cmd='echo a | $(busybox which nc) -U -u -w 1 /run/host/notify'
+ local root
+ local cmd='echo a | nc -U -u -w 1 /run/host/notify'
+
+ root="$(mktemp -d /var/lib/machines/testsuite-13.check_notification_socket.XXX)"
+ create_dummy_container "$root"
- # /testsuite-13.nc-container is prepared by test.sh
- systemd-nspawn --register=no --directory=/testsuite-13.nc-container /bin/sh -x -c "$cmd"
- systemd-nspawn --register=no --directory=/testsuite-13.nc-container -U /bin/sh -x -c "$cmd"
+ systemd-nspawn --register=no --directory="$root" bash -x -c "$cmd"
+ systemd-nspawn --register=no --directory="$root" -U bash -x -c "$cmd"
}
testcase_check_os_release() {
local root entrypoint os_release_source
root="$(mktemp -d /var/lib/machines/testsuite-13.check-os-release.XXX)"
- "$CREATE_BB_CONTAINER" "$root"
+ create_dummy_container "$root"
entrypoint="$root/entrypoint.sh"
cat >"$entrypoint" <<\EOF
-#!/bin/sh -ex
+#!/usr/bin/bash -ex
. /tmp/os-release
[[ -n "${ID:-}" && "$ID" != "$container_host_id" ]] && exit 1
testcase_check_machinectl_bind() {
local service_path service_name root container_name ec
- local cmd='for i in $(seq 1 20); do if test -f /tmp/marker; then exit 0; fi; usleep 500000; done; exit 1;'
+ local cmd='for i in $(seq 1 20); do if test -f /tmp/marker; then exit 0; fi; sleep .5; done; exit 1;'
root="$(mktemp -d /var/lib/machines/testsuite-13.check-machinectl-bind.XXX)"
- "$CREATE_BB_CONTAINER" "$root"
- container_name="${root##*/}"
+ create_dummy_container "$root"
+ container_name="$(basename "$root")"
service_path="$(mktemp /run/systemd/system/nspawn-machinectl-bind-XXX.service)"
service_name="${service_path##*/}"
cat >"$service_path" <<EOF
[Service]
Type=notify
-ExecStart=systemd-nspawn --directory="$root" --notify-ready=no /bin/sh -xec "$cmd"
+ExecStart=systemd-nspawn --directory="$root" --notify-ready=no /usr/bin/bash -xec "$cmd"
EOF
systemctl daemon-reload
timeout 10 bash -c "while [[ '\$(systemctl show -P SubState $service_name)' == running ]]; do sleep .2; done"
ec="$(systemctl show -P ExecMainStatus "$service_name")"
+ systemctl stop "$service_name"
rm -fr "$root" "$service_path"
local root
root="$(mktemp -d /var/lib/machines/testsuite-13.check-selinux.XXX)"
- "$CREATE_BB_CONTAINER" "$root"
+ create_dummy_container "$root"
chcon -R -t container_t "$root"
systemd-nspawn --register=no \
local root container_name
root="$(mktemp -d /var/lib/machines/testsuite-13.check-ephemeral-config.XXX)"
- "$CREATE_BB_CONTAINER" "$root"
+ create_dummy_container "$root"
container_name="${root##*/}"
mkdir -p /run/systemd/nspawn/
systemd-nspawn --register=no \
--directory="$root" \
--ephemeral \
- /bin/sh -x -c "test -f /tmp/ephemeral-config"
+ bash -x -c "test -f /tmp/ephemeral-config"
systemd-nspawn --register=no \
--directory="$root" \
--ephemeral \
--machine=foobar \
- /bin/sh -x -c "! test -f /tmp/ephemeral-config"
+ bash -x -c "! test -f /tmp/ephemeral-config"
rm -fr "$root" "/run/systemd/nspawn/$container_name"
}
fi
root="$(mktemp -d "/var/lib/machines/testsuite-13.unified-$1-cgns-$2-api-vfs-writable-$3.XXX")"
- "$CREATE_BB_CONTAINER" "$root"
+ create_dummy_container "$root"
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \
systemd-nspawn --register=no \
systemd-nspawn --register=no \
--directory="$root" \
--network-namespace-path=/run/netns/nspawn_test \
- /bin/ip a | grep -v -E '^1: lo.*UP'
+ ip a | grep -v -E '^1: lo.*UP'
ip netns del nspawn_test
rm -fr "$root"