]>
Commit | Line | Data |
---|---|---|
ccb26715 FS |
1 | #!/usr/bin/env bash |
2 | # SPDX-License-Identifier: LGPL-2.1-or-later | |
3 | # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- | |
4 | # ex: ts=8 sw=4 sts=4 et filetype=sh | |
5 | # shellcheck disable=SC2233,SC2235 | |
6 | set -eux | |
7 | set -o pipefail | |
8 | ||
9 | # shellcheck source=test/units/util.sh | |
10 | . "$(dirname "$0")"/util.sh | |
11 | ||
69dc36f6 DDM |
12 | BIND_LOG_SOCKETS=( |
13 | --property BindReadOnlyPaths=/dev/log | |
14 | --property BindReadOnlyPaths=/run/systemd/journal/socket | |
15 | --property BindReadOnlyPaths=/run/systemd/journal/stdout | |
16 | ) | |
17 | ||
5d259f12 FS |
18 | systemd-dissect --json=short "$MINIMAL_IMAGE.raw" | \ |
19 | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"' | |
ccb26715 | 20 | systemd-dissect "$MINIMAL_IMAGE.raw" | grep -q -F "MARKER=1" |
c77dad70 | 21 | # shellcheck disable=SC2153 |
ccb26715 FS |
22 | systemd-dissect "$MINIMAL_IMAGE.raw" | grep -q -F -f <(sed 's/"//g' "$OS_RELEASE") |
23 | ||
24 | systemd-dissect --list "$MINIMAL_IMAGE.raw" | grep -q '^etc/os-release$' | |
5d259f12 FS |
25 | systemd-dissect --mtree "$MINIMAL_IMAGE.raw" --mtree-hash yes | \ |
26 | grep -qe "^./usr/bin/cat type=file mode=0755 uid=0 gid=0 size=[0-9]* sha256sum=[a-z0-9]*$" | |
27 | systemd-dissect --mtree "$MINIMAL_IMAGE.raw" --mtree-hash no | \ | |
28 | grep -qe "^./usr/bin/cat type=file mode=0755 uid=0 gid=0 size=[0-9]*$" | |
ccb26715 FS |
29 | |
30 | read -r SHA256SUM1 _ < <(systemd-dissect --copy-from "$MINIMAL_IMAGE.raw" etc/os-release | sha256sum) | |
31 | test "$SHA256SUM1" != "" | |
32 | read -r SHA256SUM2 _ < <(systemd-dissect --read-only --with "$MINIMAL_IMAGE.raw" sha256sum etc/os-release) | |
33 | test "$SHA256SUM2" != "" | |
34 | test "$SHA256SUM1" = "$SHA256SUM2" | |
35 | ||
36 | if systemctl --version | grep -qF -- "+LIBARCHIVE" ; then | |
37 | # Make sure tarballs are reproducible | |
38 | read -r SHA256SUM1 _ < <(systemd-dissect --make-archive "$MINIMAL_IMAGE.raw" | sha256sum) | |
39 | test "$SHA256SUM1" != "" | |
40 | read -r SHA256SUM2 _ < <(systemd-dissect --make-archive "$MINIMAL_IMAGE.raw" | sha256sum) | |
41 | test "$SHA256SUM2" != "" | |
42 | test "$SHA256SUM1" = "$SHA256SUM2" | |
43 | # Also check that a file we expect to be there is there | |
44 | systemd-dissect --make-archive "$MINIMAL_IMAGE.raw" | tar t | grep etc/os-release | |
45 | fi | |
46 | ||
47 | mv "$MINIMAL_IMAGE.verity" "$MINIMAL_IMAGE.fooverity" | |
48 | mv "$MINIMAL_IMAGE.roothash" "$MINIMAL_IMAGE.foohash" | |
5d259f12 FS |
49 | systemd-dissect "$MINIMAL_IMAGE.raw" \ |
50 | --json=short \ | |
51 | --root-hash="$MINIMAL_IMAGE_ROOTHASH" \ | |
52 | --verity-data="$MINIMAL_IMAGE.fooverity" | \ | |
53 | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"' | |
54 | systemd-dissect "$MINIMAL_IMAGE.raw" \ | |
55 | --root-hash="$MINIMAL_IMAGE_ROOTHASH" \ | |
56 | --verity-data="$MINIMAL_IMAGE.fooverity" | \ | |
57 | grep -q -F "MARKER=1" | |
58 | systemd-dissect "$MINIMAL_IMAGE.raw" \ | |
59 | --root-hash="$MINIMAL_IMAGE_ROOTHASH" \ | |
60 | --verity-data="$MINIMAL_IMAGE.fooverity" | \ | |
61 | grep -q -F -f <(sed 's/"//g' "$OS_RELEASE") | |
ccb26715 FS |
62 | mv "$MINIMAL_IMAGE.fooverity" "$MINIMAL_IMAGE.verity" |
63 | mv "$MINIMAL_IMAGE.foohash" "$MINIMAL_IMAGE.roothash" | |
64 | ||
65 | mkdir -p "$IMAGE_DIR/mount" "$IMAGE_DIR/mount2" | |
66 | systemd-dissect --mount "$MINIMAL_IMAGE.raw" "$IMAGE_DIR/mount" | |
67 | grep -q -F -f "$OS_RELEASE" "$IMAGE_DIR/mount/usr/lib/os-release" | |
68 | grep -q -F -f "$OS_RELEASE" "$IMAGE_DIR/mount/etc/os-release" | |
69 | grep -q -F "MARKER=1" "$IMAGE_DIR/mount/usr/lib/os-release" | |
70 | # Verity volume should be shared (opened only once) | |
71 | systemd-dissect --mount "$MINIMAL_IMAGE.raw" "$IMAGE_DIR/mount2" | |
72 | verity_count=$(find /dev/mapper/ -name "*verity*" | wc -l) | |
73 | # In theory we should check that count is exactly one. In practice, libdevmapper | |
74 | # randomly and unpredictably fails with an unhelpful EINVAL when a device is open | |
75 | # (and even mounted and in use), so best-effort is the most we can do for now | |
76 | if [[ "$verity_count" -lt 1 ]]; then | |
77 | echo "Verity device $MINIMAL_IMAGE.raw not found in /dev/mapper/" | |
78 | exit 1 | |
79 | fi | |
80 | systemd-dissect --umount "$IMAGE_DIR/mount" | |
81 | systemd-dissect --umount "$IMAGE_DIR/mount2" | |
82 | ||
69dc36f6 | 83 | systemd-run -P -p RootImage="$MINIMAL_IMAGE.raw" "${BIND_LOG_SOCKETS[@]}" cat /usr/lib/os-release | grep -q -F "MARKER=1" |
ccb26715 FS |
84 | mv "$MINIMAL_IMAGE.verity" "$MINIMAL_IMAGE.fooverity" |
85 | mv "$MINIMAL_IMAGE.roothash" "$MINIMAL_IMAGE.foohash" | |
5d259f12 FS |
86 | systemd-run -P \ |
87 | -p RootImage="$MINIMAL_IMAGE.raw" \ | |
88 | -p RootHash="$MINIMAL_IMAGE.foohash" \ | |
89 | -p RootVerity="$MINIMAL_IMAGE.fooverity" \ | |
69dc36f6 | 90 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 91 | cat /usr/lib/os-release | grep -q -F "MARKER=1" |
ccb26715 | 92 | # Let's use the long option name just here as a test |
5d259f12 FS |
93 | systemd-run -P \ |
94 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
95 | --property RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
96 | --property RootVerity="$MINIMAL_IMAGE.fooverity" \ | |
69dc36f6 | 97 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 98 | cat /usr/lib/os-release | grep -q -F "MARKER=1" |
ccb26715 FS |
99 | mv "$MINIMAL_IMAGE.fooverity" "$MINIMAL_IMAGE.verity" |
100 | mv "$MINIMAL_IMAGE.foohash" "$MINIMAL_IMAGE.roothash" | |
101 | ||
102 | # Derive partition UUIDs from root hash, in UUID syntax | |
103 | ROOT_UUID="$(systemd-id128 -u show "$(head -c 32 "$MINIMAL_IMAGE.roothash")" -u | tail -n 1 | cut -b 6-)" | |
104 | VERITY_UUID="$(systemd-id128 -u show "$(tail -c 32 "$MINIMAL_IMAGE.roothash")" -u | tail -n 1 | cut -b 6-)" | |
105 | ||
5d259f12 FS |
106 | systemd-dissect --json=short \ |
107 | --root-hash "$MINIMAL_IMAGE_ROOTHASH" \ | |
108 | "$MINIMAL_IMAGE.gpt" | \ | |
109 | grep -q '{"rw":"ro","designator":"root","partition_uuid":"'"$ROOT_UUID"'","partition_label":"Root Partition","fstype":"squashfs","architecture":"'"$ARCHITECTURE"'","verity":"signed",' | |
110 | systemd-dissect --json=short \ | |
111 | --root-hash "$MINIMAL_IMAGE_ROOTHASH" \ | |
112 | "$MINIMAL_IMAGE.gpt" | \ | |
113 | grep -q '{"rw":"ro","designator":"root-verity","partition_uuid":"'"$VERITY_UUID"'","partition_label":"Verity Partition","fstype":"DM_verity_hash","architecture":"'"$ARCHITECTURE"'","verity":null,' | |
ccb26715 | 114 | if [[ -n "${OPENSSL_CONFIG:-}" ]]; then |
5d259f12 FS |
115 | systemd-dissect --json=short \ |
116 | --root-hash "$MINIMAL_IMAGE_ROOTHASH" \ | |
117 | "$MINIMAL_IMAGE.gpt" | \ | |
118 | grep -qE '{"rw":"ro","designator":"root-verity-sig","partition_uuid":"'".*"'","partition_label":"Signature Partition","fstype":"verity_hash_signature","architecture":"'"$ARCHITECTURE"'","verity":null,' | |
ccb26715 FS |
119 | fi |
120 | systemd-dissect --root-hash "$MINIMAL_IMAGE_ROOTHASH" "$MINIMAL_IMAGE.gpt" | grep -q -F "MARKER=1" | |
121 | systemd-dissect --root-hash "$MINIMAL_IMAGE_ROOTHASH" "$MINIMAL_IMAGE.gpt" | grep -q -F -f <(sed 's/"//g' "$OS_RELEASE") | |
122 | ||
123 | # Test image policies | |
124 | systemd-dissect --validate "$MINIMAL_IMAGE.gpt" | |
125 | systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy='*' | |
126 | (! systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy='~') | |
127 | (! systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy='-') | |
128 | (! systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=absent) | |
129 | (! systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=swap=unprotected+encrypted+verity) | |
130 | systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=unprotected | |
131 | systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=verity | |
132 | systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=verity:root-verity-sig=unused+absent | |
133 | systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=verity:swap=absent | |
134 | systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=verity:swap=absent+unprotected | |
135 | (! systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=verity:root-verity=unused+absent) | |
136 | systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=signed | |
137 | (! systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=signed:root-verity-sig=unused+absent) | |
138 | (! systemd-dissect --validate "$MINIMAL_IMAGE.gpt" --image-policy=root=signed:root-verity=unused+absent) | |
139 | ||
140 | # Test RootImagePolicy= unit file setting | |
5d259f12 FS |
141 | systemd-run --wait -P \ |
142 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
143 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
144 | -p MountAPIVFS=yes \ | |
69dc36f6 | 145 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
146 | cat /usr/lib/os-release | grep -q -F "MARKER=1" |
147 | systemd-run --wait -P \ | |
148 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
149 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
150 | -p RootImagePolicy='*' \ | |
151 | -p MountAPIVFS=yes \ | |
69dc36f6 | 152 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
153 | cat /usr/lib/os-release | grep -q -F "MARKER=1" |
154 | (! systemd-run --wait -P \ | |
155 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
156 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
157 | -p RootImagePolicy='~' \ | |
158 | -p MountAPIVFS=yes \ | |
69dc36f6 | 159 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
160 | cat /usr/lib/os-release | grep -q -F "MARKER=1") |
161 | (! systemd-run --wait -P \ | |
162 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
163 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
164 | -p RootImagePolicy='-' \ | |
165 | -p MountAPIVFS=yes \ | |
69dc36f6 | 166 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
167 | cat /usr/lib/os-release | grep -q -F "MARKER=1") |
168 | (! systemd-run --wait -P \ | |
169 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
170 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
171 | -p RootImagePolicy='root=absent' \ | |
172 | -p MountAPIVFS=yes \ | |
69dc36f6 | 173 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
174 | cat /usr/lib/os-release | grep -q -F "MARKER=1") |
175 | systemd-run --wait -P \ | |
176 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
177 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
178 | -p RootImagePolicy='root=verity' \ | |
179 | -p MountAPIVFS=yes \ | |
69dc36f6 | 180 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
181 | cat /usr/lib/os-release | grep -q -F "MARKER=1" |
182 | systemd-run --wait -P \ | |
183 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
184 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
185 | -p RootImagePolicy='root=signed' \ | |
186 | -p MountAPIVFS=yes \ | |
69dc36f6 | 187 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
188 | cat /usr/lib/os-release | grep -q -F "MARKER=1" |
189 | (! systemd-run --wait -P \ | |
190 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
191 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
192 | -p RootImagePolicy='root=encrypted' \ | |
193 | -p MountAPIVFS=yes \ | |
69dc36f6 | 194 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 195 | cat /usr/lib/os-release | grep -q -F "MARKER=1") |
ccb26715 FS |
196 | |
197 | systemd-dissect --root-hash "$MINIMAL_IMAGE_ROOTHASH" --mount "$MINIMAL_IMAGE.gpt" "$IMAGE_DIR/mount" | |
198 | grep -q -F -f "$OS_RELEASE" "$IMAGE_DIR/mount/usr/lib/os-release" | |
199 | grep -q -F -f "$OS_RELEASE" "$IMAGE_DIR/mount/etc/os-release" | |
200 | grep -q -F "MARKER=1" "$IMAGE_DIR/mount/usr/lib/os-release" | |
201 | systemd-dissect --umount "$IMAGE_DIR/mount" | |
202 | ||
203 | systemd-dissect --root-hash "$MINIMAL_IMAGE_ROOTHASH" --mount "$MINIMAL_IMAGE.gpt" --in-memory "$IMAGE_DIR/mount" | |
204 | grep -q -F -f "$OS_RELEASE" "$IMAGE_DIR/mount/usr/lib/os-release" | |
205 | grep -q -F -f "$OS_RELEASE" "$IMAGE_DIR/mount/etc/os-release" | |
206 | grep -q -F "MARKER=1" "$IMAGE_DIR/mount/usr/lib/os-release" | |
207 | systemd-dissect --umount "$IMAGE_DIR/mount" | |
208 | ||
209 | # add explicit -p MountAPIVFS=yes once to test the parser | |
5d259f12 FS |
210 | systemd-run -P \ |
211 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
212 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
213 | -p MountAPIVFS=yes \ | |
69dc36f6 | 214 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
215 | cat /usr/lib/os-release | grep -q -F "MARKER=1" |
216 | systemd-run -P \ | |
217 | -p RootImage="$MINIMAL_IMAGE.raw" \ | |
218 | -p RootImageOptions="root:nosuid,dev home:ro,dev ro,noatime" \ | |
69dc36f6 | 219 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
220 | mount | grep -F "squashfs" | grep -q -F "nosuid" |
221 | systemd-run -P \ | |
222 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
223 | -p RootImageOptions="root:ro,noatime root:ro,dev" \ | |
69dc36f6 | 224 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 225 | mount | grep -F "squashfs" | grep -q -F "noatime" |
ccb26715 FS |
226 | |
227 | mkdir -p "$IMAGE_DIR/result" | |
228 | cat >/run/systemd/system/testservice-50a.service <<EOF | |
229 | [Service] | |
230 | Type=oneshot | |
231 | ExecStart=bash -c "mount >/run/result/a" | |
232 | BindPaths=$IMAGE_DIR/result:/run/result | |
233 | TemporaryFileSystem=/run | |
234 | RootImage=$MINIMAL_IMAGE.raw | |
235 | RootImageOptions=root:ro,noatime home:ro,dev relatime,dev | |
236 | RootImageOptions=nosuid,dev | |
69dc36f6 | 237 | BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout |
ccb26715 FS |
238 | EOF |
239 | systemctl start testservice-50a.service | |
240 | grep -F "squashfs" "$IMAGE_DIR/result/a" | grep -q -F "noatime" | |
241 | grep -F "squashfs" "$IMAGE_DIR/result/a" | grep -q -F -v "nosuid" | |
242 | ||
243 | cat >/run/systemd/system/testservice-50b.service <<EOF | |
244 | [Service] | |
245 | Type=oneshot | |
246 | ExecStart=bash -c "mount >/run/result/b" | |
247 | BindPaths=$IMAGE_DIR/result:/run/result | |
248 | TemporaryFileSystem=/run | |
249 | RootImage=$MINIMAL_IMAGE.gpt | |
250 | RootImageOptions=root:ro,noatime,nosuid home:ro,dev nosuid,dev | |
251 | RootImageOptions=home:ro,dev nosuid,dev,%%foo | |
252 | # this is the default, but let's specify once to test the parser | |
253 | MountAPIVFS=yes | |
69dc36f6 | 254 | BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout |
ccb26715 FS |
255 | EOF |
256 | systemctl start testservice-50b.service | |
257 | grep -F "squashfs" "$IMAGE_DIR/result/b" | grep -q -F "noatime" | |
258 | ||
259 | # Check that specifier escape is applied %%foo → %foo | |
5d259f12 FS |
260 | busctl get-property org.freedesktop.systemd1 \ |
261 | /org/freedesktop/systemd1/unit/testservice_2d50b_2eservice \ | |
262 | org.freedesktop.systemd1.Service RootImageOptions | grep -F "nosuid,dev,%foo" | |
ccb26715 FS |
263 | |
264 | # Now do some checks with MountImages, both by itself, with options and in combination with RootImage, and as single FS or GPT image | |
5d259f12 FS |
265 | systemd-run -P \ |
266 | -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2" \ | |
267 | cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1" | |
268 | systemd-run -P \ | |
269 | -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2" \ | |
270 | cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1" | |
271 | systemd-run -P \ | |
272 | -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2:nosuid,dev" \ | |
273 | mount | grep -F "squashfs" | grep -q -F "nosuid" | |
274 | systemd-run -P \ | |
275 | -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1:root:nosuid $MINIMAL_IMAGE.raw:/run/img2:home:suid" \ | |
276 | mount | grep -F "squashfs" | grep -q -F "nosuid" | |
277 | systemd-run -P \ | |
278 | -p MountImages="$MINIMAL_IMAGE.raw:/run/img2\:3" \ | |
279 | cat /run/img2:3/usr/lib/os-release | grep -q -F "MARKER=1" | |
280 | systemd-run -P \ | |
281 | -p MountImages="$MINIMAL_IMAGE.raw:/run/img2\:3:nosuid" \ | |
282 | mount | grep -F "squashfs" | grep -q -F "nosuid" | |
283 | systemd-run -P \ | |
284 | -p TemporaryFileSystem=/run \ | |
285 | -p RootImage="$MINIMAL_IMAGE.raw" \ | |
286 | -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2" \ | |
69dc36f6 | 287 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
288 | cat /usr/lib/os-release | grep -q -F "MARKER=1" |
289 | systemd-run -P \ | |
290 | -p TemporaryFileSystem=/run \ | |
291 | -p RootImage="$MINIMAL_IMAGE.raw" \ | |
292 | -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2" \ | |
69dc36f6 | 293 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
294 | cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1" |
295 | systemd-run -P \ | |
296 | -p TemporaryFileSystem=/run \ | |
297 | -p RootImage="$MINIMAL_IMAGE.gpt" \ | |
298 | -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ | |
299 | -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2" \ | |
69dc36f6 | 300 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 301 | cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1" |
ccb26715 FS |
302 | cat >/run/systemd/system/testservice-50c.service <<EOF |
303 | [Service] | |
304 | MountAPIVFS=yes | |
305 | TemporaryFileSystem=/run | |
306 | RootImage=$MINIMAL_IMAGE.raw | |
69dc36f6 | 307 | BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout |
ccb26715 FS |
308 | MountImages=$MINIMAL_IMAGE.gpt:/run/img1:root:noatime:home:relatime |
309 | MountImages=$MINIMAL_IMAGE.raw:/run/img2\:3:nosuid | |
310 | ExecStart=bash -c "cat /run/img1/usr/lib/os-release >/run/result/c" | |
311 | ExecStart=bash -c "cat /run/img2:3/usr/lib/os-release >>/run/result/c" | |
312 | ExecStart=bash -c "mount >>/run/result/c" | |
313 | BindPaths=$IMAGE_DIR/result:/run/result | |
314 | Type=oneshot | |
315 | EOF | |
316 | systemctl start testservice-50c.service | |
317 | grep -q -F "MARKER=1" "$IMAGE_DIR/result/c" | |
318 | grep -F "squashfs" "$IMAGE_DIR/result/c" | grep -q -F "noatime" | |
319 | grep -F "squashfs" "$IMAGE_DIR/result/c" | grep -q -F -v "nosuid" | |
320 | ||
321 | # Adding a new mounts at runtime works if the unit is in the active state, | |
322 | # so use Type=notify to make sure there's no race condition in the test | |
323 | cat >/run/systemd/system/testservice-50d.service <<EOF | |
324 | [Service] | |
325 | RuntimeMaxSec=300 | |
326 | Type=notify | |
327 | RemainAfterExit=yes | |
328 | MountAPIVFS=yes | |
329 | PrivateTmp=yes | |
330 | ExecStart=sh -c ' \\ | |
331 | systemd-notify --ready; \\ | |
332 | while [ ! -f /tmp/img/usr/lib/os-release ] || ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do \\ | |
333 | sleep 0.1; \\ | |
334 | done; \\ | |
335 | mount; \\ | |
336 | mount | grep -F "on /tmp/img type squashfs" | grep -q -F "nosuid"; \\ | |
337 | ' | |
338 | EOF | |
339 | systemctl start testservice-50d.service | |
340 | ||
341 | # Mount twice to exercise mount-beneath (on kernel 6.5+, on older kernels it will just overmount) | |
342 | mkdir -p /tmp/wrong/foo | |
343 | mksquashfs /tmp/wrong/foo /tmp/wrong.raw | |
344 | systemctl mount-image --mkdir testservice-50d.service /tmp/wrong.raw /tmp/img | |
345 | test "$(systemctl show -P SubState testservice-50d.service)" = "running" | |
346 | systemctl mount-image --mkdir testservice-50d.service "$MINIMAL_IMAGE.raw" /tmp/img root:nosuid | |
5f42fae2 FS |
347 | # shellcheck disable=SC2016 |
348 | timeout 30s bash -xec 'while [[ $(systemctl show -P SubState testservice-50d.service) == running ]]; do sleep .2; done' | |
ccb26715 FS |
349 | systemctl is-active testservice-50d.service |
350 | ||
351 | # ExtensionImages will set up an overlay | |
5d259f12 | 352 | systemd-run -P \ |
c77dad70 | 353 | --property ExtensionImages=/tmp/app0.raw \ |
5d259f12 | 354 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 355 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
356 | cat /opt/script0.sh | grep -q -F "extension-release.app0" |
357 | systemd-run -P \ | |
c77dad70 | 358 | --property ExtensionImages=/tmp/app0.raw \ |
5d259f12 | 359 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 360 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
361 | cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
362 | systemd-run -P \ | |
c77dad70 | 363 | --property ExtensionImages="/tmp/app0.raw /tmp/app1.raw" \ |
5d259f12 | 364 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 365 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
366 | cat /opt/script0.sh | grep -q -F "extension-release.app0" |
367 | systemd-run -P \ | |
c77dad70 | 368 | --property ExtensionImages="/tmp/app0.raw /tmp/app1.raw" \ |
5d259f12 | 369 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 370 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
371 | cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
372 | systemd-run -P \ | |
c77dad70 | 373 | --property ExtensionImages="/tmp/app0.raw /tmp/app1.raw" \ |
5d259f12 | 374 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 375 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
376 | cat /opt/script1.sh | grep -q -F "extension-release.app2" |
377 | systemd-run -P \ | |
c77dad70 | 378 | --property ExtensionImages="/tmp/app0.raw /tmp/app1.raw" \ |
5d259f12 | 379 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 380 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
381 | cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1" |
382 | systemd-run -P \ | |
c77dad70 | 383 | --property ExtensionImages=/tmp/app-nodistro.raw \ |
5d259f12 | 384 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 385 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
386 | cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
387 | systemd-run -P \ | |
388 | --property ExtensionImages=/etc/service-scoped-test.raw \ | |
389 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 390 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 391 | cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" |
ccb26715 | 392 | # Check that using a symlink to NAME-VERSION.raw works as long as the symlink has the correct name NAME.raw |
c77dad70 DDM |
393 | mkdir -p /tmp/symlink-test/ |
394 | cp /tmp/app-nodistro.raw /tmp/symlink-test/app-nodistro-v1.raw | |
395 | ln -fs /tmp/symlink-test/app-nodistro-v1.raw /tmp/symlink-test/app-nodistro.raw | |
5d259f12 | 396 | systemd-run -P \ |
c77dad70 | 397 | --property ExtensionImages=/tmp/symlink-test/app-nodistro.raw \ |
5d259f12 | 398 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 399 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 400 | cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
ccb26715 FS |
401 | |
402 | # Symlink check again but for confext | |
403 | mkdir -p /etc/symlink-test/ | |
404 | cp /etc/service-scoped-test.raw /etc/symlink-test/service-scoped-test-v1.raw | |
405 | ln -fs /etc/symlink-test/service-scoped-test-v1.raw /etc/symlink-test/service-scoped-test.raw | |
5d259f12 FS |
406 | systemd-run -P \ |
407 | --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw \ | |
408 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 409 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 410 | cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" |
ccb26715 FS |
411 | # And again mixing sysext and confext |
412 | systemd-run -P \ | |
c77dad70 | 413 | --property ExtensionImages=/tmp/symlink-test/app-nodistro.raw \ |
ccb26715 | 414 | --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw \ |
5d259f12 | 415 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 416 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 417 | cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" |
ccb26715 | 418 | systemd-run -P \ |
c77dad70 | 419 | --property ExtensionImages=/tmp/symlink-test/app-nodistro.raw \ |
ccb26715 | 420 | --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw \ |
5d259f12 | 421 | --property RootImage="$MINIMAL_IMAGE.raw" \ |
69dc36f6 | 422 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 423 | cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
ccb26715 FS |
424 | |
425 | cat >/run/systemd/system/testservice-50e.service <<EOF | |
426 | [Service] | |
427 | MountAPIVFS=yes | |
428 | TemporaryFileSystem=/run /var/lib | |
429 | StateDirectory=app0 | |
430 | RootImage=$MINIMAL_IMAGE.raw | |
c77dad70 | 431 | ExtensionImages=/tmp/app0.raw /tmp/app1.raw:nosuid |
69dc36f6 | 432 | BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout |
ccb26715 FS |
433 | # Relevant only for sanitizer runs |
434 | UnsetEnvironment=LD_PRELOAD | |
435 | ExecStart=bash -c '/opt/script0.sh | grep ID' | |
436 | ExecStart=bash -c '/opt/script1.sh | grep ID' | |
437 | Type=oneshot | |
438 | RemainAfterExit=yes | |
439 | EOF | |
440 | systemctl start testservice-50e.service | |
441 | systemctl is-active testservice-50e.service | |
442 | ||
443 | # Check vpick support in ExtensionImages= | |
444 | VBASE="vtest$RANDOM" | |
445 | VDIR="/tmp/$VBASE.v" | |
446 | mkdir "$VDIR" | |
447 | ||
c77dad70 DDM |
448 | ln -s /tmp/app0.raw "$VDIR/${VBASE}_0.raw" |
449 | ln -s /tmp/app1.raw "$VDIR/${VBASE}_1.raw" | |
ccb26715 FS |
450 | |
451 | systemd-run -P -p ExtensionImages="$VDIR" bash -c '/opt/script1.sh | grep ID' | |
452 | ||
453 | rm -rf "$VDIR" | |
454 | ||
455 | # ExtensionDirectories will set up an overlay | |
456 | mkdir -p "$IMAGE_DIR/app0" "$IMAGE_DIR/app1" "$IMAGE_DIR/app-nodistro" "$IMAGE_DIR/service-scoped-test" | |
5d259f12 FS |
457 | (! systemd-run -P \ |
458 | --property ExtensionDirectories="$IMAGE_DIR/nonexistent" \ | |
459 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 460 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
461 | cat /opt/script0.sh) |
462 | (! systemd-run -P \ | |
463 | --property ExtensionDirectories="$IMAGE_DIR/app0" \ | |
464 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 465 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 466 | cat /opt/script0.sh) |
c77dad70 DDM |
467 | systemd-dissect --mount /tmp/app0.raw "$IMAGE_DIR/app0" |
468 | systemd-dissect --mount /tmp/app1.raw "$IMAGE_DIR/app1" | |
469 | systemd-dissect --mount /tmp/app-nodistro.raw "$IMAGE_DIR/app-nodistro" | |
ccb26715 | 470 | systemd-dissect --mount /etc/service-scoped-test.raw "$IMAGE_DIR/service-scoped-test" |
5d259f12 FS |
471 | systemd-run -P \ |
472 | --property ExtensionDirectories="$IMAGE_DIR/app0" \ | |
473 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 474 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
475 | cat /opt/script0.sh | grep -q -F "extension-release.app0" |
476 | systemd-run -P \ | |
477 | --property ExtensionDirectories="$IMAGE_DIR/app0" \ | |
478 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 479 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
480 | cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
481 | systemd-run -P \ | |
482 | --property ExtensionDirectories="$IMAGE_DIR/app0 $IMAGE_DIR/app1" \ | |
483 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 484 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
485 | cat /opt/script0.sh | grep -q -F "extension-release.app0" |
486 | systemd-run -P \ | |
487 | --property ExtensionDirectories="$IMAGE_DIR/app0 $IMAGE_DIR/app1" \ | |
488 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 489 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
490 | cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
491 | systemd-run -P \ | |
492 | --property ExtensionDirectories="$IMAGE_DIR/app0 $IMAGE_DIR/app1" \ | |
493 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 494 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
495 | cat /opt/script1.sh | grep -q -F "extension-release.app2" |
496 | systemd-run -P \ | |
497 | --property ExtensionDirectories="$IMAGE_DIR/app0 $IMAGE_DIR/app1" \ | |
498 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 499 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
500 | cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1" |
501 | systemd-run -P \ | |
502 | --property ExtensionDirectories="$IMAGE_DIR/app-nodistro" \ | |
503 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 504 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 FS |
505 | cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
506 | systemd-run -P \ | |
507 | --property ExtensionDirectories="$IMAGE_DIR/service-scoped-test" \ | |
508 | --property RootImage="$MINIMAL_IMAGE.raw" \ | |
69dc36f6 | 509 | "${BIND_LOG_SOCKETS[@]}" \ |
5d259f12 | 510 | cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" |
ccb26715 FS |
511 | cat >/run/systemd/system/testservice-50f.service <<EOF |
512 | [Service] | |
513 | MountAPIVFS=yes | |
514 | TemporaryFileSystem=/run /var/lib | |
515 | StateDirectory=app0 | |
516 | RootImage=$MINIMAL_IMAGE.raw | |
69dc36f6 | 517 | BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout |
ccb26715 FS |
518 | ExtensionDirectories=$IMAGE_DIR/app0 $IMAGE_DIR/app1 |
519 | # Relevant only for sanitizer runs | |
520 | UnsetEnvironment=LD_PRELOAD | |
521 | ExecStart=bash -c '/opt/script0.sh | grep ID' | |
522 | ExecStart=bash -c '/opt/script1.sh | grep ID' | |
523 | Type=oneshot | |
524 | RemainAfterExit=yes | |
525 | EOF | |
526 | systemctl start testservice-50f.service | |
527 | systemctl is-active testservice-50f.service | |
528 | ||
529 | # Check vpick support in ExtensionDirectories= | |
530 | VBASE="vtest$RANDOM" | |
531 | VDIR="/tmp/$VBASE.v" | |
532 | mkdir "$VDIR" | |
533 | ||
534 | ln -s "$IMAGE_DIR/app0" "$VDIR/${VBASE}_0" | |
535 | ln -s "$IMAGE_DIR/app1" "$VDIR/${VBASE}_1" | |
536 | ||
537 | systemd-run -P --property ExtensionDirectories="$VDIR" cat /opt/script1.sh | grep -q -F "extension-release.app2" | |
538 | ||
539 | rm -rf "$VDIR" | |
540 | ||
541 | systemd-dissect --umount "$IMAGE_DIR/app0" | |
542 | systemd-dissect --umount "$IMAGE_DIR/app1" | |
543 | ||
544 | # Test that an extension consisting of an empty directory under /etc/extensions/ takes precedence | |
545 | mkdir -p /var/lib/extensions/ | |
c77dad70 | 546 | ln -s /tmp/app-nodistro.raw /var/lib/extensions/app-nodistro.raw |
ccb26715 FS |
547 | systemd-sysext merge |
548 | grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file | |
549 | systemd-sysext unmerge | |
550 | mkdir -p /etc/extensions/app-nodistro | |
551 | systemd-sysext merge | |
552 | test ! -e /usr/lib/systemd/system/some_file | |
553 | systemd-sysext unmerge | |
554 | rmdir /etc/extensions/app-nodistro | |
555 | ||
556 | # Similar, but go via varlink | |
557 | varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.List '{}' | |
558 | (! grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file ) | |
559 | varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Merge '{}' | |
560 | grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file | |
561 | varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Refresh '{}' | |
562 | grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file | |
563 | varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Unmerge '{}' | |
564 | (! grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file ) | |
565 | ||
566 | # Check that extensions cannot contain os-release | |
567 | mkdir -p /run/extensions/app-reject/usr/lib/{extension-release.d/,systemd/system} | |
568 | echo "ID=_any" >/run/extensions/app-reject/usr/lib/extension-release.d/extension-release.app-reject | |
569 | echo "ID=_any" >/run/extensions/app-reject/usr/lib/os-release | |
570 | touch /run/extensions/app-reject/usr/lib/systemd/system/other_file | |
571 | (! systemd-sysext merge) | |
572 | test ! -e /usr/lib/systemd/system/some_file | |
573 | test ! -e /usr/lib/systemd/system/other_file | |
574 | systemd-sysext unmerge | |
575 | rm -rf /run/extensions/app-reject | |
576 | rm /var/lib/extensions/app-nodistro.raw | |
577 | ||
578 | # Some super basic test that RootImage= works with .v/ dirs | |
579 | VBASE="vtest$RANDOM" | |
580 | VDIR="/tmp/$VBASE.v" | |
581 | mkdir "$VDIR" | |
582 | ||
583 | ln -s "$MINIMAL_IMAGE.raw" "$VDIR/${VBASE}_33.raw" | |
584 | ln -s "$MINIMAL_IMAGE.raw" "$VDIR/${VBASE}_34.raw" | |
585 | ln -s "$MINIMAL_IMAGE.raw" "$VDIR/${VBASE}_35.raw" | |
586 | ||
69dc36f6 | 587 | systemd-run -P -p RootImage="$VDIR" "${BIND_LOG_SOCKETS[@]}" cat /usr/lib/os-release | grep -q -F "MARKER=1" |
ccb26715 FS |
588 | |
589 | rm "$VDIR/${VBASE}_33.raw" "$VDIR/${VBASE}_34.raw" "$VDIR/${VBASE}_35.raw" | |
590 | rmdir "$VDIR" | |
591 | ||
592 | mkdir -p /run/machines /run/portables /run/extensions | |
593 | touch /run/machines/a.raw /run/portables/b.raw /run/extensions/c.raw | |
594 | ||
595 | systemd-dissect --discover --json=short >/tmp/discover.json | |
596 | grep -q -F '{"name":"a","type":"raw","class":"machine","ro":false,"path":"/run/machines/a.raw"' /tmp/discover.json | |
597 | grep -q -F '{"name":"b","type":"raw","class":"portable","ro":false,"path":"/run/portables/b.raw"' /tmp/discover.json | |
598 | grep -q -F '{"name":"c","type":"raw","class":"sysext","ro":false,"path":"/run/extensions/c.raw"' /tmp/discover.json | |
599 | rm /tmp/discover.json /run/machines/a.raw /run/portables/b.raw /run/extensions/c.raw | |
600 | ||
601 | LOOP="$(systemd-dissect --attach --loop-ref=waldo "$MINIMAL_IMAGE.raw")" | |
602 | ||
603 | # Wait until the symlinks we want to test are established | |
604 | udevadm trigger -w "$LOOP" | |
605 | ||
606 | # Check if the /dev/loop/* symlinks really reference the right device | |
607 | test /dev/disk/by-loop-ref/waldo -ef "$LOOP" | |
608 | ||
609 | if [ "$(stat -c '%Hd:%Ld' "$MINIMAL_IMAGE.raw")" != '?d:?d' ] ; then | |
610 | # Old stat didn't know the %Hd and %Ld specifiers and turned them into ?d | |
611 | # instead. Let's simply skip the test on such old systems. | |
612 | test "$(stat -c '/dev/disk/by-loop-inode/%Hd:%Ld-%i' "$MINIMAL_IMAGE.raw")" -ef "$LOOP" | |
613 | fi | |
614 | ||
615 | # Detach by loopback device | |
616 | systemd-dissect --detach "$LOOP" | |
617 | ||
618 | # Test long reference name. | |
619 | # Note, sizeof_field(struct loop_info64, lo_file_name) == 64, | |
620 | # and --loop-ref accepts upto 63 characters, and udev creates symlink | |
621 | # based on the name when it has upto _62_ characters. | |
622 | name="$(for _ in {1..62}; do echo -n 'x'; done)" | |
623 | LOOP="$(systemd-dissect --attach --loop-ref="$name" "$MINIMAL_IMAGE.raw")" | |
624 | udevadm trigger -w "$LOOP" | |
625 | ||
626 | # Check if the /dev/disk/by-loop-ref/$name symlink really references the right device | |
627 | test "/dev/disk/by-loop-ref/$name" -ef "$LOOP" | |
628 | ||
629 | # Detach by the /dev/disk/by-loop-ref symlink | |
630 | systemd-dissect --detach "/dev/disk/by-loop-ref/$name" | |
631 | ||
632 | name="$(for _ in {1..63}; do echo -n 'x'; done)" | |
633 | LOOP="$(systemd-dissect --attach --loop-ref="$name" "$MINIMAL_IMAGE.raw")" | |
634 | udevadm trigger -w "$LOOP" | |
635 | ||
636 | # Check if the /dev/disk/by-loop-ref/$name symlink does not exist | |
637 | test ! -e "/dev/disk/by-loop-ref/$name" | |
638 | ||
639 | # Detach by backing inode | |
640 | systemd-dissect --detach "$MINIMAL_IMAGE.raw" | |
641 | (! systemd-dissect --detach "$MINIMAL_IMAGE.raw") | |
642 | ||
643 | # check for confext functionality | |
644 | mkdir -p /run/confexts/test/etc/extension-release.d | |
645 | echo "ID=_any" >/run/confexts/test/etc/extension-release.d/extension-release.test | |
646 | echo "ARCHITECTURE=_any" >>/run/confexts/test/etc/extension-release.d/extension-release.test | |
647 | echo "MARKER_CONFEXT_123" >/run/confexts/test/etc/testfile | |
648 | cat <<EOF >/run/confexts/test/etc/testscript | |
649 | #!/bin/bash | |
650 | echo "This should not happen" | |
651 | EOF | |
652 | chmod +x /run/confexts/test/etc/testscript | |
653 | systemd-confext merge | |
654 | grep -q -F "MARKER_CONFEXT_123" /etc/testfile | |
655 | (! /etc/testscript) | |
656 | systemd-confext status | |
657 | systemd-confext unmerge | |
658 | rm -rf /run/confexts/ | |
659 | ||
660 | unsquashfs -no-xattrs -d /tmp/img "$MINIMAL_IMAGE.raw" | |
661 | systemd-run --unit=test-root-ephemeral \ | |
662 | -p RootDirectory=/tmp/img \ | |
663 | -p RootEphemeral=yes \ | |
664 | -p Type=exec \ | |
69dc36f6 | 665 | "${BIND_LOG_SOCKETS[@]}" \ |
ccb26715 FS |
666 | bash -c "touch /abc && sleep infinity" |
667 | test -n "$(ls -A /var/lib/systemd/ephemeral-trees)" | |
668 | systemctl stop test-root-ephemeral | |
669 | # shellcheck disable=SC2016 | |
670 | timeout 10 bash -c 'until test -z "$(ls -A /var/lib/systemd/ephemeral-trees)"; do sleep .5; done' | |
671 | test ! -f /tmp/img/abc | |
672 | ||
dcbf0be1 DDM |
673 | systemd-dissect --mtree /tmp/img >/dev/null |
674 | systemd-dissect --list /tmp/img >/dev/null | |
ccb26715 FS |
675 | |
676 | read -r SHA256SUM1 _ < <(systemd-dissect --copy-from /tmp/img etc/os-release | sha256sum) | |
677 | test "$SHA256SUM1" != "" | |
678 | ||
679 | echo abc > abc | |
680 | systemd-dissect --copy-to /tmp/img abc /abc | |
681 | test -f /tmp/img/abc | |
682 | ||
683 | # Test for dissect tool support with systemd-sysext | |
684 | mkdir -p /run/extensions/ testkit/usr/lib/extension-release.d/ | |
685 | echo "ID=_any" >testkit/usr/lib/extension-release.d/extension-release.testkit | |
686 | echo "ARCHITECTURE=_any" >>testkit/usr/lib/extension-release.d/extension-release.testkit | |
687 | echo "MARKER_SYSEXT_123" >testkit/usr/lib/testfile | |
688 | mksquashfs testkit/ testkit.raw | |
689 | cp testkit.raw /run/extensions/ | |
690 | unsquashfs -l /run/extensions/testkit.raw | |
691 | systemd-dissect --no-pager /run/extensions/testkit.raw | grep -q '✓ sysext for portable service' | |
692 | systemd-dissect --no-pager /run/extensions/testkit.raw | grep -q '✓ sysext for system' | |
693 | systemd-sysext merge | |
694 | systemd-sysext status | |
695 | grep -q -F "MARKER_SYSEXT_123" /usr/lib/testfile | |
696 | systemd-sysext unmerge | |
697 | rm -rf /run/extensions/ testkit/ | |
698 | ||
699 | # Test for dissect tool support with systemd-confext | |
700 | mkdir -p /run/confexts/ testjob/etc/extension-release.d/ | |
701 | echo "ID=_any" >testjob/etc/extension-release.d/extension-release.testjob | |
702 | echo "ARCHITECTURE=_any" >>testjob/etc/extension-release.d/extension-release.testjob | |
703 | echo "MARKER_CONFEXT_123" >testjob/etc/testfile | |
704 | mksquashfs testjob/ testjob.raw | |
705 | cp testjob.raw /run/confexts/ | |
706 | unsquashfs -l /run/confexts/testjob.raw | |
707 | systemd-dissect --no-pager /run/confexts/testjob.raw | grep -q '✓ confext for system' | |
708 | systemd-dissect --no-pager /run/confexts/testjob.raw | grep -q '✓ confext for portable service' | |
709 | systemd-confext merge | |
710 | systemd-confext status | |
711 | grep -q -F "MARKER_CONFEXT_123" /etc/testfile | |
712 | systemd-confext unmerge | |
713 | rm -rf /run/confexts/ testjob/ | |
714 | ||
69dc36f6 | 715 | systemd-run -P -p RootImage="$MINIMAL_IMAGE.raw" "${BIND_LOG_SOCKETS[@]}" cat /run/host/os-release | cmp "$OS_RELEASE" |
ccb26715 FS |
716 | |
717 | # Test that systemd-sysext reloads the daemon. | |
718 | mkdir -p /var/lib/extensions/ | |
c77dad70 | 719 | ln -s /tmp/app-reload.raw /var/lib/extensions/app-reload.raw |
ccb26715 FS |
720 | systemd-sysext merge --no-reload |
721 | # the service should not be running | |
722 | (! systemctl --quiet is-active foo.service) | |
723 | systemd-sysext unmerge --no-reload | |
724 | systemd-sysext merge | |
725 | # shellcheck disable=SC2016 | |
726 | timeout 30s bash -xec 'until [[ $(journalctl -b -u foo.service _TRANSPORT=stdout -o cat) == foo ]]; do sleep .5; done' | |
727 | systemd-sysext unmerge --no-reload | |
728 | # Grep on the Warning to find the warning helper mentioning the daemon reload. | |
729 | systemctl status foo.service 2>&1 | grep -q -F "Warning" | |
730 | systemd-sysext merge | |
731 | systemd-sysext unmerge | |
732 | systemctl status foo.service 2>&1 | grep -v -q -F "Warning" | |
733 | rm /var/lib/extensions/app-reload.raw | |
734 | ||
735 | # Sneak in a couple of expected-to-fail invocations to cover | |
736 | # https://github.com/systemd/systemd/issues/29610 | |
737 | (! systemd-run -P -p MountImages="/this/should/definitely/not/exist.img:/run/img2\:3:nosuid" false) | |
738 | (! systemd-run -P -p ExtensionImages="/this/should/definitely/not/exist.img" false) | |
739 | (! systemd-run -P -p RootImage="/this/should/definitely/not/exist.img" false) | |
740 | (! systemd-run -P -p ExtensionDirectories="/foo/bar /foo/baz" false) |