2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 # shellcheck disable=SC2016
7 # shellcheck source=test/units/util.sh
8 .
"$(dirname "$0")"/util.sh
10 systemd-run
--help --no-pager
12 systemd-run
--no-ask-password true
13 systemd-run
--no-block --collect true
16 touch /tmp
/public-marker
18 : "Transient service (system daemon)"
19 systemd-run
--wait --pipe \
20 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
21 systemd-run
--wait --pipe --system \
22 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
23 systemd-run
--wait --pipe --slice=foo \
24 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.service$ ]]'
25 systemd-run
--wait --pipe --slice=foo.slice \
26 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.service$ ]]'
27 systemd-run
--wait --pipe --slice-inherit \
28 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
29 systemd-run
--wait --pipe --slice-inherit --slice=foo \
30 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/system-foo\.slice/run-.+\.service$ ]]'
31 # We should not inherit caller's environment
32 systemd-run
--wait --pipe bash
-xec '[[ -z "$PARENT_FOO" ]]'
33 systemd-run
--wait --pipe bash
-xec '[[ "$PWD" == / && -n "$INVOCATION_ID" ]]'
34 systemd-run
--wait --pipe \
36 --working-directory="" \
37 --working-directory=/tmp \
38 bash
-xec '[[ "$PWD" == /tmp ]]'
39 systemd-run
--wait --pipe --same-dir bash
-xec "[[ \"\$PWD\" == $PWD ]]"
40 systemd-run
--wait --pipe \
41 --property=LimitCORE
=1M
:2M \
42 --property=LimitCORE
=16M
:32M \
43 --property=PrivateTmp
=yes \
44 bash
-xec '[[ "$(ulimit -c -S)" -eq 16384 && "$(ulimit -c -H)" -eq 32768 && ! -e /tmp/public-marker ]]'
45 systemd-run
--wait --pipe \
47 bash
-xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == testuser ]]'
48 systemd-run
--wait --pipe \
50 bash
-xec '[[ "$(id -nu)" == root && "$(id -ng)" == testuser ]]'
51 systemd-run
--wait --pipe \
54 bash
-xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == root ]]'
55 systemd-run
--wait --pipe --expand-environment=no \
57 bash
-xec 'read -r -a SELF_STAT </proc/self/stat && [[ "${SELF_STAT[18]}" -eq 10 ]]'
58 systemd-run
--wait --pipe \
59 --setenv=ENV_HELLO
="nope" \
60 --setenv=ENV_HELLO
="env world" \
63 --property=Environment
="ALSO_HELLO='also world'" \
64 bash
-xec '[[ "$ENV_HELLO" == "env world" && -z "$EMPTY" && "$PARENT_FOO" == bar && "$ALSO_HELLO" == "also world" ]]'
66 UNIT
="service-0-$RANDOM"
67 systemd-run
--remain-after-exit --unit="$UNIT" \
68 --service-type=simple \
69 --service-type=oneshot \
72 grep -q "^Type=oneshot" "/run/systemd/transient/$UNIT.service"
73 systemctl stop
"$UNIT"
74 (! systemctl
cat "$UNIT")
76 : "Transient service (user daemon)"
77 systemd-run
--wait --pipe --user --machine=testuser@ \
78 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /user\.slice/.+/run-.+\.service$ ]]'
79 systemd-run
--wait --pipe --user --machine=testuser@ \
80 bash
-xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == testuser ]]'
81 systemd-run
--wait --pipe --user --machine=testuser@ \
82 bash
-xec '[[ "$PWD" == /home/testuser && -n "$INVOCATION_ID" ]]'
83 systemd-run
--wait --pipe --user --machine=testuser@ \
84 --property=LimitCORE
=1M
:2M \
85 --property=LimitCORE
=16M
:32M \
86 --property=PrivateTmp
=yes \
87 bash
-xec '[[ "$(ulimit -c -S)" -eq 16384 && "$(ulimit -c -H)" -eq 32768 && ! -e /tmp/public-marker ]]'
89 : "Transient scope (system daemon)"
91 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
92 systemd-run
--scope --system \
93 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
94 systemd-run
--scope --slice=foo \
95 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.scope$ ]]'
96 systemd-run
--scope --slice=foo.slice \
97 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.scope$ ]]'
98 systemd-run
--scope --slice-inherit \
99 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
100 systemd-run
--scope --slice-inherit --slice=foo \
101 bash
-xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/system-foo\.slice/run-.+\.scope$ ]]'
102 # We should inherit caller's environment
103 systemd-run
--scope bash
-xec '[[ "$PARENT_FOO" == bar ]]'
104 systemd-run
--scope \
105 --property=RuntimeMaxSec
=10 \
106 --property=RuntimeMaxSec
=infinity \
109 : "Transient scope (user daemon)"
110 # FIXME: https://github.com/systemd/systemd/issues/27883
111 #systemd-run --scope --user --machine=testuser@ \
112 # bash -xec '[[ "$(</proc/self/cgroup)" =~ /user\.slice/run-.+\.scope$ ]]'
113 # We should inherit caller's environment
114 #systemd-run --scope --user --machine=testuser@ bash -xec '[[ "$PARENT_FOO" == bar ]]'
116 : "Transient timer unit"
117 UNIT
="timer-0-$RANDOM"
118 systemd-run
--remain-after-exit \
120 --timer-property=OnUnitInactiveSec
=16h \
122 systemctl
cat "$UNIT.service" "$UNIT.timer"
123 grep -q "^OnUnitInactiveSec=16h$" "/run/systemd/transient/$UNIT.timer"
124 grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
125 systemctl stop
"$UNIT.timer" "$UNIT.service" ||
:
127 UNIT
="timer-1-$RANDOM"
128 systemd-run
--remain-after-exit \
134 --on-unit-active=3h20m \
135 --on-unit-inactive="5d 4m 32s" \
136 --on-calendar="mon,fri *-1/2-1,3 *:30:45" \
139 --on-timezone-change \
140 --timer-property=After
=systemd-journald.service \
141 --description="Hello world" \
142 --description="My Fancy Timer" \
144 systemctl
cat "$UNIT.service" "$UNIT.timer"
145 systemd-analyze verify
--recursive-errors=no
"/run/systemd/transient/$UNIT.service"
146 systemd-analyze verify
--recursive-errors=no
"/run/systemd/transient/$UNIT.timer"
147 grep -q "^Description=My Fancy Timer$" "/run/systemd/transient/$UNIT.timer"
148 grep -q "^OnActiveSec=10s$" "/run/systemd/transient/$UNIT.timer"
149 grep -q "^OnActiveSec=30s$" "/run/systemd/transient/$UNIT.timer"
150 grep -q "^OnBootSec=1s$" "/run/systemd/transient/$UNIT.timer"
151 grep -q "^OnStartupSec=2min$" "/run/systemd/transient/$UNIT.timer"
152 grep -q "^OnUnitActiveSec=3h 20min$" "/run/systemd/transient/$UNIT.timer"
153 grep -q "^OnUnitInactiveSec=5d 4min 32s$" "/run/systemd/transient/$UNIT.timer"
154 grep -q "^OnCalendar=mon,fri \*\-1/2\-1,3 \*:30:45$" "/run/systemd/transient/$UNIT.timer"
155 grep -q "^OnClockChange=yes$" "/run/systemd/transient/$UNIT.timer"
156 grep -q "^OnTimezoneChange=yes$" "/run/systemd/transient/$UNIT.timer"
157 grep -q "^After=systemd-journald.service$" "/run/systemd/transient/$UNIT.timer"
158 grep -q "^Description=My Fancy Timer$" "/run/systemd/transient/$UNIT.service"
159 grep -q "^RemainAfterExit=yes$" "/run/systemd/transient/$UNIT.service"
160 grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
161 (! grep -q "^After=systemd-journald.service$" "/run/systemd/transient/$UNIT.service")
162 systemctl stop
"$UNIT.timer" "$UNIT.service" ||
:
164 : "Transient path unit"
165 UNIT
="path-0-$RANDOM"
166 systemd-run
--remain-after-exit \
168 --path-property=PathExists
=/tmp \
169 --path-property=PathExists
=/tmp
/foo \
170 --path-property=PathChanged
=/root
/bar \
172 systemctl
cat "$UNIT.service" "$UNIT.path"
173 systemd-analyze verify
--recursive-errors=no
"/run/systemd/transient/$UNIT.service"
174 systemd-analyze verify
--recursive-errors=no
"/run/systemd/transient/$UNIT.path"
175 grep -q "^PathExists=/tmp$" "/run/systemd/transient/$UNIT.path"
176 grep -q "^PathExists=/tmp/foo$" "/run/systemd/transient/$UNIT.path"
177 grep -q "^PathChanged=/root/bar$" "/run/systemd/transient/$UNIT.path"
178 grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
179 systemctl stop
"$UNIT.path" "$UNIT.service" ||
:
181 : "Transient socket unit"
182 UNIT
="socket-0-$RANDOM"
183 systemd-run
--remain-after-exit \
185 --socket-property=ListenFIFO
=/tmp
/socket.fifo \
186 --socket-property=SocketMode
=0666 \
187 --socket-property=SocketMode
=0644 \
189 systemctl
cat "$UNIT.service" "$UNIT.socket"
190 systemd-analyze verify
--recursive-errors=no
"/run/systemd/transient/$UNIT.service"
191 systemd-analyze verify
--recursive-errors=no
"/run/systemd/transient/$UNIT.socket"
192 grep -q "^ListenFIFO=/tmp/socket.fifo$" "/run/systemd/transient/$UNIT.socket"
193 grep -q "^SocketMode=0666$" "/run/systemd/transient/$UNIT.socket"
194 grep -q "^SocketMode=0644$" "/run/systemd/transient/$UNIT.socket"
195 grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
196 systemctl stop
"$UNIT.socket" "$UNIT.service" ||
:
198 : "Interactive options"
199 SHELL
=/bin
/true systemd-run
--shell
200 SHELL
=/bin
/true systemd-run
--scope --shell
201 systemd-run
--wait --pty true
202 systemd-run
--wait --machine=.
host --pty true
203 (! SHELL
=/bin
/false systemd-run
--quiet --shell)
207 (! systemd-run
--foo=bar
)
208 (! systemd-run
--wait --pipe --slice=foo.service true
)
210 for opt
in nice on-
{active
,boot
,calendar
,startup
,unit-active
,unit-inactive
} property service-type setenv
; do
211 (! systemd-run
"--$opt=" true
)
212 (! systemd-run
"--$opt=''" true
)
215 # Let's make sure that ProtectProc= properly moves submounts of the original /proc over to the new proc
217 A
=$
(cat /proc
/sys
/kernel
/random
/boot_id
)
218 B
=$
(systemd-run
-q --wait --pipe -p ProtectProc
=invisible
cat /proc
/sys
/kernel
/random
/boot_id
)
221 V
="/tmp/version.$RANDOM"
222 A
="$(cat /proc/version).piff"
224 mount
--bind "$V" /proc
/version
226 B
=$
(systemd-run
-q --wait --pipe -p ProtectProc
=invisible
cat /proc
/version
)