2019-12-09 23:45:46 +03:00
#!/usr/bin/env bash
2021-10-17 19:13:06 +03:00
# SPDX-License-Identifier: LGPL-2.1-or-later
2021-04-09 20:39:41 +03:00
# shellcheck disable=SC2016
set -eux
2019-12-09 23:45:46 +03:00
set -o pipefail
export SYSTEMD_LOG_LEVEL = debug
2022-09-02 13:43:02 +03:00
export SYSTEMD_LOG_TARGET = journal
2019-12-09 23:45:46 +03:00
# check cgroup-v2
is_v2_supported = no
mkdir -p /tmp/cgroup2
if mount -t cgroup2 cgroup2 /tmp/cgroup2; then
is_v2_supported = yes
umount /tmp/cgroup2
fi
rmdir /tmp/cgroup2
# check cgroup namespaces
is_cgns_supported = no
if [ [ -f /proc/1/ns/cgroup ] ] ; then
is_cgns_supported = yes
fi
is_user_ns_supported = no
# On some systems (e.g. CentOS 7) the default limit for user namespaces
# is set to 0, which causes the following unshare syscall to fail, even
# 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
is_user_ns_supported = yes
fi
function check_bind_tmp_path {
# https://github.com/systemd/systemd/issues/4789
2020-03-31 12:23:21 +03:00
local _root = "/var/lib/machines/testsuite-13.bind-tmp-path"
rm -rf " $_root "
2019-12-09 23:45:46 +03:00
/usr/lib/systemd/tests/testdata/create-busybox-container " $_root "
2021-04-09 20:55:27 +03:00
: >/tmp/bind
2021-08-03 13:18:40 +03:00
systemd-nspawn --register= no -D " $_root " --bind= /tmp/bind /bin/sh -c 'test -e /tmp/bind'
2019-12-09 23:45:46 +03:00
}
function check_norbind {
# https://github.com/systemd/systemd/issues/13170
2020-03-31 12:23:21 +03:00
local _root = "/var/lib/machines/testsuite-13.norbind-path"
rm -rf " $_root "
2019-12-09 23:45:46 +03:00
mkdir -p /tmp/binddir/subdir
2021-04-08 01:09:55 +03:00
echo -n "outer" >/tmp/binddir/subdir/file
2019-12-09 23:45:46 +03:00
mount -t tmpfs tmpfs /tmp/binddir/subdir
2021-04-08 01:09:55 +03:00
echo -n "inner" >/tmp/binddir/subdir/file
2019-12-09 23:45:46 +03:00
/usr/lib/systemd/tests/testdata/create-busybox-container " $_root "
2021-08-03 13:18:40 +03:00
systemd-nspawn --register= no -D " $_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'
2019-12-09 23:45:46 +03:00
}
2022-09-06 16:42:43 +03:00
function check_rootidmap {
local _owner = 1000
local _root = "/var/lib/machines/testsuite-13.rootidmap-path"
local _command
rm -rf " $_root "
# Create ext4 image, as ext4 supports idmapped-mounts.
dd if = /dev/zero of = /tmp/ext4.img bs = 4k count = 2048
mkfs.ext4 /tmp/ext4.img
mkdir -p /tmp/rootidmapdir
mount /tmp/ext4.img /tmp/rootidmapdir
touch /tmp/rootidmapdir/file
chown -R $_owner :$_owner /tmp/rootidmapdir
/usr/lib/systemd/tests/testdata/create-busybox-container " $_root "
_command = '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 -D " $_root " \
--bind= /tmp/rootidmapdir:/mnt:rootidmap \
/bin/sh -c " $_command " | & 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
fi
return 1
fi
PERMISSIONS = $( stat -c "%u:%g" /tmp/rootidmapdir/other_file)
if [ [ $PERMISSIONS != " $_owner : $_owner " ] ] ; then
echo " *** wrong permissions: $PERMISSIONS "
[ [ " $is_user_ns_supported " = "yes" ] ] && return 1
fi
}
2019-12-09 23:45:46 +03:00
function check_notification_socket {
# https://github.com/systemd/systemd/issues/4944
2020-07-22 19:00:18 +03:00
local _cmd = 'echo a | $(busybox which nc) -U -u -w 1 /run/host/notify'
2020-03-31 12:23:21 +03:00
# /testsuite-13.nc-container is prepared by test.sh
2021-08-03 13:18:40 +03:00
systemd-nspawn --register= no -D /testsuite-13.nc-container /bin/sh -x -c " $_cmd "
systemd-nspawn --register= no -D /testsuite-13.nc-container -U /bin/sh -x -c " $_cmd "
2019-12-09 23:45:46 +03:00
}
2020-05-22 18:06:54 +03:00
function check_os_release {
local _cmd = ' . /tmp/os-release
if [ -n " ${ ID : +set } " ] && [ " ${ ID } " != " ${ container_host_id } " ] ; then exit 1; fi
if [ -n " ${ VERSION_ID : +set } " ] && [ " ${ VERSION_ID } " != " ${ container_host_version_id } " ] ; then exit 1; fi
if [ -n " ${ BUILD_ID : +set } " ] && [ " ${ BUILD_ID } " != " ${ container_host_build_id } " ] ; then exit 1; fi
if [ -n " ${ VARIANT_ID : +set } " ] && [ " ${ VARIANT_ID } " != " ${ container_host_variant_id } " ] ; then exit 1; fi
2020-07-23 17:49:13 +03:00
cd /tmp; ( cd /run/host; md5sum os-release) | md5sum -c
2021-04-08 01:09:55 +03:00
if echo test >>/run/host/os-release; then exit 1; fi
2020-05-22 18:06:54 +03:00
'
2020-07-23 17:49:13 +03:00
local _os_release_source = "/etc/os-release"
2021-04-09 20:55:27 +03:00
if [ [ ! -r " ${ _os_release_source } " ] ] ; then
2020-07-23 17:49:13 +03:00
_os_release_source = "/usr/lib/os-release"
2021-04-09 20:55:27 +03:00
elif [ [ -L " ${ _os_release_source } " ] ] && rm /etc/os-release; then
2020-07-23 17:49:13 +03:00
# Ensure that /etc always wins if available
cp /usr/lib/os-release /etc
2021-04-08 01:09:55 +03:00
echo MARKER = 1 >>/etc/os-release
2020-07-23 17:49:13 +03:00
fi
2021-08-03 13:18:40 +03:00
systemd-nspawn --register= no -D /testsuite-13.nc-container --bind= " ${ _os_release_source } " :/tmp/os-release /bin/sh -x -e -c " $_cmd "
2020-07-23 17:49:13 +03:00
if grep -q MARKER /etc/os-release; then
rm /etc/os-release
ln -s ../usr/lib/os-release /etc/os-release
fi
2020-05-22 18:06:54 +03:00
}
2021-01-14 02:52:00 +03:00
function check_machinectl_bind {
2021-08-05 09:38:27 +03:00
local _cmd = 'for i in $(seq 1 20); do if test -f /tmp/marker; then exit 0; fi; usleep 500000; done; exit 1;'
2021-01-14 02:52:00 +03:00
2021-04-09 20:55:27 +03:00
cat >/run/systemd/system/nspawn_machinectl_bind.service <<EOF
2021-01-14 02:52:00 +03:00
[ Service]
Type = notify
2021-04-09 20:55:27 +03:00
ExecStart = systemd-nspawn ${ SUSE_OPTS [@] } -D /testsuite-13.nc-container --notify-ready= no /bin/sh -x -e -c " $_cmd "
2021-01-14 02:52:00 +03:00
EOF
systemctl start nspawn_machinectl_bind.service
touch /tmp/marker
machinectl bind --mkdir testsuite-13.nc-container /tmp/marker
while systemctl show -P SubState nspawn_machinectl_bind.service | grep -q running
do
sleep 0.1
done
2021-04-09 20:49:32 +03:00
return " $( systemctl show -P ExecMainStatus nspawn_machinectl_bind.service) "
2021-01-14 02:52:00 +03:00
}
2021-07-14 21:29:37 +03:00
function check_selinux {
2022-09-02 20:39:30 +03:00
if ! command -v selinuxenabled >/dev/null || ! selinuxenabled; then
2021-07-14 21:29:37 +03:00
echo >& 2 "SELinux is not enabled, skipping SELinux-related tests"
return 0
fi
# Basic test coverage to avoid issues like https://github.com/systemd/systemd/issues/19976
systemd-nspawn " ${ SUSE_OPTS [@] } " --register= no -b -D /testsuite-13.nc-container --selinux-apifs-context= system_u:object_r:container_file_t:s0:c0,c1 --selinux-context= system_u:system_r:container_t:s0:c0,c1
}
2022-04-18 19:39:18 +03:00
function check_ephemeral_config {
# https://github.com/systemd/systemd/issues/13297
mkdir -p /run/systemd/nspawn/
cat >/run/systemd/nspawn/testsuite-13.nc-container.nspawn <<EOF
[ Files]
BindReadOnly = /tmp/ephemeral-config
EOF
touch /tmp/ephemeral-config
# /testsuite-13.nc-container is prepared by test.sh
2022-04-19 13:45:26 +03:00
systemd-nspawn --register= no -D /testsuite-13.nc-container --ephemeral /bin/sh -x -c "test -f /tmp/ephemeral-config"
systemd-nspawn --register= no -D /testsuite-13.nc-container --ephemeral --machine foobar /bin/sh -x -c "! test -f /tmp/ephemeral-config"
2022-04-18 19:39:18 +03:00
rm -f /run/systemd/nspawn/testsuite-13.nc-container.nspawn
}
2019-12-09 23:45:46 +03:00
function run {
if [ [ " $1 " = "yes" && " $is_v2_supported " = "no" ] ] ; then
printf "Unified cgroup hierarchy is not supported. Skipping.\n" >& 2
return 0
fi
if [ [ " $2 " = "yes" && " $is_cgns_supported " = "no" ] ] ; then
printf "CGroup namespaces are not supported. Skipping.\n" >& 2
return 0
fi
2020-03-31 12:23:21 +03:00
local _root = " /var/lib/machines/testsuite-13.unified- $1 -cgns- $2 -api-vfs-writable- $3 "
rm -rf " $_root "
2019-12-09 23:45:46 +03:00
/usr/lib/systemd/tests/testdata/create-busybox-container " $_root "
2021-08-03 13:18:40 +03:00
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY = " $1 " SYSTEMD_NSPAWN_USE_CGNS = " $2 " SYSTEMD_NSPAWN_API_VFS_WRITABLE = " $3 " systemd-nspawn --register= no -D " $_root " -b
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY = " $1 " SYSTEMD_NSPAWN_USE_CGNS = " $2 " SYSTEMD_NSPAWN_API_VFS_WRITABLE = " $3 " systemd-nspawn --register= no -D " $_root " --private-network -b
2019-12-09 23:45:46 +03:00
2021-08-03 13:18:40 +03:00
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY = " $1 " SYSTEMD_NSPAWN_USE_CGNS = " $2 " SYSTEMD_NSPAWN_API_VFS_WRITABLE = " $3 " systemd-nspawn --register= no -D " $_root " -U -b; then
2019-12-09 23:45:46 +03:00
[ [ " $is_user_ns_supported " = "yes" && " $3 " = "network" ] ] && return 1
else
[ [ " $is_user_ns_supported " = "no" && " $3 " = "network" ] ] && return 1
fi
2021-08-03 13:18:40 +03:00
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY = " $1 " SYSTEMD_NSPAWN_USE_CGNS = " $2 " SYSTEMD_NSPAWN_API_VFS_WRITABLE = " $3 " systemd-nspawn --register= no -D " $_root " --private-network -U -b; then
2019-12-09 23:45:46 +03:00
[ [ " $is_user_ns_supported " = "yes" && " $3 " = "yes" ] ] && return 1
else
[ [ " $is_user_ns_supported " = "no" && " $3 " = "yes" ] ] && return 1
fi
local _netns_opt = "--network-namespace-path=/proc/self/ns/net"
2021-04-09 20:55:27 +03:00
local _net_opts = (
"--network-bridge=lo"
"--network-interface=lo"
"--network-ipvlan=lo"
"--network-macvlan=lo"
"--network-veth"
"--network-veth-extra=lo"
"--network-zone=zone"
)
2019-12-09 23:45:46 +03:00
# --network-namespace-path and network-related options cannot be used together
2021-04-09 20:55:27 +03:00
for netopt in " ${ _net_opts [@] } " ; do
echo " $_netns_opt in combination with $netopt should fail "
2021-08-03 13:18:40 +03:00
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY = " $1 " SYSTEMD_NSPAWN_USE_CGNS = " $2 " SYSTEMD_NSPAWN_API_VFS_WRITABLE = " $3 " systemd-nspawn --register= no -D " $_root " -b " $_netns_opt " " $netopt " ; then
2021-04-09 20:55:27 +03:00
echo >& 2 "unexpected pass"
return 1
fi
done
2019-12-09 23:45:46 +03:00
# allow combination of --network-namespace-path and --private-network
2021-08-03 13:18:40 +03:00
if ! SYSTEMD_NSPAWN_UNIFIED_HIERARCHY = " $1 " SYSTEMD_NSPAWN_USE_CGNS = " $2 " SYSTEMD_NSPAWN_API_VFS_WRITABLE = " $3 " systemd-nspawn --register= no -D " $_root " -b " $_netns_opt " --private-network; then
2019-12-09 23:45:46 +03:00
return 1
fi
# test --network-namespace-path works with a network namespace created by "ip netns"
ip netns add nspawn_test
_netns_opt = "--network-namespace-path=/run/netns/nspawn_test"
2021-08-03 13:18:40 +03:00
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY = " $1 " SYSTEMD_NSPAWN_USE_CGNS = " $2 " SYSTEMD_NSPAWN_API_VFS_WRITABLE = " $3 " systemd-nspawn --register= no -D " $_root " " $_netns_opt " /bin/ip a | grep -v -E '^1: lo.*UP'
2019-12-09 23:45:46 +03:00
local r = $?
ip netns del nspawn_test
2021-04-09 20:55:27 +03:00
if [ [ $r -ne 0 ] ] ; then
2019-12-09 23:45:46 +03:00
return 1
fi
return 0
}
check_bind_tmp_path
check_norbind
2022-09-06 16:42:43 +03:00
check_rootidmap
2019-12-09 23:45:46 +03:00
check_notification_socket
2020-05-22 18:06:54 +03:00
check_os_release
2019-12-09 23:45:46 +03:00
for api_vfs_writable in yes no network; do
run no no $api_vfs_writable
run yes no $api_vfs_writable
run no yes $api_vfs_writable
run yes yes $api_vfs_writable
done
2021-01-14 02:52:00 +03:00
check_machinectl_bind
2021-07-14 21:29:37 +03:00
check_selinux
2022-04-18 19:39:18 +03:00
check_ephemeral_config
2019-12-09 23:45:46 +03:00
touch /testok