1
0
mirror of https://github.com/systemd/systemd synced 2025-10-06 00:13:24 +02:00

test: get rid of the busybox stuff

It already required a lot of workarounds, since the busybox utilities
often work differently than their "full" counterparts, and putting
the container together using our "tools" is quite simple anyway.
This commit is contained in:
Frantisek Sumsal
2023-05-17 19:10:55 +02:00
parent 89572df859
commit 5656759d06
7 changed files with 134 additions and 174 deletions

View File

@@ -11,19 +11,34 @@ TEST_NO_NSPAWN=1
test_append_files() { test_append_files() {
local workspace="${1:?}" local workspace="${1:?}"
local container="$workspace/testsuite-13-container-template"
# On openSUSE the static linked version of busybox is named "busybox-static". # Create a dummy container "template" with a minimal toolset, which we can
busybox="$(type -P busybox-static || type -P busybox)" # then use as a base for our nspawn/machinectl tests
inst_simple "$busybox" "$(dirname "$busybox")/busybox" initdir="$container" setup_basic_dirs
initdir="$container" image_install \
bash \
cat \
hostname \
grep \
ip \
ls \
md5sum \
mountpoint \
nc \
ps \
seq \
sleep \
stat \
touch
if command -v selinuxenabled >/dev/null && selinuxenabled; then cp /etc/os-release "$container/usr/lib/os-release"
image_install chcon selinuxenabled cat >"$container/sbin/init" <<EOF
cp -ar /etc/selinux "$workspace/etc/selinux" #!/bin/bash
sed -i "s/^SELINUX=.*$/SELINUX=permissive/" "$workspace/etc/selinux/config" echo "Hello from dummy init, beautiful day, innit?"
fi ip link
EOF
"$TEST_BASE_DIR/create-busybox-container" "$workspace/testsuite-13.nc-container" chmod +x "$container/sbin/init"
initdir="$workspace/testsuite-13.nc-container" image_install nc ip md5sum
} }
do_test "$@" do_test "$@"

View File

@@ -1,85 +0,0 @@
#!/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"

View File

@@ -45,10 +45,6 @@ if install_tests
install_dir : testdata_dir) install_dir : testdata_dir)
endif endif
install_data('create-busybox-container',
install_mode : 'rwxr-xr-x',
install_dir : testdata_dir)
# The unit tests implemented as shell scripts expect to find testdata/ # The unit tests implemented as shell scripts expect to find testdata/
# in the directory where they are stored. # in the directory where they are stored.
meson.add_install_script(meson_make_symlink, meson.add_install_script(meson_make_symlink,

View File

@@ -4,9 +4,10 @@
set -eux set -eux
set -o pipefail 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() { at_exit() {
set +e set +e
@@ -24,18 +25,17 @@ mount -t tmpfs tmpfs /var/lib/machines
# Create a couple of containers we can refer to in tests # Create a couple of containers we can refer to in tests
for i in {0..4}; do 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" machinectl start "container$i"
done done
# Create one "long running" container with some basic signal handling # 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 cat >/var/lib/machines/long-running/sbin/init <<\EOF
#!/bin/sh -x #!/usr/bin/bash -x
#
PID=0 PID=0
# sh doesn't recognize RTMIN+4, so we have to use the signal number directly trap "touch /poweroff" RTMIN+4
trap "touch /poweroff" 38
trap "touch /reboot" INT trap "touch /reboot" INT
trap "touch /trap" TRAP trap "touch /trap" TRAP
trap 'kill $PID' EXIT trap 'kill $PID' EXIT
@@ -82,24 +82,24 @@ machinectl disable long-running
test ! -L /etc/systemd/system/machines.target.wants/systemd-nspawn@long-running.service test ! -L /etc/systemd/system/machines.target.wants/systemd-nspawn@long-running.service
machinectl disable long-running long-running long-running container1 machinectl disable long-running long-running long-running container1
[[ "$(machinectl shell testuser@ /bin/sh -c 'echo -ne $FOO')" == "" ]] [[ "$(machinectl shell testuser@ /usr/bin/bash -c 'echo -ne $FOO')" == "" ]]
[[ "$(machinectl shell --setenv=FOO=bar testuser@ /bin/sh -c 'echo -ne $FOO')" == "bar" ]] [[ "$(machinectl shell --setenv=FOO=bar testuser@ /usr/bin/bash -c 'echo -ne $FOO')" == "bar" ]]
[[ "$(machinectl show --property=State --value long-running)" == "running" ]] [[ "$(machinectl show --property=State --value long-running)" == "running" ]]
# Equivalent to machinectl kill --signal=SIGRTMIN+4 --kill-whom=leader # Equivalent to machinectl kill --signal=SIGRTMIN+4 --kill-whom=leader
rm -f /var/lib/machines/long-running/poweroff rm -f /var/lib/machines/long-running/poweroff
machinectl poweroff long-running 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 machinectl poweroff long-running long-running long-running
# Equivalent to machinectl kill --signal=SIGINT --kill-whom=leader # Equivalent to machinectl kill --signal=SIGINT --kill-whom=leader
rm -f /var/lib/machines/long-running/reboot rm -f /var/lib/machines/long-running/reboot
machinectl reboot long-running 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 machinectl reboot long-running long-running long-running
# Skip machinectl terminate for now, as it doesn't play well with our "init" # Skip machinectl terminate for now, as it doesn't play well with our "init"
rm -f /var/lib/machines/long-running/trap rm -f /var/lib/machines/long-running/trap
machinectl kill --signal=SIGTRAP --kill-whom=leader long-running 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 machinectl kill --signal=SIGTRAP --kill-whom=leader long-running long-running long-running
# All used signals should've been caught by a handler # All used signals should've been caught by a handler
[[ "$(machinectl show --property=State --value long-running)" == "running" ]] [[ "$(machinectl show --property=State --value long-running)" == "running" ]]
@@ -181,7 +181,7 @@ machinectl import-fs /tmp/container.dir container-dir
machinectl start container-dir machinectl start container-dir
rm -fr /tmp/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" NSPAWN_FRAGMENT="machinectl-test-$RANDOM.nspawn"
cat >"/var/lib/machines/$NSPAWN_FRAGMENT" <<EOF cat >"/var/lib/machines/$NSPAWN_FRAGMENT" <<EOF

View File

@@ -4,9 +4,11 @@
set -eux set -eux
set -o pipefail set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
export SYSTEMD_LOG_LEVEL=debug export SYSTEMD_LOG_LEVEL=debug
export SYSTEMD_LOG_TARGET=journal export SYSTEMD_LOG_TARGET=journal
CREATE_BB_CONTAINER="/usr/lib/systemd/tests/testdata/create-busybox-container"
# shellcheck disable=SC2317 # shellcheck disable=SC2317
at_exit() { at_exit() {
@@ -32,7 +34,7 @@ mount --bind /proc/self/ns/net "$NETNS"
TMPDIR="$(mktemp -d)" TMPDIR="$(mktemp -d)"
touch "$TMPDIR/hello" touch "$TMPDIR/hello"
OCI="$(mktemp -d /var/lib/machines/testsuite-13.oci-bundle.XXX)" OCI="$(mktemp -d /var/lib/machines/testsuite-13.oci-bundle.XXX)"
"$CREATE_BB_CONTAINER" "$OCI/rootfs" create_dummy_container "$OCI/rootfs"
mkdir -p "$OCI/rootfs/opt/var" mkdir -p "$OCI/rootfs/opt/var"
mkdir -p "$OCI/rootfs/opt/readonly" mkdir -p "$OCI/rootfs/opt/readonly"
@@ -52,7 +54,7 @@ cat >"$OCI/config.json" <<EOF
] ]
} }
EOF EOF
systemd-nspawn --oci-bundle="$OCI" sh -xec 'mountpoint /root' systemd-nspawn --oci-bundle="$OCI" bash -xec 'mountpoint /root'
# And now for something a bit more involved # And now for something a bit more involved
# Notes: # Notes:
@@ -97,7 +99,7 @@ cat >"$OCI/config.json" <<EOF
], ],
"cwd" : "/root", "cwd" : "/root",
"args" : [ "args" : [
"sh", "bash",
"-xe", "-xe",
"/entrypoint.sh" "/entrypoint.sh"
], ],
@@ -347,7 +349,7 @@ EOF
# Create a simple "entrypoint" script that validates that the container # Create a simple "entrypoint" script that validates that the container
# is created correctly according to the OCI config # is created correctly according to the OCI config
cat >"$OCI/rootfs/entrypoint.sh" <<EOF cat >"$OCI/rootfs/entrypoint.sh" <<EOF
#!/bin/sh -e #!/usr/bin/bash -e
# Mounts # Mounts
mountpoint /root mountpoint /root

View File

@@ -4,9 +4,11 @@
set -eux set -eux
set -o pipefail set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
export SYSTEMD_LOG_LEVEL=debug export SYSTEMD_LOG_LEVEL=debug
export SYSTEMD_LOG_TARGET=journal export SYSTEMD_LOG_TARGET=journal
CREATE_BB_CONTAINER="/usr/lib/systemd/tests/testdata/create-busybox-container"
at_exit() { at_exit() {
set +e set +e
@@ -37,7 +39,7 @@ IS_USERNS_SUPPORTED=no
# with enabled user namespaces support. By setting this value explicitly # with enabled user namespaces support. By setting this value explicitly
# we can ensure the user namespaces support to be detected correctly. # we can ensure the user namespaces support to be detected correctly.
sysctl -w user.max_user_namespaces=10000 sysctl -w user.max_user_namespaces=10000
if unshare -U sh -c :; then if unshare -U bash -c :; then
IS_USERNS_SUPPORTED=yes IS_USERNS_SUPPORTED=yes
fi fi
@@ -50,7 +52,7 @@ testcase_sanity_check() {
tmpdir="$(mktemp -d)" tmpdir="$(mktemp -d)"
template="$(mktemp -d /tmp/nspawn-template.XXX)" 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 # Create a simple image from the just created container template
image="$(mktemp /var/lib/machines/testsuite-13.image-XXX.img)" image="$(mktemp /var/lib/machines/testsuite-13.image-XXX.img)"
dd if=/dev/zero of="$image" bs=1M count=32 dd if=/dev/zero of="$image" bs=1M count=32
@@ -65,49 +67,49 @@ testcase_sanity_check() {
# --template= # --template=
root="$(mktemp -u -d /var/lib/machines/testsuite-13.sanity.XXX)" 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 # Initialize $root from $template (the $root directory must not exist, hence
# the `mktemp -u` above) # the `mktemp -u` above)
systemd-nspawn --directory="$root" --template="$template" sh -xec 'echo hello' systemd-nspawn --directory="$root" --template="$template" bash -xec 'echo hello'
systemd-nspawn --directory="$root" sh -xec 'echo hello; touch /initialized' systemd-nspawn --directory="$root" bash -xec 'echo hello; touch /initialized'
test -e "$root/initialized" test -e "$root/initialized"
# Check if the $root doesn't get re-initialized once it's not empty # 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" 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" test ! -e "$root/ephemeral"
(! systemd-nspawn --directory="$root" \ (! systemd-nspawn --directory="$root" \
--bind="${COVERAGE_BUILD_DIR:-$tmpdir}" \ --bind="${COVERAGE_BUILD_DIR:-$tmpdir}" \
--read-only \ --read-only \
sh -xec 'touch /nope') bash -xec 'touch /nope')
test ! -e "$root/nope" test ! -e "$root/nope"
systemd-nspawn --image="$image" sh -xec 'echo hello' systemd-nspawn --image="$image" bash -xec 'echo hello'
# --volatile= # --volatile=
touch "$root/usr/has-usr" touch "$root/usr/has-usr"
# volatile(=yes): rootfs is tmpfs, /usr/ from the OS tree is mounted read only # volatile(=yes): rootfs is tmpfs, /usr/ from the OS tree is mounted read only
systemd-nspawn --directory="$root"\ systemd-nspawn --directory="$root"\
--volatile \ --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/nope"
test ! -e "$root/usr/read-only" test ! -e "$root/usr/read-only"
systemd-nspawn --directory="$root"\ systemd-nspawn --directory="$root"\
--volatile=yes \ --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/nope"
test ! -e "$root/usr/read-only" test ! -e "$root/usr/read-only"
# volatile=state: rootfs is read-only, /var/ is tmpfs # volatile=state: rootfs is read-only, /var/ is tmpfs
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--bind="${COVERAGE_BUILD_DIR:-$tmpdir}" \ --bind="${COVERAGE_BUILD_DIR:-$tmpdir}" \
--volatile=state \ --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/read-only"
test ! -e "$root/var/nope" test ! -e "$root/var/nope"
# volatile=state: tmpfs overlay is mounted over rootfs # volatile=state: tmpfs overlay is mounted over rootfs
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--volatile=overlay \ --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/nope"
test ! -e "$root/var/also-nope" test ! -e "$root/var/also-nope"
test ! -e "$root/usr/nope-too" test ! -e "$root/usr/nope-too"
@@ -115,29 +117,43 @@ testcase_sanity_check() {
# --machine=, --hostname= # --machine=, --hostname=
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--machine="foo-bar.baz" \ --machine="foo-bar.baz" \
sh -xec '[[ $(hostname) == foo-bar.baz ]]' bash -xec '[[ $(hostname) == foo-bar.baz ]]'
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--hostname="hello.world.tld" \ --hostname="hello.world.tld" \
sh -xec '[[ $(hostname) == hello.world.tld ]]' bash -xec '[[ $(hostname) == hello.world.tld ]]'
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--machine="foo-bar.baz" \ --machine="foo-bar.baz" \
--hostname="hello.world.tld" \ --hostname="hello.world.tld" \
sh -xec '[[ $(hostname) == hello.world.tld ]]' bash -xec '[[ $(hostname) == hello.world.tld ]]'
# --uuid= # --uuid=
rm -f "$root/etc/machine-id" rm -f "$root/etc/machine-id"
uuid="deadbeef-dead-dead-beef-000000000000" uuid="deadbeef-dead-dead-beef-000000000000"
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--uuid="$uuid" \ --uuid="$uuid" \
sh -xec "[[ \$container_uuid == $uuid ]]" bash -xec "[[ \$container_uuid == $uuid ]]"
# --as-pid2 # --as-pid2
systemd-nspawn --directory="$root" sh -xec '[[ $$ -eq 1 ]]' systemd-nspawn --directory="$root" bash -xec '[[ $$ -eq 1 ]]'
systemd-nspawn --directory="$root" --as-pid2 sh -xec '[[ $$ -eq 2 ]]' systemd-nspawn --directory="$root" --as-pid2 bash -xec '[[ $$ -eq 2 ]]'
# --user= # --user=
systemd-nspawn --directory="$root" sh -xec '[[ $USER == root ]]' # "Fake" getent passwd's bare minimum, so we don't have to pull it in
systemd-nspawn --directory="$root" --user=testuser sh -xec '[[ $USER == testuser ]]' # 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 # --settings= + .nspawn files
mkdir -p /run/systemd/nspawn/ mkdir -p /run/systemd/nspawn/
@@ -146,22 +162,22 @@ testcase_sanity_check() {
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--machine=foo-bar \ --machine=foo-bar \
--settings=yes \ --settings=yes \
sh -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]' bash -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--machine=foo-bar \ --machine=foo-bar \
--uuid="$uuid" \ --uuid="$uuid" \
--settings=yes \ --settings=yes \
sh -xec "[[ \$container_uuid == $uuid ]]" bash -xec "[[ \$container_uuid == $uuid ]]"
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--machine=foo-bar \ --machine=foo-bar \
--uuid="$uuid" \ --uuid="$uuid" \
--settings=override \ --settings=override \
sh -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]' bash -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--machine=foo-bar \ --machine=foo-bar \
--uuid="$uuid" \ --uuid="$uuid" \
--settings=trusted \ --settings=trusted \
sh -xec "[[ \$container_uuid == $uuid ]]" bash -xec "[[ \$container_uuid == $uuid ]]"
# Mounts # Mounts
mkdir "$tmpdir"/{1,2,3} mkdir "$tmpdir"/{1,2,3}
@@ -170,35 +186,35 @@ testcase_sanity_check() {
# --bind= # --bind=
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--bind="$tmpdir:/foo" \ --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" test -e "$tmpdir/bar"
# --bind-ro= # --bind-ro=
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--bind-ro="$tmpdir:/foo" \ --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= # --inaccessible=
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--inaccessible=/var \ --inaccessible=/var \
sh -xec 'touch /var/foo && exit 1; true' bash -xec 'touch /var/foo && exit 1; true'
# --tmpfs= # --tmpfs=
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--tmpfs=/var:rw,nosuid,noexec \ --tmpfs=/var:rw,nosuid,noexec \
sh -xec 'touch /var/nope' bash -xec 'touch /var/nope'
test ! -e "$root/var/nope" test ! -e "$root/var/nope"
# --overlay= # --overlay=
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--overlay="$tmpdir/1:$tmpdir/2:$tmpdir/3:/var" \ --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" test -e "$tmpdir/3/foo"
# --overlay-ro= # --overlay-ro=
systemd-nspawn --directory="$root" \ systemd-nspawn --directory="$root" \
--overlay-ro="$tmpdir/1:$tmpdir/2:$tmpdir/3:/var" \ --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" test ! -e "$tmpdir/3/nope"
rm -fr "$tmpdir" rm -fr "$tmpdir"
# Assorted tests # 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 --capability=help
systemd-nspawn --resolv-conf=help systemd-nspawn --resolv-conf=help
systemd-nspawn --timezone=help systemd-nspawn --timezone=help
@@ -252,12 +268,12 @@ testcase_check_bind_tmp_path() {
local root local root
root="$(mktemp -d /var/lib/machines/testsuite-13.bind-tmp-path.XXX)" root="$(mktemp -d /var/lib/machines/testsuite-13.bind-tmp-path.XXX)"
"$CREATE_BB_CONTAINER" "$root" create_dummy_container "$root"
: >/tmp/bind : >/tmp/bind
systemd-nspawn --register=no \ systemd-nspawn --register=no \
--directory="$root" \ --directory="$root" \
--bind=/tmp/bind \ --bind=/tmp/bind \
/bin/sh -c 'test -e /tmp/bind' bash -c 'test -e /tmp/bind'
rm -fr "$root" /tmp/bind rm -fr "$root" /tmp/bind
} }
@@ -271,12 +287,12 @@ testcase_check_norbind() {
echo -n "outer" >/tmp/binddir/subdir/file echo -n "outer" >/tmp/binddir/subdir/file
mount -t tmpfs tmpfs /tmp/binddir/subdir mount -t tmpfs tmpfs /tmp/binddir/subdir
echo -n "inner" >/tmp/binddir/subdir/file echo -n "inner" >/tmp/binddir/subdir/file
"$CREATE_BB_CONTAINER" "$root" create_dummy_container "$root"
systemd-nspawn --register=no \ systemd-nspawn --register=no \
--directory="$root" \ --directory="$root" \
--bind=/tmp/binddir:/mnt:norbind \ --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 umount /tmp/binddir/subdir
rm -fr "$root" /tmp/binddir/ rm -fr "$root" /tmp/binddir/
@@ -304,13 +320,13 @@ testcase_check_rootidmap() {
touch /tmp/rootidmap/bind/file touch /tmp/rootidmap/bind/file
chown -R "$owner:$owner" /tmp/rootidmap/bind 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' 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 \ if ! SYSTEMD_LOG_TARGET=console \
systemd-nspawn --register=no \ systemd-nspawn --register=no \
--directory="$root" \ --directory="$root" \
--bind=/tmp/rootidmap/bind:/mnt:rootidmap \ --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 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..." echo "idmapped mounts are not supported, skipping the test..."
return 0 return 0
@@ -328,21 +344,24 @@ testcase_check_rootidmap() {
testcase_check_notification_socket() { testcase_check_notification_socket() {
# https://github.com/systemd/systemd/issues/4944 # 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'
# /testsuite-13.nc-container is prepared by test.sh root="$(mktemp -d /var/lib/machines/testsuite-13.check_notification_socket.XXX)"
systemd-nspawn --register=no --directory=/testsuite-13.nc-container /bin/sh -x -c "$cmd" create_dummy_container "$root"
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() { testcase_check_os_release() {
local root entrypoint os_release_source local root entrypoint os_release_source
root="$(mktemp -d /var/lib/machines/testsuite-13.check-os-release.XXX)" root="$(mktemp -d /var/lib/machines/testsuite-13.check-os-release.XXX)"
"$CREATE_BB_CONTAINER" "$root" create_dummy_container "$root"
entrypoint="$root/entrypoint.sh" entrypoint="$root/entrypoint.sh"
cat >"$entrypoint" <<\EOF cat >"$entrypoint" <<\EOF
#!/bin/sh -ex #!/usr/bin/bash -ex
. /tmp/os-release . /tmp/os-release
[[ -n "${ID:-}" && "$ID" != "$container_host_id" ]] && exit 1 [[ -n "${ID:-}" && "$ID" != "$container_host_id" ]] && exit 1
@@ -378,18 +397,18 @@ EOF
testcase_check_machinectl_bind() { testcase_check_machinectl_bind() {
local service_path service_name root container_name ec 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)" root="$(mktemp -d /var/lib/machines/testsuite-13.check-machinectl-bind.XXX)"
"$CREATE_BB_CONTAINER" "$root" create_dummy_container "$root"
container_name="${root##*/}" container_name="$(basename "$root")"
service_path="$(mktemp /run/systemd/system/nspawn-machinectl-bind-XXX.service)" service_path="$(mktemp /run/systemd/system/nspawn-machinectl-bind-XXX.service)"
service_name="${service_path##*/}" service_name="${service_path##*/}"
cat >"$service_path" <<EOF cat >"$service_path" <<EOF
[Service] [Service]
Type=notify 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 EOF
systemctl daemon-reload systemctl daemon-reload
@@ -399,6 +418,7 @@ EOF
timeout 10 bash -c "while [[ '\$(systemctl show -P SubState $service_name)' == running ]]; do sleep .2; done" timeout 10 bash -c "while [[ '\$(systemctl show -P SubState $service_name)' == running ]]; do sleep .2; done"
ec="$(systemctl show -P ExecMainStatus "$service_name")" ec="$(systemctl show -P ExecMainStatus "$service_name")"
systemctl stop "$service_name"
rm -fr "$root" "$service_path" rm -fr "$root" "$service_path"
@@ -415,7 +435,7 @@ testcase_check_selinux() {
local root local root
root="$(mktemp -d /var/lib/machines/testsuite-13.check-selinux.XXX)" 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" chcon -R -t container_t "$root"
systemd-nspawn --register=no \ systemd-nspawn --register=no \
@@ -432,7 +452,7 @@ testcase_check_ephemeral_config() {
local root container_name local root container_name
root="$(mktemp -d /var/lib/machines/testsuite-13.check-ephemeral-config.XXX)" root="$(mktemp -d /var/lib/machines/testsuite-13.check-ephemeral-config.XXX)"
"$CREATE_BB_CONTAINER" "$root" create_dummy_container "$root"
container_name="${root##*/}" container_name="${root##*/}"
mkdir -p /run/systemd/nspawn/ mkdir -p /run/systemd/nspawn/
@@ -445,13 +465,13 @@ EOF
systemd-nspawn --register=no \ systemd-nspawn --register=no \
--directory="$root" \ --directory="$root" \
--ephemeral \ --ephemeral \
/bin/sh -x -c "test -f /tmp/ephemeral-config" bash -x -c "test -f /tmp/ephemeral-config"
systemd-nspawn --register=no \ systemd-nspawn --register=no \
--directory="$root" \ --directory="$root" \
--ephemeral \ --ephemeral \
--machine=foobar \ --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" rm -fr "$root" "/run/systemd/nspawn/$container_name"
} }
@@ -473,7 +493,7 @@ matrix_run_one() {
fi fi
root="$(mktemp -d "/var/lib/machines/testsuite-13.unified-$1-cgns-$2-api-vfs-writable-$3.XXX")" 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_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 \
@@ -548,7 +568,7 @@ matrix_run_one() {
systemd-nspawn --register=no \ systemd-nspawn --register=no \
--directory="$root" \ --directory="$root" \
--network-namespace-path=/run/netns/nspawn_test \ --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 ip netns del nspawn_test
rm -fr "$root" rm -fr "$root"

View File

@@ -80,3 +80,15 @@ runas() {
shift shift
XDG_RUNTIME_DIR=/run/user/"$(id -u "$userid")" setpriv --reuid="$userid" --init-groups "$@" XDG_RUNTIME_DIR=/run/user/"$(id -u "$userid")" setpriv --reuid="$userid" --init-groups "$@"
} }
create_dummy_container() {
local root="${1:?}"
if [[ ! -d /testsuite-13-container-template ]]; then
echo >&2 "Missing container template, probably not running in TEST-13-NSPAWN?"
exit 1
fi
mkdir -p "$root"
cp -a /testsuite-13-container-template/* "$root"
}