1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-09 01:18:19 +03:00
systemd/test/units/testsuite-74.run.sh
Nick Rosbrook 6327d30224 test: skip a systemd-run test if unprivileged userns is restricted
With newer versions of AppArmor, unprivileged user namespace creation
may be restricted by default, in which case user manager instances will
not be able to apply PrivateUsers=yes, which is implied by
PrivateTmp=yes in this systemd-run invocation.
2024-01-19 10:21:57 -05:00

246 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# shellcheck disable=SC2016
set -eux
set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
systemd-run --help --no-pager
systemd-run --version
systemd-run --no-ask-password true
systemd-run --no-block --collect true
export PARENT_FOO=bar
touch /tmp/public-marker
: "Transient service (system daemon)"
systemd-run --wait --pipe \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --system \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --slice=foo \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --slice=foo.slice \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --slice-inherit \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --slice-inherit --slice=foo \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/system-foo\.slice/run-.+\.service$ ]]'
# We should not inherit caller's environment
systemd-run --wait --pipe bash -xec '[[ -z "$PARENT_FOO" ]]'
systemd-run --wait --pipe bash -xec '[[ "$PWD" == / && -n "$INVOCATION_ID" ]]'
systemd-run --wait --pipe \
--send-sighup \
--working-directory="" \
--working-directory=/tmp \
bash -xec '[[ "$PWD" == /tmp ]]'
systemd-run --wait --pipe --same-dir bash -xec "[[ \"\$PWD\" == $PWD ]]"
systemd-run --wait --pipe \
--property=LimitCORE=1M:2M \
--property=LimitCORE=16M:32M \
--property=PrivateTmp=yes \
bash -xec '[[ "$(ulimit -c -S)" -eq 16384 && "$(ulimit -c -H)" -eq 32768 && ! -e /tmp/public-marker ]]'
systemd-run --wait --pipe \
--uid=testuser \
bash -xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == testuser ]]'
systemd-run --wait --pipe \
--gid=testuser \
bash -xec '[[ "$(id -nu)" == root && "$(id -ng)" == testuser ]]'
systemd-run --wait --pipe \
--uid=testuser \
--gid=root \
bash -xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == root ]]'
systemd-run --wait --pipe --expand-environment=no \
--nice=10 \
bash -xec 'read -r -a SELF_STAT </proc/self/stat && [[ "${SELF_STAT[18]}" -eq 10 ]]'
systemd-run --wait --pipe \
--setenv=ENV_HELLO="nope" \
--setenv=ENV_HELLO="env world" \
--setenv=EMPTY= \
--setenv=PARENT_FOO \
--property=Environment="ALSO_HELLO='also world'" \
bash -xec '[[ "$ENV_HELLO" == "env world" && -z "$EMPTY" && "$PARENT_FOO" == bar && "$ALSO_HELLO" == "also world" ]]'
UNIT="service-0-$RANDOM"
systemd-run --remain-after-exit --unit="$UNIT" \
--service-type=simple \
--service-type=oneshot \
true
systemctl cat "$UNIT"
grep -q "^Type=oneshot" "/run/systemd/transient/$UNIT.service"
systemctl stop "$UNIT"
(! systemctl cat "$UNIT")
: "Transient service (user daemon)"
systemd-run --wait --pipe --user --machine=testuser@ \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /user\.slice/.+/run-.+\.service$ ]]'
systemd-run --wait --pipe --user --machine=testuser@ \
bash -xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == testuser ]]'
systemd-run --wait --pipe --user --machine=testuser@ \
bash -xec '[[ "$PWD" == /home/testuser && -n "$INVOCATION_ID" ]]'
# PrivateTmp=yes implies PrivateUsers=yes for user manager, so skip this if we
# don't have unprivileged user namespaces.
if [[ "$(sysctl -ne kernel.apparmor_restrict_unprivileged_userns)" -ne 1 ]]; then
systemd-run --wait --pipe --user --machine=testuser@ \
--property=LimitCORE=1M:2M \
--property=LimitCORE=16M:32M \
--property=PrivateTmp=yes \
bash -xec '[[ "$(ulimit -c -S)" -eq 16384 && "$(ulimit -c -H)" -eq 32768 && ! -e /tmp/public-marker ]]'
fi
: "Transient scope (system daemon)"
systemd-run --scope \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
systemd-run --scope --system \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
systemd-run --scope --slice=foo \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.scope$ ]]'
systemd-run --scope --slice=foo.slice \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.scope$ ]]'
systemd-run --scope --slice-inherit \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
systemd-run --scope --slice-inherit --slice=foo \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/system-foo\.slice/run-.+\.scope$ ]]'
# We should inherit caller's environment
systemd-run --scope bash -xec '[[ "$PARENT_FOO" == bar ]]'
systemd-run --scope \
--property=RuntimeMaxSec=10 \
--property=RuntimeMaxSec=infinity \
true
: "Transient scope (user daemon)"
# FIXME: https://github.com/systemd/systemd/issues/27883
#systemd-run --scope --user --machine=testuser@ \
# bash -xec '[[ "$(</proc/self/cgroup)" =~ /user\.slice/run-.+\.scope$ ]]'
# We should inherit caller's environment
#systemd-run --scope --user --machine=testuser@ bash -xec '[[ "$PARENT_FOO" == bar ]]'
: "Transient timer unit"
UNIT="timer-0-$RANDOM"
systemd-run --remain-after-exit \
--unit="$UNIT" \
--timer-property=OnUnitInactiveSec=16h \
true
systemctl cat "$UNIT.service" "$UNIT.timer"
grep -q "^OnUnitInactiveSec=16h$" "/run/systemd/transient/$UNIT.timer"
grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
systemctl stop "$UNIT.timer" "$UNIT.service" || :
UNIT="timer-1-$RANDOM"
systemd-run --remain-after-exit \
--unit="$UNIT" \
--on-active=10 \
--on-active=30s \
--on-boot=1s \
--on-startup=2m \
--on-unit-active=3h20m \
--on-unit-inactive="5d 4m 32s" \
--on-calendar="mon,fri *-1/2-1,3 *:30:45" \
--on-clock-change \
--on-clock-change \
--on-timezone-change \
--timer-property=After=systemd-journald.service \
--description="Hello world" \
--description="My Fancy Timer" \
true
systemctl cat "$UNIT.service" "$UNIT.timer"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.service"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.timer"
grep -q "^Description=My Fancy Timer$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnActiveSec=10s$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnActiveSec=30s$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnBootSec=1s$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnStartupSec=2min$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnUnitActiveSec=3h 20min$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnUnitInactiveSec=5d 4min 32s$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnCalendar=mon,fri \*\-1/2\-1,3 \*:30:45$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnClockChange=yes$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnTimezoneChange=yes$" "/run/systemd/transient/$UNIT.timer"
grep -q "^After=systemd-journald.service$" "/run/systemd/transient/$UNIT.timer"
grep -q "^Description=My Fancy Timer$" "/run/systemd/transient/$UNIT.service"
grep -q "^RemainAfterExit=yes$" "/run/systemd/transient/$UNIT.service"
grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
(! grep -q "^After=systemd-journald.service$" "/run/systemd/transient/$UNIT.service")
systemctl stop "$UNIT.timer" "$UNIT.service" || :
: "Transient path unit"
UNIT="path-0-$RANDOM"
systemd-run --remain-after-exit \
--unit="$UNIT" \
--path-property=PathExists=/tmp \
--path-property=PathExists=/tmp/foo \
--path-property=PathChanged=/root/bar \
true
systemctl cat "$UNIT.service" "$UNIT.path"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.service"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.path"
grep -q "^PathExists=/tmp$" "/run/systemd/transient/$UNIT.path"
grep -q "^PathExists=/tmp/foo$" "/run/systemd/transient/$UNIT.path"
grep -q "^PathChanged=/root/bar$" "/run/systemd/transient/$UNIT.path"
grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
systemctl stop "$UNIT.path" "$UNIT.service" || :
: "Transient socket unit"
UNIT="socket-0-$RANDOM"
systemd-run --remain-after-exit \
--unit="$UNIT" \
--socket-property=ListenFIFO=/tmp/socket.fifo \
--socket-property=SocketMode=0666 \
--socket-property=SocketMode=0644 \
true
systemctl cat "$UNIT.service" "$UNIT.socket"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.service"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.socket"
grep -q "^ListenFIFO=/tmp/socket.fifo$" "/run/systemd/transient/$UNIT.socket"
grep -q "^SocketMode=0666$" "/run/systemd/transient/$UNIT.socket"
grep -q "^SocketMode=0644$" "/run/systemd/transient/$UNIT.socket"
grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
systemctl stop "$UNIT.socket" "$UNIT.service" || :
: "Interactive options"
SHELL=/bin/true systemd-run --shell
SHELL=/bin/true systemd-run --scope --shell
systemd-run --wait --pty true
systemd-run --wait --machine=.host --pty true
(! SHELL=/bin/false systemd-run --quiet --shell)
(! systemd-run)
(! systemd-run "")
(! systemd-run --foo=bar)
(! systemd-run --wait --pipe --slice=foo.service true)
for opt in nice on-{active,boot,calendar,startup,unit-active,unit-inactive} property service-type setenv; do
(! systemd-run "--$opt=" true)
(! systemd-run "--$opt=''" true)
done
# Let's make sure that ProtectProc= properly moves submounts of the original /proc over to the new proc
BOOT_ID="$(</proc/sys/kernel/random/boot_id)"
UNIT_BOOT_ID="$(systemd-run -q --wait --pipe -p ProtectProc=invisible cat /proc/sys/kernel/random/boot_id)"
assert_eq "$BOOT_ID" "$UNIT_BOOT_ID"
TMP_KVER="/tmp/version.$RANDOM"
KVER="$(</proc/version).piff"
echo "$KVER" >"$TMP_KVER"
mount --bind "$TMP_KVER" /proc/version
UNIT_KVER="$(systemd-run -q --wait --pipe -p ProtectProc=invisible cat /proc/version)"
assert_eq "$KVER" "$UNIT_KVER"
umount /proc/version
rm -f "$TMP_KVER"
# Check that invoking the tool under the uid0 alias name works
uid0 ls /
assert_eq "$(uid0 echo foo)" "foo"
# Check if we set some expected environment variables
for arg in "" "--user=root" "--user=testuser"; do
assert_eq "$(uid0 ${arg:+"$arg"} bash -c 'echo $SUDO_USER')" "$USER"
assert_eq "$(uid0 ${arg:+"$arg"} bash -c 'echo $SUDO_UID')" "$(id -u "$USER")"
assert_eq "$(uid0 ${arg:+"$arg"} bash -c 'echo $SUDO_GID')" "$(id -u "$USER")"
done
# Let's chain a couple of uid0 calls together, for fun
readarray -t cmdline < <(printf "%.0suid0\n" {0..31})
assert_eq "$("${cmdline[@]}" bash -c 'echo $SUDO_USER')" "$USER"