]>
Commit | Line | Data |
---|---|---|
378db9e2 FS |
1 | #!/usr/bin/env bash |
2 | # SPDX-License-Identifier: LGPL-2.1-or-later | |
3 | # shellcheck disable=SC2016 | |
28ed2326 FS |
4 | # |
5 | # Notes on coverage: when collecting coverage we need the $BUILD_DIR present | |
6 | # and writable in the container as well. To do this in the least intrusive way, | |
7 | # two things are going on in the background (only when built with -Db_coverage=true): | |
8 | # 1) the systemd-nspawn@.service is copied to /etc/systemd/system/ with | |
9 | # --bind=$BUILD_DIR appended to the ExecStart= line | |
10 | # 2) each create_dummy_container() call also creates an .nspawn file in /run/systemd/nspawn/ | |
11 | # with the last fragment from the path used as a name | |
12 | # | |
13 | # The first change is quite self-contained and applies only to containers run | |
14 | # with machinectl. The second one might cause some unexpected side-effects, namely: | |
15 | # - nspawn config (setting) files don't support dropins, so tests that test | |
16 | # the config files might need some tweaking (as seen below with | |
17 | # the $COVERAGE_BUILD_DIR shenanigans) since they overwrite the .nspawn file | |
18 | # - also a note - if /etc/systemd/nspawn/cont-name.nspawn exists, it takes | |
19 | # precedence and /run/systemd/nspawn/cont-name.nspawn won't be read even | |
20 | # if it exists | |
928733cd | 21 | # - also a note 2 - --bind= overrides any Bind= from a config file |
28ed2326 FS |
22 | # - in some cases we don't create a test container using create_dummy_container(), |
23 | # so in that case an explicit call to coverage_create_nspawn_dropin() is needed | |
928733cd FS |
24 | # |
25 | # However, even after jumping through all these hooks, there still might (and is) | |
26 | # some "incorrectly" missing coverage, especially in the window between spawning | |
27 | # the inner child process and bind-mounting the coverage $BUILD_DIR | |
378db9e2 FS |
28 | set -eux |
29 | set -o pipefail | |
30 | ||
b60d910d FS |
31 | # shellcheck source=test/units/test-control.sh |
32 | . "$(dirname "$0")"/test-control.sh | |
5656759d FS |
33 | # shellcheck source=test/units/util.sh |
34 | . "$(dirname "$0")"/util.sh | |
35 | ||
b60d910d | 36 | |
378db9e2 FS |
37 | export SYSTEMD_LOG_LEVEL=debug |
38 | export SYSTEMD_LOG_TARGET=journal | |
378db9e2 FS |
39 | |
40 | at_exit() { | |
41 | set +e | |
42 | ||
d4317fe1 | 43 | mountpoint -q /var/lib/machines && umount --recursive /var/lib/machines |
28ed2326 | 44 | rm -f /run/systemd/nspawn/*.nspawn |
378db9e2 FS |
45 | } |
46 | ||
47 | trap at_exit EXIT | |
48 | ||
49 | # check cgroup-v2 | |
50 | IS_CGROUPSV2_SUPPORTED=no | |
51 | mkdir -p /tmp/cgroup2 | |
52 | if mount -t cgroup2 cgroup2 /tmp/cgroup2; then | |
53 | IS_CGROUPSV2_SUPPORTED=yes | |
54 | umount /tmp/cgroup2 | |
55 | fi | |
56 | rmdir /tmp/cgroup2 | |
57 | ||
58 | # check cgroup namespaces | |
59 | IS_CGNS_SUPPORTED=no | |
60 | if [[ -f /proc/1/ns/cgroup ]]; then | |
61 | IS_CGNS_SUPPORTED=yes | |
62 | fi | |
63 | ||
64 | IS_USERNS_SUPPORTED=no | |
65 | # On some systems (e.g. CentOS 7) the default limit for user namespaces | |
66 | # is set to 0, which causes the following unshare syscall to fail, even | |
67 | # with enabled user namespaces support. By setting this value explicitly | |
68 | # we can ensure the user namespaces support to be detected correctly. | |
69 | sysctl -w user.max_user_namespaces=10000 | |
5656759d | 70 | if unshare -U bash -c :; then |
378db9e2 FS |
71 | IS_USERNS_SUPPORTED=yes |
72 | fi | |
73 | ||
74 | # Mount tmpfs over /var/lib/machines to not pollute the image | |
75 | mkdir -p /var/lib/machines | |
76 | mount -t tmpfs tmpfs /var/lib/machines | |
77 | ||
cf260f79 | 78 | testcase_sanity() { |
0d5896a9 | 79 | local template root image uuid tmpdir |
70376640 | 80 | |
806b1824 | 81 | tmpdir="$(mktemp -d)" |
70376640 | 82 | template="$(mktemp -d /tmp/nspawn-template.XXX)" |
5656759d | 83 | create_dummy_container "$template" |
70376640 FS |
84 | # Create a simple image from the just created container template |
85 | image="$(mktemp /var/lib/machines/testsuite-13.image-XXX.img)" | |
256c1ac9 | 86 | dd if=/dev/zero of="$image" bs=1M count=64 |
70376640 FS |
87 | mkfs.ext4 "$image" |
88 | mkdir -p /mnt | |
89 | mount -o loop "$image" /mnt | |
90 | cp -r "$template"/* /mnt/ | |
91 | umount /mnt | |
70376640 FS |
92 | |
93 | systemd-nspawn --help --no-pager | |
94 | systemd-nspawn --version | |
95 | ||
96 | # --template= | |
97 | root="$(mktemp -u -d /var/lib/machines/testsuite-13.sanity.XXX)" | |
28ed2326 | 98 | coverage_create_nspawn_dropin "$root" |
5656759d | 99 | (! systemd-nspawn --directory="$root" bash -xec 'echo hello') |
70376640 FS |
100 | # Initialize $root from $template (the $root directory must not exist, hence |
101 | # the `mktemp -u` above) | |
5656759d FS |
102 | systemd-nspawn --directory="$root" --template="$template" bash -xec 'echo hello' |
103 | systemd-nspawn --directory="$root" bash -xec 'echo hello; touch /initialized' | |
70376640 FS |
104 | test -e "$root/initialized" |
105 | # Check if the $root doesn't get re-initialized once it's not empty | |
5656759d | 106 | systemd-nspawn --directory="$root" --template="$template" bash -xec 'echo hello' |
70376640 FS |
107 | test -e "$root/initialized" |
108 | ||
5656759d | 109 | systemd-nspawn --directory="$root" --ephemeral bash -xec 'touch /ephemeral' |
70376640 | 110 | test ! -e "$root/ephemeral" |
806b1824 | 111 | (! systemd-nspawn --directory="$root" \ |
806b1824 | 112 | --read-only \ |
5656759d | 113 | bash -xec 'touch /nope') |
70376640 | 114 | test ! -e "$root/nope" |
5656759d | 115 | systemd-nspawn --image="$image" bash -xec 'echo hello' |
70376640 FS |
116 | |
117 | # --volatile= | |
118 | touch "$root/usr/has-usr" | |
119 | # volatile(=yes): rootfs is tmpfs, /usr/ from the OS tree is mounted read only | |
120 | systemd-nspawn --directory="$root"\ | |
121 | --volatile \ | |
5656759d | 122 | bash -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope' |
70376640 FS |
123 | test ! -e "$root/nope" |
124 | test ! -e "$root/usr/read-only" | |
125 | systemd-nspawn --directory="$root"\ | |
126 | --volatile=yes \ | |
5656759d | 127 | bash -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope' |
70376640 FS |
128 | test ! -e "$root/nope" |
129 | test ! -e "$root/usr/read-only" | |
130 | # volatile=state: rootfs is read-only, /var/ is tmpfs | |
131 | systemd-nspawn --directory="$root" \ | |
132 | --volatile=state \ | |
5656759d | 133 | bash -xec 'test -e /usr/has-usr; mountpoint /var; touch /read-only && exit 1; touch /var/nope' |
70376640 FS |
134 | test ! -e "$root/read-only" |
135 | test ! -e "$root/var/nope" | |
136 | # volatile=state: tmpfs overlay is mounted over rootfs | |
137 | systemd-nspawn --directory="$root" \ | |
138 | --volatile=overlay \ | |
5656759d | 139 | bash -xec 'test -e /usr/has-usr; touch /nope; touch /var/also-nope; touch /usr/nope-too' |
70376640 FS |
140 | test ! -e "$root/nope" |
141 | test ! -e "$root/var/also-nope" | |
142 | test ! -e "$root/usr/nope-too" | |
143 | ||
144 | # --machine=, --hostname= | |
145 | systemd-nspawn --directory="$root" \ | |
146 | --machine="foo-bar.baz" \ | |
5656759d | 147 | bash -xec '[[ $(hostname) == foo-bar.baz ]]' |
70376640 FS |
148 | systemd-nspawn --directory="$root" \ |
149 | --hostname="hello.world.tld" \ | |
5656759d | 150 | bash -xec '[[ $(hostname) == hello.world.tld ]]' |
70376640 FS |
151 | systemd-nspawn --directory="$root" \ |
152 | --machine="foo-bar.baz" \ | |
153 | --hostname="hello.world.tld" \ | |
5656759d | 154 | bash -xec '[[ $(hostname) == hello.world.tld ]]' |
70376640 FS |
155 | |
156 | # --uuid= | |
157 | rm -f "$root/etc/machine-id" | |
158 | uuid="deadbeef-dead-dead-beef-000000000000" | |
159 | systemd-nspawn --directory="$root" \ | |
160 | --uuid="$uuid" \ | |
5656759d | 161 | bash -xec "[[ \$container_uuid == $uuid ]]" |
70376640 FS |
162 | |
163 | # --as-pid2 | |
5656759d FS |
164 | systemd-nspawn --directory="$root" bash -xec '[[ $$ -eq 1 ]]' |
165 | systemd-nspawn --directory="$root" --as-pid2 bash -xec '[[ $$ -eq 2 ]]' | |
70376640 FS |
166 | |
167 | # --user= | |
5656759d FS |
168 | # "Fake" getent passwd's bare minimum, so we don't have to pull it in |
169 | # with all the DSO shenanigans | |
170 | cat >"$root/bin/getent" <<\EOF | |
171 | #!/bin/bash | |
172 | ||
173 | if [[ $# -eq 0 ]]; then | |
174 | : | |
175 | elif [[ $1 == passwd ]]; then | |
176 | echo "testuser:x:1000:1000:testuser:/:/bin/sh" | |
177 | elif [[ $1 == initgroups ]]; then | |
178 | echo "testuser" | |
179 | fi | |
180 | EOF | |
181 | chmod +x "$root/bin/getent" | |
182 | systemd-nspawn --directory="$root" bash -xec '[[ $USER == root ]]' | |
183 | systemd-nspawn --directory="$root" --user=testuser bash -xec '[[ $USER == testuser ]]' | |
70376640 FS |
184 | |
185 | # --settings= + .nspawn files | |
186 | mkdir -p /run/systemd/nspawn/ | |
187 | uuid="deadbeef-dead-dead-beef-000000000000" | |
188 | echo -ne "[Exec]\nMachineID=deadbeef-dead-dead-beef-111111111111" >/run/systemd/nspawn/foo-bar.nspawn | |
189 | systemd-nspawn --directory="$root" \ | |
190 | --machine=foo-bar \ | |
191 | --settings=yes \ | |
5656759d | 192 | bash -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]' |
70376640 FS |
193 | systemd-nspawn --directory="$root" \ |
194 | --machine=foo-bar \ | |
195 | --uuid="$uuid" \ | |
196 | --settings=yes \ | |
5656759d | 197 | bash -xec "[[ \$container_uuid == $uuid ]]" |
70376640 FS |
198 | systemd-nspawn --directory="$root" \ |
199 | --machine=foo-bar \ | |
200 | --uuid="$uuid" \ | |
201 | --settings=override \ | |
5656759d | 202 | bash -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]' |
70376640 FS |
203 | systemd-nspawn --directory="$root" \ |
204 | --machine=foo-bar \ | |
205 | --uuid="$uuid" \ | |
206 | --settings=trusted \ | |
5656759d | 207 | bash -xec "[[ \$container_uuid == $uuid ]]" |
70376640 FS |
208 | |
209 | # Mounts | |
70376640 FS |
210 | mkdir "$tmpdir"/{1,2,3} |
211 | touch "$tmpdir/1/one" "$tmpdir/2/two" "$tmpdir/3/three" | |
212 | touch "$tmpdir/foo" | |
213 | # --bind= | |
214 | systemd-nspawn --directory="$root" \ | |
928733cd | 215 | ${COVERAGE_BUILD_DIR:+--bind="$COVERAGE_BUILD_DIR"} \ |
70376640 | 216 | --bind="$tmpdir:/foo" \ |
928733cd FS |
217 | --bind="$tmpdir:/also-foo:noidmap,norbind" \ |
218 | bash -xec 'test -e /foo/foo; touch /foo/bar; test -e /also-foo/bar' | |
70376640 FS |
219 | test -e "$tmpdir/bar" |
220 | # --bind-ro= | |
221 | systemd-nspawn --directory="$root" \ | |
222 | --bind-ro="$tmpdir:/foo" \ | |
928733cd FS |
223 | --bind-ro="$tmpdir:/bar:noidmap,norbind" \ |
224 | bash -xec 'test -e /foo/foo; touch /foo/baz && exit 1; touch /bar && exit 1; true' | |
70376640 FS |
225 | # --inaccessible= |
226 | systemd-nspawn --directory="$root" \ | |
227 | --inaccessible=/var \ | |
5656759d | 228 | bash -xec 'touch /var/foo && exit 1; true' |
70376640 FS |
229 | # --tmpfs= |
230 | systemd-nspawn --directory="$root" \ | |
231 | --tmpfs=/var:rw,nosuid,noexec \ | |
5656759d | 232 | bash -xec 'touch /var/nope' |
70376640 FS |
233 | test ! -e "$root/var/nope" |
234 | # --overlay= | |
235 | systemd-nspawn --directory="$root" \ | |
236 | --overlay="$tmpdir/1:$tmpdir/2:$tmpdir/3:/var" \ | |
5656759d | 237 | bash -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/foo' |
70376640 FS |
238 | test -e "$tmpdir/3/foo" |
239 | # --overlay-ro= | |
240 | systemd-nspawn --directory="$root" \ | |
241 | --overlay-ro="$tmpdir/1:$tmpdir/2:$tmpdir/3:/var" \ | |
5656759d | 242 | bash -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/nope && exit 1; true' |
70376640 FS |
243 | test ! -e "$tmpdir/3/nope" |
244 | rm -fr "$tmpdir" | |
245 | ||
74696ba5 FS |
246 | # --port (sanity only) |
247 | systemd-nspawn --network-veth --directory="$root" --port=80 --port=90 true | |
248 | systemd-nspawn --network-veth --directory="$root" --port=80:8080 true | |
249 | systemd-nspawn --network-veth --directory="$root" --port=tcp:80 true | |
250 | systemd-nspawn --network-veth --directory="$root" --port=tcp:80:8080 true | |
251 | systemd-nspawn --network-veth --directory="$root" --port=udp:80 true | |
252 | systemd-nspawn --network-veth --directory="$root" --port=udp:80:8080 --port=tcp:80:8080 true | |
253 | (! systemd-nspawn --network-veth --directory="$root" --port= true) | |
254 | (! systemd-nspawn --network-veth --directory="$root" --port=-1 true) | |
255 | (! systemd-nspawn --network-veth --directory="$root" --port=: true) | |
256 | (! systemd-nspawn --network-veth --directory="$root" --port=icmp:80:8080 true) | |
257 | (! systemd-nspawn --network-veth --directory="$root" --port=tcp::8080 true) | |
258 | (! systemd-nspawn --network-veth --directory="$root" --port=8080: true) | |
928733cd FS |
259 | # Exercise adding/removing ports from an interface |
260 | systemd-nspawn --directory="$root" \ | |
261 | --network-veth \ | |
262 | --port=6667 \ | |
263 | --port=80:8080 \ | |
264 | --port=udp:53 \ | |
265 | --port=tcp:22:2222 \ | |
266 | bash -xec 'ip addr add dev host0 10.0.0.10/24; ip a; ip addr del dev host0 10.0.0.10/24' | |
267 | ||
268 | # --load-credential=, --set-credential= | |
269 | echo "foo bar" >/tmp/cred.path | |
270 | systemd-nspawn --directory="$root" \ | |
271 | --load-credential=cred.path:/tmp/cred.path \ | |
272 | --set-credential="cred.set:hello world" \ | |
273 | bash -xec '[[ "$(</run/host/credentials/cred.path)" == "foo bar" ]]; [[ "$(</run/host/credentials/cred.set)" == "hello world" ]]' | |
274 | rm -f /tmp/cred.path | |
74696ba5 | 275 | |
70376640 | 276 | # Assorted tests |
5656759d | 277 | systemd-nspawn --directory="$root" --suppress-sync=yes bash -xec 'echo hello' |
70376640 FS |
278 | systemd-nspawn --capability=help |
279 | systemd-nspawn --resolv-conf=help | |
280 | systemd-nspawn --timezone=help | |
281 | ||
282 | # Handling of invalid arguments | |
283 | opts=( | |
284 | bind | |
285 | bind-ro | |
286 | bind-user | |
287 | chdir | |
288 | console | |
289 | inaccessible | |
290 | kill-signal | |
291 | link-journal | |
292 | load-credential | |
293 | network-{interface,macvlan,ipvlan,veth-extra,bridge,zone} | |
294 | no-new-privileges | |
295 | oom-score-adjust | |
296 | overlay | |
297 | overlay-ro | |
298 | personality | |
299 | pivot-root | |
300 | port | |
301 | private-users | |
302 | private-users-ownership | |
303 | register | |
304 | resolv-conf | |
305 | rlimit | |
306 | root-hash | |
307 | root-hash-sig | |
308 | set-credential | |
309 | settings | |
310 | suppress-sync | |
311 | timezone | |
312 | tmpfs | |
313 | uuid | |
314 | ) | |
315 | for opt in "${opts[@]}"; do | |
316 | (! systemd-nspawn "--$opt") | |
317 | [[ "$opt" == network-zone ]] && continue | |
318 | (! systemd-nspawn "--$opt=''") | |
319 | (! systemd-nspawn "--$opt=%\$Å¡") | |
320 | done | |
321 | (! systemd-nspawn --volatile="") | |
322 | (! systemd-nspawn --volatile=-1) | |
323 | (! systemd-nspawn --rlimit==) | |
324 | } | |
325 | ||
cbd20ab4 | 326 | nspawn_settings_cleanup() { |
e8736fb6 | 327 | for dev in sd-host-only sd-shared{1,2,3} sd-macvlan{1,2} sd-ipvlan{1,2}; do |
cbd20ab4 FS |
328 | ip link del "$dev" || : |
329 | done | |
330 | ||
331 | return 0 | |
332 | } | |
333 | ||
334 | testcase_nspawn_settings() { | |
d2e8dc78 | 335 | local root container dev private_users wlan_names |
cbd20ab4 FS |
336 | |
337 | mkdir -p /run/systemd/nspawn | |
338 | root="$(mktemp -d /var/lib/machines/testsuite-13.nspawn-settings.XXX)" | |
339 | container="$(basename "$root")" | |
340 | create_dummy_container "$root" | |
341 | rm -f "/etc/systemd/nspawn/$container.nspawn" | |
342 | mkdir -p "$root/tmp" "$root"/opt/{tmp,inaccessible,also-inaccessible} | |
343 | ||
e8736fb6 YW |
344 | # add virtual wlan interfaces |
345 | if modprobe mac80211_hwsim radios=2; then | |
d2e8dc78 | 346 | wlan_names="wlan0 wlan1:wl-renamed1" |
e8736fb6 YW |
347 | fi |
348 | ||
349 | for dev in sd-host-only sd-shared{1,2,3} sd-macvlan{1,2} sd-macvlanloong sd-ipvlan{1,2} sd-ipvlanlooong; do | |
cbd20ab4 FS |
350 | ip link add "$dev" type dummy |
351 | done | |
352 | udevadm settle | |
e8736fb6 | 353 | ip link property add dev sd-shared3 altname sd-altname3 altname sd-altname-tooooooooooooo-long |
cbd20ab4 FS |
354 | ip link |
355 | trap nspawn_settings_cleanup RETURN | |
356 | ||
357 | # Let's start with one huge config to test as much as we can at once | |
358 | cat >"/run/systemd/nspawn/$container.nspawn" <<EOF | |
359 | [Exec] | |
360 | Boot=no | |
361 | Ephemeral=no | |
362 | ProcessTwo=no | |
363 | Parameters=bash /entrypoint.sh "foo bar" 'bar baz' | |
364 | Environment=FOO=bar | |
365 | Environment=BAZ="hello world" | |
366 | User=root | |
367 | WorkingDirectory=/tmp | |
368 | Capability=CAP_BLOCK_SUSPEND CAP_BPF CAP_CHOWN | |
369 | DropCapability=CAP_AUDIT_CONTROL CAP_AUDIT_WRITE | |
370 | AmbientCapability=CAP_BPF CAP_CHOWN | |
371 | NoNewPrivileges=no | |
372 | MachineID=f28f129b51874b1280a89421ec4b4ad4 | |
373 | PrivateUsers=no | |
374 | NotifyReady=no | |
375 | SystemCallFilter=@basic-io @chown | |
376 | SystemCallFilter=~ @clock | |
377 | LimitNOFILE=1024:2048 | |
378 | LimitRTPRIO=8:16 | |
379 | OOMScoreAdjust=32 | |
380 | CPUAffinity=0,0-5,1-5 | |
381 | Hostname=nspawn-settings | |
382 | ResolvConf=copy-host | |
383 | Timezone=delete | |
384 | LinkJournal=no | |
385 | SuppressSync=no | |
386 | ||
387 | [Files] | |
388 | ReadOnly=no | |
389 | Volatile=no | |
390 | TemporaryFileSystem=/tmp | |
391 | TemporaryFileSystem=/opt/tmp | |
392 | Inaccessible=/opt/inaccessible | |
393 | Inaccessible=/opt/also-inaccessible | |
394 | PrivateUsersOwnership=auto | |
395 | Overlay=+/var::/var | |
396 | ${COVERAGE_BUILD_DIR:+"Bind=$COVERAGE_BUILD_DIR"} | |
397 | ||
398 | [Network] | |
399 | Private=yes | |
400 | VirtualEthernet=yes | |
401 | VirtualEthernetExtra=my-fancy-veth1 | |
402 | VirtualEthernetExtra=fancy-veth2:my-fancy-veth2 | |
d2e8dc78 | 403 | Interface=sd-shared1 sd-shared2:sd-renamed2 sd-shared3:sd-altname3 ${wlan_names:-} |
927e20fa YW |
404 | MACVLAN=sd-macvlan1 sd-macvlan2:my-macvlan2 sd-macvlanloong |
405 | IPVLAN=sd-ipvlan1 sd-ipvlan2:my-ipvlan2 sd-ipvlanlooong | |
cbd20ab4 FS |
406 | Zone=sd-zone0 |
407 | Port=80 | |
408 | Port=81:8181 | |
409 | Port=tcp:60 | |
410 | Port=udp:60:61 | |
411 | EOF | |
412 | cat >"$root/entrypoint.sh" <<\EOF | |
7b1c2929 FS |
413 | #!/bin/bash |
414 | set -ex | |
cbd20ab4 | 415 | |
8ee32f68 FS |
416 | env |
417 | ||
cbd20ab4 FS |
418 | [[ "$1" == "foo bar" ]] |
419 | [[ "$2" == "bar baz" ]] | |
420 | ||
421 | [[ "$USER" == root ]] | |
422 | [[ "$FOO" == bar ]] | |
423 | [[ "$BAZ" == "hello world" ]] | |
424 | [[ "$PWD" == /tmp ]] | |
8ee32f68 | 425 | [[ "$container_uuid" == f28f129b-5187-4b12-80a8-9421ec4b4ad4 ]] |
cbd20ab4 FS |
426 | [[ "$(ulimit -S -n)" -eq 1024 ]] |
427 | [[ "$(ulimit -H -n)" -eq 2048 ]] | |
428 | [[ "$(ulimit -S -r)" -eq 8 ]] | |
429 | [[ "$(ulimit -H -r)" -eq 16 ]] | |
430 | [[ "$(</proc/self/oom_score_adj)" -eq 32 ]] | |
431 | [[ "$(hostname)" == nspawn-settings ]] | |
432 | [[ -e /etc/resolv.conf ]] | |
433 | [[ ! -e /etc/localtime ]] | |
434 | ||
435 | mountpoint /tmp | |
436 | touch /tmp/foo | |
437 | mountpoint /opt/tmp | |
438 | touch /opt/tmp/foo | |
439 | touch /opt/inaccessible/foo && exit 1 | |
440 | touch /opt/also-inaccessible/foo && exit 1 | |
441 | mountpoint /var | |
442 | ||
443 | ip link | |
444 | ip link | grep host-only && exit 1 | |
445 | ip link | grep host0@ | |
446 | ip link | grep my-fancy-veth1@ | |
447 | ip link | grep my-fancy-veth2@ | |
448 | ip link | grep sd-shared1 | |
e8736fb6 YW |
449 | ip link | grep sd-renamed2 |
450 | ip link | grep sd-shared3 | |
451 | ip link | grep sd-altname3 | |
452 | ip link | grep sd-altname-tooooooooooooo-long | |
cbd20ab4 FS |
453 | ip link | grep mv-sd-macvlan1@ |
454 | ip link | grep my-macvlan2@ | |
455 | ip link | grep iv-sd-ipvlan1@ | |
456 | ip link | grep my-ipvlan2@ | |
457 | EOF | |
d2e8dc78 FS |
458 | if [[ -n "${wlan_names:-}" ]]; then |
459 | cat >>"$root/entrypoint.sh" <<\EOF | |
460 | ip link | grep wlan0 | |
461 | ip link | grep wl-renamed1 | |
462 | EOF | |
463 | fi | |
e8736fb6 | 464 | |
cbd20ab4 FS |
465 | timeout 30 systemd-nspawn --directory="$root" |
466 | ||
467 | # And now for stuff that needs to run separately | |
468 | # | |
469 | # Note on the condition below: since our container tree is owned by root, | |
470 | # both "yes" and "identity" private users settings will behave the same | |
471 | # as PrivateUsers=0:65535, which makes BindUser= fail as the UID already | |
472 | # exists there, so skip setting it in such case | |
473 | for private_users in "131072:65536" yes identity pick; do | |
474 | cat >"/run/systemd/nspawn/$container.nspawn" <<EOF | |
475 | [Exec] | |
476 | Hostname=private-users | |
477 | PrivateUsers=$private_users | |
478 | ||
479 | [Files] | |
480 | PrivateUsersOwnership=auto | |
481 | BindUser= | |
482 | $([[ "$private_users" =~ (yes|identity) ]] || echo "BindUser=testuser") | |
483 | ${COVERAGE_BUILD_DIR:+"Bind=$COVERAGE_BUILD_DIR"} | |
484 | EOF | |
485 | cat "/run/systemd/nspawn/$container.nspawn" | |
486 | chown -R root:root "$root" | |
487 | systemd-nspawn --directory="$root" bash -xec '[[ "$(hostname)" == private-users ]]' | |
488 | done | |
489 | ||
490 | rm -fr "$root" "/run/systemd/nspawn/$container.nspawn" | |
491 | } | |
492 | ||
d5a6ff8c FS |
493 | bind_user_cleanup() { |
494 | userdel --force --remove nspawn-bind-user-1 | |
495 | userdel --force --remove nspawn-bind-user-2 | |
496 | } | |
497 | ||
498 | testcase_bind_user() { | |
499 | local root | |
500 | ||
501 | root="$(mktemp -d /var/lib/machines/testsuite-13.bind-user.XXX)" | |
502 | create_dummy_container "$root" | |
503 | useradd --create-home --user-group nspawn-bind-user-1 | |
504 | useradd --create-home --user-group nspawn-bind-user-2 | |
505 | trap bind_user_cleanup RETURN | |
506 | touch /home/nspawn-bind-user-1/foo | |
507 | touch /home/nspawn-bind-user-2/bar | |
508 | # Add a couple of POSIX ACLs to test the patch-uid stuff | |
509 | mkdir -p "$root/opt" | |
510 | setfacl -R -m 'd:u:nspawn-bind-user-1:rwX' -m 'u:nspawn-bind-user-1:rwX' "$root/opt" | |
511 | setfacl -R -m 'd:g:nspawn-bind-user-1:rwX' -m 'g:nspawn-bind-user-1:rwX' "$root/opt" | |
512 | ||
513 | systemd-nspawn --directory="$root" \ | |
514 | --private-users=pick \ | |
515 | --bind-user=nspawn-bind-user-1 \ | |
516 | bash -xec 'test -e /run/host/home/nspawn-bind-user-1/foo' | |
517 | ||
518 | systemd-nspawn --directory="$root" \ | |
519 | --private-users=pick \ | |
520 | --private-users-ownership=chown \ | |
521 | --bind-user=nspawn-bind-user-1 \ | |
522 | --bind-user=nspawn-bind-user-2 \ | |
523 | bash -xec 'test -e /run/host/home/nspawn-bind-user-1/foo; test -e /run/host/home/nspawn-bind-user-2/bar' | |
524 | chown -R root:root "$root" | |
525 | ||
526 | # User/group name collision | |
527 | echo "nspawn-bind-user-2:x:1000:1000:nspawn-bind-user-2:/home/nspawn-bind-user-2:/bin/bash" >"$root/etc/passwd" | |
528 | (! systemd-nspawn --directory="$root" \ | |
529 | --private-users=pick \ | |
530 | --bind-user=nspawn-bind-user-1 \ | |
531 | --bind-user=nspawn-bind-user-2 \ | |
532 | true) | |
533 | rm -f "$root/etc/passwd" | |
534 | ||
535 | echo "nspawn-bind-user-2:x:1000:" >"$root/etc/group" | |
536 | (! systemd-nspawn --directory="$root" \ | |
537 | --private-users=pick \ | |
538 | --bind-user=nspawn-bind-user-1 \ | |
539 | --bind-user=nspawn-bind-user-2 \ | |
540 | true) | |
541 | rm -f "$root/etc/group" | |
542 | ||
543 | rm -fr "$root" | |
544 | } | |
545 | ||
cf260f79 | 546 | testcase_bind_tmp_path() { |
378db9e2 FS |
547 | # https://github.com/systemd/systemd/issues/4789 |
548 | local root | |
549 | ||
550 | root="$(mktemp -d /var/lib/machines/testsuite-13.bind-tmp-path.XXX)" | |
5656759d | 551 | create_dummy_container "$root" |
378db9e2 FS |
552 | : >/tmp/bind |
553 | systemd-nspawn --register=no \ | |
554 | --directory="$root" \ | |
555 | --bind=/tmp/bind \ | |
5656759d | 556 | bash -c 'test -e /tmp/bind' |
378db9e2 FS |
557 | |
558 | rm -fr "$root" /tmp/bind | |
559 | } | |
560 | ||
cf260f79 | 561 | testcase_norbind() { |
378db9e2 FS |
562 | # https://github.com/systemd/systemd/issues/13170 |
563 | local root | |
564 | ||
565 | root="$(mktemp -d /var/lib/machines/testsuite-13.norbind-path.XXX)" | |
566 | mkdir -p /tmp/binddir/subdir | |
567 | echo -n "outer" >/tmp/binddir/subdir/file | |
568 | mount -t tmpfs tmpfs /tmp/binddir/subdir | |
569 | echo -n "inner" >/tmp/binddir/subdir/file | |
5656759d | 570 | create_dummy_container "$root" |
378db9e2 FS |
571 | |
572 | systemd-nspawn --register=no \ | |
573 | --directory="$root" \ | |
574 | --bind=/tmp/binddir:/mnt:norbind \ | |
5656759d | 575 | bash -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; exit 1; fi' |
378db9e2 FS |
576 | |
577 | umount /tmp/binddir/subdir | |
578 | rm -fr "$root" /tmp/binddir/ | |
579 | } | |
580 | ||
cf260f79 | 581 | rootidmap_cleanup() { |
378db9e2 FS |
582 | local dir="${1:?}" |
583 | ||
584 | mountpoint -q "$dir/bind" && umount "$dir/bind" | |
585 | rm -fr "$dir" | |
586 | } | |
587 | ||
cf260f79 | 588 | testcase_rootidmap() { |
378db9e2 FS |
589 | local root cmd permissions |
590 | local owner=1000 | |
591 | ||
592 | root="$(mktemp -d /var/lib/machines/testsuite-13.rootidmap-path.XXX)" | |
593 | # Create ext4 image, as ext4 supports idmapped-mounts. | |
594 | mkdir -p /tmp/rootidmap/bind | |
595 | dd if=/dev/zero of=/tmp/rootidmap/ext4.img bs=4k count=2048 | |
596 | mkfs.ext4 /tmp/rootidmap/ext4.img | |
597 | mount /tmp/rootidmap/ext4.img /tmp/rootidmap/bind | |
cf260f79 | 598 | trap "rootidmap_cleanup /tmp/rootidmap/" RETURN |
378db9e2 FS |
599 | |
600 | touch /tmp/rootidmap/bind/file | |
601 | chown -R "$owner:$owner" /tmp/rootidmap/bind | |
602 | ||
5656759d | 603 | create_dummy_container "$root" |
378db9e2 FS |
604 | cmd='PERMISSIONS=$(stat -c "%u:%g" /mnt/file); if [[ $PERMISSIONS != "0:0" ]]; then echo "*** wrong permissions: $PERMISSIONS"; return 1; fi; touch /mnt/other_file' |
605 | if ! SYSTEMD_LOG_TARGET=console \ | |
606 | systemd-nspawn --register=no \ | |
607 | --directory="$root" \ | |
608 | --bind=/tmp/rootidmap/bind:/mnt:rootidmap \ | |
5656759d | 609 | bash -c "$cmd" |& tee nspawn.out; then |
378db9e2 FS |
610 | if grep -q "Failed to map ids for bind mount.*: Function not implemented" nspawn.out; then |
611 | echo "idmapped mounts are not supported, skipping the test..." | |
612 | return 0 | |
613 | fi | |
614 | ||
615 | return 1 | |
616 | fi | |
617 | ||
618 | permissions=$(stat -c "%u:%g" /tmp/rootidmap/bind/other_file) | |
619 | if [[ $permissions != "$owner:$owner" ]]; then | |
614d09a3 BF |
620 | echo "*** wrong permissions: $permissions" |
621 | [[ "$IS_USERNS_SUPPORTED" == "yes" ]] && return 1 | |
622 | fi | |
623 | } | |
624 | ||
625 | owneridmap_cleanup() { | |
626 | local dir="${1:?}" | |
627 | ||
628 | mountpoint -q "$dir/bind" && umount "$dir/bind" | |
629 | rm -fr "$dir" | |
630 | } | |
631 | ||
632 | testcase_owneridmap() { | |
633 | local root cmd permissions | |
634 | local owner=1000 | |
635 | ||
636 | root="$(mktemp -d /var/lib/machines/testsuite-13.owneridmap-path.XXX)" | |
637 | # Create ext4 image, as ext4 supports idmapped-mounts. | |
638 | mkdir -p /tmp/owneridmap/bind | |
639 | dd if=/dev/zero of=/tmp/owneridmap/ext4.img bs=4k count=2048 | |
640 | mkfs.ext4 /tmp/owneridmap/ext4.img | |
641 | mount /tmp/owneridmap/ext4.img /tmp/owneridmap/bind | |
642 | trap "owneridmap_cleanup /tmp/owneridmap/" RETURN | |
643 | ||
644 | touch /tmp/owneridmap/bind/file | |
645 | chown -R "$owner:$owner" /tmp/owneridmap/bind | |
646 | ||
647 | # Allow users to read and execute / in order to execute binaries | |
648 | chmod o+rx "$root" | |
649 | ||
650 | create_dummy_container "$root" | |
651 | ||
652 | # --user= | |
653 | # "Fake" getent passwd's bare minimum, so we don't have to pull it in | |
654 | # with all the DSO shenanigans | |
655 | cat >"$root/bin/getent" <<\EOF | |
656 | #!/bin/bash | |
657 | ||
658 | if [[ $# -eq 0 ]]; then | |
659 | : | |
660 | elif [[ $1 == passwd ]]; then | |
661 | echo "testuser:x:1010:1010:testuser:/:/bin/sh" | |
662 | elif [[ $1 == initgroups ]]; then | |
663 | echo "testuser" | |
664 | fi | |
665 | EOF | |
666 | chmod +x "$root/bin/getent" | |
667 | ||
668 | mkdir -p "$root/home/testuser" | |
669 | chown 1010:1010 "$root/home/testuser" | |
670 | ||
671 | cmd='PERMISSIONS=$(stat -c "%u:%g" /home/testuser/file); if [[ $PERMISSIONS != "1010:1010" ]]; then echo "*** wrong permissions: $PERMISSIONS"; return 1; fi; touch /home/testuser/other_file' | |
672 | if ! SYSTEMD_LOG_TARGET=console \ | |
673 | systemd-nspawn --register=no \ | |
674 | --directory="$root" \ | |
675 | -U \ | |
676 | --user=testuser \ | |
677 | --bind=/tmp/owneridmap/bind:/home/testuser:owneridmap \ | |
678 | /usr/bin/bash -c "$cmd" |& tee nspawn.out; then | |
679 | if grep -q "Failed to map ids for bind mount.*: Function not implemented" nspawn.out; then | |
680 | echo "idmapped mounts are not supported, skipping the test..." | |
681 | return 0 | |
682 | fi | |
683 | ||
684 | return 1 | |
685 | fi | |
686 | ||
687 | permissions=$(stat -c "%u:%g" /tmp/owneridmap/bind/other_file) | |
688 | if [[ $permissions != "$owner:$owner" ]]; then | |
378db9e2 FS |
689 | echo "*** wrong permissions: $permissions" |
690 | [[ "$IS_USERNS_SUPPORTED" == "yes" ]] && return 1 | |
691 | fi | |
692 | } | |
693 | ||
cf260f79 | 694 | testcase_notification_socket() { |
378db9e2 | 695 | # https://github.com/systemd/systemd/issues/4944 |
5656759d FS |
696 | local root |
697 | local cmd='echo a | nc -U -u -w 1 /run/host/notify' | |
698 | ||
699 | root="$(mktemp -d /var/lib/machines/testsuite-13.check_notification_socket.XXX)" | |
700 | create_dummy_container "$root" | |
378db9e2 | 701 | |
5656759d FS |
702 | systemd-nspawn --register=no --directory="$root" bash -x -c "$cmd" |
703 | systemd-nspawn --register=no --directory="$root" -U bash -x -c "$cmd" | |
cbd20ab4 FS |
704 | |
705 | rm -fr "$root" | |
378db9e2 FS |
706 | } |
707 | ||
cf260f79 | 708 | testcase_os_release() { |
378db9e2 FS |
709 | local root entrypoint os_release_source |
710 | ||
cf260f79 | 711 | root="$(mktemp -d /var/lib/machines/testsuite-13.os-release.XXX)" |
5656759d | 712 | create_dummy_container "$root" |
378db9e2 FS |
713 | entrypoint="$root/entrypoint.sh" |
714 | cat >"$entrypoint" <<\EOF | |
5656759d | 715 | #!/usr/bin/bash -ex |
378db9e2 FS |
716 | |
717 | . /tmp/os-release | |
718 | [[ -n "${ID:-}" && "$ID" != "$container_host_id" ]] && exit 1 | |
719 | [[ -n "${VERSION_ID:-}" && "$VERSION_ID" != "$container_host_version_id" ]] && exit 1 | |
720 | [[ -n "${BUILD_ID:-}" && "$BUILD_ID" != "$container_host_build_id" ]] && exit 1 | |
721 | [[ -n "${VARIANT_ID:-}" && "$VARIANT_ID" != "$container_host_variant_id" ]] && exit 1 | |
722 | ||
723 | cd /tmp | |
724 | (cd /run/host && md5sum os-release) | md5sum -c | |
725 | EOF | |
726 | chmod +x "$entrypoint" | |
727 | ||
728 | os_release_source="/etc/os-release" | |
729 | if [[ ! -r "$os_release_source" ]]; then | |
730 | os_release_source="/usr/lib/os-release" | |
731 | elif [[ -L "$os_release_source" ]]; then | |
732 | # Ensure that /etc always wins if available | |
733 | cp --remove-destination -fv /usr/lib/os-release /etc/os-release | |
734 | echo MARKER=1 >>/etc/os-release | |
735 | fi | |
736 | ||
737 | systemd-nspawn --register=no \ | |
738 | --directory="$root" \ | |
739 | --bind="$os_release_source:/tmp/os-release" \ | |
740 | "${entrypoint##"$root"}" | |
741 | ||
742 | if grep -q MARKER /etc/os-release; then | |
743 | ln -svrf /usr/lib/os-release /etc/os-release | |
744 | fi | |
745 | ||
746 | rm -fr "$root" | |
747 | } | |
748 | ||
cf260f79 | 749 | testcase_machinectl_bind() { |
378db9e2 | 750 | local service_path service_name root container_name ec |
5656759d | 751 | local cmd='for i in $(seq 1 20); do if test -f /tmp/marker; then exit 0; fi; sleep .5; done; exit 1;' |
378db9e2 | 752 | |
cf260f79 | 753 | root="$(mktemp -d /var/lib/machines/testsuite-13.machinectl-bind.XXX)" |
5656759d FS |
754 | create_dummy_container "$root" |
755 | container_name="$(basename "$root")" | |
378db9e2 FS |
756 | |
757 | service_path="$(mktemp /run/systemd/system/nspawn-machinectl-bind-XXX.service)" | |
758 | service_name="${service_path##*/}" | |
759 | cat >"$service_path" <<EOF | |
760 | [Service] | |
761 | Type=notify | |
5656759d | 762 | ExecStart=systemd-nspawn --directory="$root" --notify-ready=no /usr/bin/bash -xec "$cmd" |
378db9e2 FS |
763 | EOF |
764 | ||
765 | systemctl daemon-reload | |
766 | systemctl start "$service_name" | |
767 | touch /tmp/marker | |
768 | machinectl bind --mkdir "$container_name" /tmp/marker | |
769 | ||
770 | timeout 10 bash -c "while [[ '\$(systemctl show -P SubState $service_name)' == running ]]; do sleep .2; done" | |
771 | ec="$(systemctl show -P ExecMainStatus "$service_name")" | |
5656759d | 772 | systemctl stop "$service_name" |
378db9e2 FS |
773 | |
774 | rm -fr "$root" "$service_path" | |
775 | ||
776 | return "$ec" | |
777 | } | |
778 | ||
cf260f79 | 779 | testcase_selinux() { |
378db9e2 FS |
780 | # Basic test coverage to avoid issues like https://github.com/systemd/systemd/issues/19976 |
781 | if ! command -v selinuxenabled >/dev/null || ! selinuxenabled; then | |
782 | echo >&2 "SELinux is not enabled, skipping SELinux-related tests" | |
783 | return 0 | |
784 | fi | |
785 | ||
786 | local root | |
787 | ||
cf260f79 | 788 | root="$(mktemp -d /var/lib/machines/testsuite-13.selinux.XXX)" |
5656759d | 789 | create_dummy_container "$root" |
378db9e2 FS |
790 | chcon -R -t container_t "$root" |
791 | ||
792 | systemd-nspawn --register=no \ | |
793 | --boot \ | |
794 | --directory="$root" \ | |
795 | --selinux-apifs-context=system_u:object_r:container_file_t:s0:c0,c1 \ | |
796 | --selinux-context=system_u:system_r:container_t:s0:c0,c1 | |
797 | ||
798 | rm -fr "$root" | |
799 | } | |
800 | ||
cf260f79 | 801 | testcase_ephemeral_config() { |
378db9e2 FS |
802 | # https://github.com/systemd/systemd/issues/13297 |
803 | local root container_name | |
804 | ||
cf260f79 | 805 | root="$(mktemp -d /var/lib/machines/testsuite-13.ephemeral-config.XXX)" |
5656759d | 806 | create_dummy_container "$root" |
cf260f79 | 807 | container_name="$(basename "$root")" |
378db9e2 FS |
808 | |
809 | mkdir -p /run/systemd/nspawn/ | |
28ed2326 | 810 | rm -f "/etc/systemd/nspawn/$container_name.nspawn" |
378db9e2 FS |
811 | cat >"/run/systemd/nspawn/$container_name.nspawn" <<EOF |
812 | [Files] | |
28ed2326 | 813 | ${COVERAGE_BUILD_DIR:+"Bind=$COVERAGE_BUILD_DIR"} |
378db9e2 FS |
814 | BindReadOnly=/tmp/ephemeral-config |
815 | EOF | |
816 | touch /tmp/ephemeral-config | |
817 | ||
818 | systemd-nspawn --register=no \ | |
819 | --directory="$root" \ | |
820 | --ephemeral \ | |
5656759d | 821 | bash -x -c "test -f /tmp/ephemeral-config" |
378db9e2 FS |
822 | |
823 | systemd-nspawn --register=no \ | |
824 | --directory="$root" \ | |
825 | --ephemeral \ | |
826 | --machine=foobar \ | |
5656759d | 827 | bash -x -c "! test -f /tmp/ephemeral-config" |
378db9e2 | 828 | |
cbd20ab4 | 829 | rm -fr "$root" "/run/systemd/nspawn/$container_name.nspawn" |
378db9e2 FS |
830 | } |
831 | ||
832 | matrix_run_one() { | |
833 | local cgroupsv2="${1:?}" | |
834 | local use_cgns="${2:?}" | |
835 | local api_vfs_writable="${3:?}" | |
836 | local root | |
837 | ||
838 | if [[ "$cgroupsv2" == "yes" && "$IS_CGROUPSV2_SUPPORTED" == "no" ]]; then | |
839 | echo >&2 "Unified cgroup hierarchy is not supported, skipping..." | |
840 | return 0 | |
841 | fi | |
842 | ||
843 | if [[ "$use_cgns" == "yes" && "$IS_CGNS_SUPPORTED" == "no" ]]; then | |
844 | echo >&2 "CGroup namespaces are not supported, skipping..." | |
845 | return 0 | |
846 | fi | |
847 | ||
848 | root="$(mktemp -d "/var/lib/machines/testsuite-13.unified-$1-cgns-$2-api-vfs-writable-$3.XXX")" | |
5656759d | 849 | create_dummy_container "$root" |
378db9e2 FS |
850 | |
851 | SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \ | |
852 | systemd-nspawn --register=no \ | |
853 | --directory="$root" \ | |
854 | --boot | |
855 | ||
856 | SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \ | |
857 | systemd-nspawn --register=no \ | |
858 | --directory="$root" \ | |
859 | --private-network \ | |
860 | --boot | |
861 | ||
862 | if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \ | |
863 | systemd-nspawn --register=no \ | |
864 | --directory="$root" \ | |
865 | --private-users=pick \ | |
866 | --boot; then | |
867 | [[ "$IS_USERNS_SUPPORTED" == "yes" && "$api_vfs_writable" == "network" ]] && return 1 | |
868 | else | |
869 | [[ "$IS_USERNS_SUPPORTED" == "no" && "$api_vfs_writable" = "network" ]] && return 1 | |
870 | fi | |
871 | ||
872 | if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \ | |
873 | systemd-nspawn --register=no \ | |
874 | --directory="$root" \ | |
875 | --private-network \ | |
876 | --private-users=pick \ | |
877 | --boot; then | |
878 | [[ "$IS_USERNS_SUPPORTED" == "yes" && "$api_vfs_writable" == "yes" ]] && return 1 | |
879 | else | |
880 | [[ "$IS_USERNS_SUPPORTED" == "no" && "$api_vfs_writable" = "yes" ]] && return 1 | |
881 | fi | |
882 | ||
883 | local netns_opt="--network-namespace-path=/proc/self/ns/net" | |
884 | local net_opt | |
885 | local net_opts=( | |
886 | "--network-bridge=lo" | |
887 | "--network-interface=lo" | |
888 | "--network-ipvlan=lo" | |
889 | "--network-macvlan=lo" | |
890 | "--network-veth" | |
891 | "--network-veth-extra=lo" | |
892 | "--network-zone=zone" | |
893 | ) | |
894 | ||
895 | # --network-namespace-path and network-related options cannot be used together | |
896 | for net_opt in "${net_opts[@]}"; do | |
897 | echo "$netns_opt in combination with $net_opt should fail" | |
898 | if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \ | |
899 | systemd-nspawn --register=no \ | |
900 | --directory="$root" \ | |
901 | --boot \ | |
902 | "$netns_opt" \ | |
903 | "$net_opt"; then | |
904 | echo >&2 "unexpected pass" | |
905 | return 1 | |
906 | fi | |
907 | done | |
908 | ||
909 | # allow combination of --network-namespace-path and --private-network | |
910 | SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \ | |
911 | systemd-nspawn --register=no \ | |
912 | --directory="$root" \ | |
913 | --boot \ | |
914 | --private-network \ | |
915 | "$netns_opt" | |
916 | ||
917 | # test --network-namespace-path works with a network namespace created by "ip netns" | |
918 | ip netns add nspawn_test | |
919 | netns_opt="--network-namespace-path=/run/netns/nspawn_test" | |
920 | SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \ | |
921 | systemd-nspawn --register=no \ | |
922 | --directory="$root" \ | |
923 | --network-namespace-path=/run/netns/nspawn_test \ | |
5656759d | 924 | ip a | grep -v -E '^1: lo.*UP' |
378db9e2 FS |
925 | ip netns del nspawn_test |
926 | ||
927 | rm -fr "$root" | |
928 | ||
929 | return 0 | |
930 | } | |
931 | ||
d4317fe1 FS |
932 | testcase_check_os_release() { |
933 | # https://github.com/systemd/systemd/issues/29185 | |
934 | local base common_opts root | |
935 | ||
936 | base="$(mktemp -d /var/lib/machines/testsuite-13.check_os_release_base.XXX)" | |
937 | root="$(mktemp -d /var/lib/machines/testsuite-13.check_os_release.XXX)" | |
938 | create_dummy_container "$base" | |
939 | cp -d "$base"/{bin,sbin,lib,lib64} "$root/" | |
940 | common_opts=( | |
941 | --boot | |
942 | --register=no | |
943 | --directory="$root" | |
944 | --bind-ro="$base/usr:/usr" | |
945 | ) | |
946 | ||
947 | # Empty /etc/ & /usr/ | |
948 | (! systemd-nspawn "${common_opts[@]}") | |
949 | (! SYSTEMD_NSPAWN_CHECK_OS_RELEASE=1 systemd-nspawn "${common_opts[@]}") | |
950 | (! SYSTEMD_NSPAWN_CHECK_OS_RELEASE=foo systemd-nspawn "${common_opts[@]}") | |
951 | SYSTEMD_NSPAWN_CHECK_OS_RELEASE=0 systemd-nspawn "${common_opts[@]}" | |
952 | ||
953 | # Empty /usr/ + a broken /etc/os-release -> /usr/os-release symlink | |
954 | ln -svrf "$root/etc/os-release" "$root/usr/os-release" | |
955 | (! systemd-nspawn "${common_opts[@]}") | |
956 | (! SYSTEMD_NSPAWN_CHECK_OS_RELEASE=1 systemd-nspawn "${common_opts[@]}") | |
957 | SYSTEMD_NSPAWN_CHECK_OS_RELEASE=0 systemd-nspawn "${common_opts[@]}" | |
958 | ||
959 | rm -fr "$root" "$base" | |
960 | } | |
961 | ||
b60d910d | 962 | run_testcases |
378db9e2 FS |
963 | |
964 | for api_vfs_writable in yes no network; do | |
965 | matrix_run_one no no $api_vfs_writable | |
966 | matrix_run_one yes no $api_vfs_writable | |
967 | matrix_run_one no yes $api_vfs_writable | |
968 | matrix_run_one yes yes $api_vfs_writable | |
969 | done |