]>
Commit | Line | Data |
---|---|---|
e7cbe5cb | 1 | #!/usr/bin/env bash |
7b3cec95 | 2 | # SPDX-License-Identifier: LGPL-2.1-or-later |
e7cbe5cb LB |
3 | # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- |
4 | # ex: ts=8 sw=4 sts=4 et filetype=sh | |
99d9edf0 | 5 | # shellcheck disable=SC2233,SC2235 |
084575ff | 6 | set -eux |
e7cbe5cb LB |
7 | set -o pipefail |
8 | ||
08de6f94 LB |
9 | export SYSTEMD_LOG_LEVEL=debug |
10 | ||
e71bac72 | 11 | # shellcheck disable=SC2317 |
d3fcb736 YW |
12 | cleanup() {( |
13 | set +ex | |
14 | ||
69398734 LB |
15 | if [ -z "${image_dir}" ]; then |
16 | return | |
17 | fi | |
d3fcb736 YW |
18 | umount "${image_dir}/app0" |
19 | umount "${image_dir}/app1" | |
20 | umount "${image_dir}/app-nodistro" | |
b856f1df | 21 | umount "${image_dir}/service-scoped-test" |
69398734 | 22 | rm -rf "${image_dir}" |
d3fcb736 | 23 | )} |
69398734 | 24 | |
20d4b3cc YW |
25 | udevadm control --log-level=debug |
26 | ||
e7cbe5cb LB |
27 | cd /tmp |
28 | ||
69398734 LB |
29 | image_dir="$(mktemp -d -t -p /tmp tmp.XXXXXX)" |
30 | if [ -z "${image_dir}" ] || [ ! -d "${image_dir}" ]; then | |
31 | echo "mktemp under /tmp failed" | |
32 | exit 1 | |
e7cbe5cb LB |
33 | fi |
34 | ||
69398734 LB |
35 | trap cleanup EXIT |
36 | ||
9785c44d LB |
37 | cp /usr/share/minimal* "${image_dir}/" |
38 | image="${image_dir}/minimal_0" | |
38825267 FS |
39 | roothash="$(cat "${image}.roothash")" |
40 | ||
41 | os_release="$(test -e /etc/os-release && echo /etc/os-release || echo /usr/lib/os-release)" | |
42 | ||
43 | systemd-dissect --json=short "${image}.raw" | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"' | |
44 | systemd-dissect "${image}.raw" | grep -q -F "MARKER=1" | |
45 | systemd-dissect "${image}.raw" | grep -q -F -f <(sed 's/"//g' "$os_release") | |
46 | ||
efffde8e | 47 | systemd-dissect --list "${image}.raw" | grep -q '^etc/os-release$' |
12d58b6c DDM |
48 | systemd-dissect --mtree "${image}.raw" --mtree-hash yes | grep -qe "^./usr/bin/cat type=file mode=0755 uid=0 gid=0 size=[0-9]* sha256sum=[a-z0-9]*$" |
49 | systemd-dissect --mtree "${image}.raw" --mtree-hash no | grep -qe "^./usr/bin/cat type=file mode=0755 uid=0 gid=0 size=[0-9]*$" | |
efffde8e LP |
50 | |
51 | read -r SHA256SUM1 _ < <(systemd-dissect --copy-from "${image}.raw" etc/os-release | sha256sum) | |
52 | test "$SHA256SUM1" != "" | |
53 | read -r SHA256SUM2 _ < <(systemd-dissect --read-only --with "${image}.raw" sha256sum etc/os-release) | |
54 | test "$SHA256SUM2" != "" | |
55 | test "$SHA256SUM1" = "$SHA256SUM2" | |
56 | ||
b68f4cad LP |
57 | if systemctl --version | grep -qF -- "+LIBARCHIVE" ; then |
58 | # Make sure tarballs are reproducible | |
59 | read -r SHA256SUM1 _ < <(systemd-dissect --make-archive "${image}.raw" | sha256sum) | |
60 | test "$SHA256SUM1" != "" | |
61 | read -r SHA256SUM2 _ < <(systemd-dissect --make-archive "${image}.raw" | sha256sum) | |
62 | test "$SHA256SUM2" != "" | |
63 | test "$SHA256SUM1" = "$SHA256SUM2" | |
64 | # Also check that a file we expect to be there is there | |
65 | systemd-dissect --make-archive "${image}.raw" | tar t | grep etc/os-release | |
66 | fi | |
67 | ||
38825267 FS |
68 | mv "${image}.verity" "${image}.fooverity" |
69 | mv "${image}.roothash" "${image}.foohash" | |
70 | systemd-dissect --json=short "${image}.raw" --root-hash="${roothash}" --verity-data="${image}.fooverity" | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"' | |
71 | systemd-dissect "${image}.raw" --root-hash="${roothash}" --verity-data="${image}.fooverity" | grep -q -F "MARKER=1" | |
72 | systemd-dissect "${image}.raw" --root-hash="${roothash}" --verity-data="${image}.fooverity" | grep -q -F -f <(sed 's/"//g' "$os_release") | |
73 | mv "${image}.fooverity" "${image}.verity" | |
74 | mv "${image}.foohash" "${image}.roothash" | |
75 | ||
76 | mkdir -p "${image_dir}/mount" "${image_dir}/mount2" | |
77 | systemd-dissect --mount "${image}.raw" "${image_dir}/mount" | |
78 | grep -q -F -f "$os_release" "${image_dir}/mount/usr/lib/os-release" | |
79 | grep -q -F -f "$os_release" "${image_dir}/mount/etc/os-release" | |
80 | grep -q -F "MARKER=1" "${image_dir}/mount/usr/lib/os-release" | |
ac1f3ad0 | 81 | # Verity volume should be shared (opened only once) |
38825267 FS |
82 | systemd-dissect --mount "${image}.raw" "${image_dir}/mount2" |
83 | verity_count=$(find /dev/mapper/ -name "*verity*" | wc -l) | |
ac1f3ad0 LB |
84 | # In theory we should check that count is exactly one. In practice, libdevmapper |
85 | # randomly and unpredictably fails with an unhelpful EINVAL when a device is open | |
86 | # (and even mounted and in use), so best-effort is the most we can do for now | |
38825267 | 87 | if [ "${verity_count}" -lt 1 ]; then |
ac1f3ad0 LB |
88 | echo "Verity device ${image}.raw not found in /dev/mapper/" |
89 | exit 1 | |
90 | fi | |
ac1f1adf DDM |
91 | systemd-dissect --umount "${image_dir}/mount" |
92 | systemd-dissect --umount "${image_dir}/mount2" | |
e7cbe5cb | 93 | |
43ed3d29 | 94 | systemd-run -P -p RootImage="${image}.raw" cat /usr/lib/os-release | grep -q -F "MARKER=1" |
38825267 FS |
95 | mv "${image}.verity" "${image}.fooverity" |
96 | mv "${image}.roothash" "${image}.foohash" | |
43ed3d29 | 97 | systemd-run -P -p RootImage="${image}.raw" -p RootHash="${image}.foohash" -p RootVerity="${image}.fooverity" cat /usr/lib/os-release | grep -q -F "MARKER=1" |
d583cf45 | 98 | # Let's use the long option name just here as a test |
43ed3d29 | 99 | systemd-run -P --property RootImage="${image}.raw" --property RootHash="${roothash}" --property RootVerity="${image}.fooverity" cat /usr/lib/os-release | grep -q -F "MARKER=1" |
38825267 FS |
100 | mv "${image}.fooverity" "${image}.verity" |
101 | mv "${image}.foohash" "${image}.roothash" | |
2bc148ad | 102 | |
a5f1d665 LB |
103 | # Make a GPT disk on the fly, with the squashfs as partition 1 and the verity hash tree as partition 2 |
104 | machine="$(uname -m)" | |
105 | if [ "${machine}" = "x86_64" ]; then | |
106 | root_guid=4f68bce3-e8cd-4db1-96e7-fbcaf984b709 | |
107 | verity_guid=2c7357ed-ebd2-46d9-aec1-23d437ec2bf5 | |
2c424ee0 | 108 | signature_guid=41092b05-9fc8-4523-994f-2def0408b176 |
91987527 | 109 | architecture="x86-64" |
a5f1d665 LB |
110 | elif [ "${machine}" = "i386" ] || [ "${machine}" = "i686" ] || [ "${machine}" = "x86" ]; then |
111 | root_guid=44479540-f297-41b2-9af7-d131d5f0458a | |
112 | verity_guid=d13c5d3b-b5d1-422a-b29f-9454fdc89d76 | |
2c424ee0 | 113 | signature_guid=5996fc05-109c-48de-808b-23fa0830b676 |
91987527 | 114 | architecture="x86" |
a5f1d665 LB |
115 | elif [ "${machine}" = "aarch64" ] || [ "${machine}" = "aarch64_be" ] || [ "${machine}" = "armv8b" ] || [ "${machine}" = "armv8l" ]; then |
116 | root_guid=b921b045-1df0-41c3-af44-4c6f280d3fae | |
117 | verity_guid=df3300ce-d69f-4c92-978c-9bfb0f38d820 | |
2c424ee0 | 118 | signature_guid=6db69de6-29f4-4758-a7a5-962190f00ce3 |
91987527 | 119 | architecture="arm64" |
a5f1d665 LB |
120 | elif [ "${machine}" = "arm" ]; then |
121 | root_guid=69dad710-2ce4-4e3c-b16c-21a1d49abed3 | |
122 | verity_guid=7386cdf2-203c-47a9-a498-f2ecce45a2d6 | |
2c424ee0 | 123 | signature_guid=42b0455f-eb11-491d-98d3-56145ba9d037 |
91987527 | 124 | architecture="arm" |
0444a6e4 XW |
125 | elif [ "${machine}" = "loongarch64" ]; then |
126 | root_guid=77055800-792c-4f94-b39a-98c91b762bb6 | |
127 | verity_guid=f3393b22-e9af-4613-a948-9d3bfbd0c535 | |
128 | signature_guid=5afb67eb-ecc8-4f85-ae8e-ac1e7c50e7d0 | |
129 | architecture="loongarch64" | |
a5f1d665 LB |
130 | elif [ "${machine}" = "ia64" ]; then |
131 | root_guid=993d8d3d-f80e-4225-855a-9daf8ed7ea97 | |
132 | verity_guid=86ed10d5-b607-45bb-8957-d350f23d0571 | |
2c424ee0 | 133 | signature_guid=e98b36ee-32ba-4882-9b12-0ce14655f46a |
91987527 | 134 | architecture="ia64" |
a94b9977 LB |
135 | elif [ "${machine}" = "s390x" ]; then |
136 | root_guid=5eead9a9-fe09-4a1e-a1d7-520d00531306 | |
137 | verity_guid=b325bfbe-c7be-4ab8-8357-139e652d2f6b | |
138 | signature_guid=c80187a5-73a3-491a-901a-017c3fa953e9 | |
139 | architecture="s390x" | |
91987527 | 140 | elif [ "${machine}" = "ppc64le" ]; then |
a94b9977 LB |
141 | root_guid=c31c45e6-3f39-412e-80fb-4809c4980599 |
142 | verity_guid=906bd944-4589-4aae-a4e4-dd983917446a | |
143 | signature_guid=d4a236e7-e873-4c07-bf1d-bf6cf7f1c3c6 | |
144 | architecture="ppc64-le" | |
08de6f94 LB |
145 | else |
146 | echo "Unexpected uname -m: ${machine} in testsuite-50.sh, please fix me" | |
147 | exit 1 | |
a5f1d665 LB |
148 | fi |
149 | # du rounds up to block size, which is more helpful for partitioning | |
38825267 FS |
150 | root_size="$(du -k "${image}.raw" | cut -f1)" |
151 | verity_size="$(du -k "${image}.verity" | cut -f1)" | |
2c424ee0 | 152 | signature_size=4 |
a5f1d665 | 153 | # 4MB seems to be the minimum size blkid will accept, below that probing fails |
2c424ee0 | 154 | dd if=/dev/zero of="${image}.gpt" bs=512 count=$((8192+root_size*2+verity_size*2+signature_size*2)) |
a5f1d665 LB |
155 | # sfdisk seems unhappy if the size overflows into the next unit, eg: 1580KiB will be interpreted as 1MiB |
156 | # so do some basic rounding up if the minimal image is more than 1 MB | |
38825267 FS |
157 | if [ "${root_size}" -ge 1024 ]; then |
158 | root_size="$((root_size/1024 + 1))MiB" | |
a5f1d665 LB |
159 | else |
160 | root_size="${root_size}KiB" | |
161 | fi | |
38825267 | 162 | verity_size="$((verity_size * 2))KiB" |
2c424ee0 LP |
163 | signature_size="$((signature_size * 2))KiB" |
164 | ||
c9d1c37c LB |
165 | HAVE_OPENSSL=0 |
166 | if systemctl --version | grep -q -- +OPENSSL ; then | |
85e3a3a8 MB |
167 | # The openssl binary is installed conditionally. |
168 | # If we have OpenSSL support enabled and openssl is missing, fail early | |
169 | # with a proper error message. | |
170 | if ! command -v openssl >/dev/null 2>&1; then | |
171 | echo "openssl missing" >/failed | |
172 | exit 1 | |
173 | fi | |
c4eb8887 | 174 | |
c9d1c37c | 175 | HAVE_OPENSSL=1 |
c4eb8887 | 176 | OPENSSL_CONFIG="$(mktemp)" |
c9d1c37c | 177 | # Unfortunately OpenSSL insists on reading some config file, hence provide one with mostly placeholder contents |
c4eb8887 | 178 | cat >"${OPENSSL_CONFIG:?}" <<EOF |
2c424ee0 LP |
179 | [ req ] |
180 | prompt = no | |
181 | distinguished_name = req_distinguished_name | |
182 | ||
183 | [ req_distinguished_name ] | |
184 | C = DE | |
185 | ST = Test State | |
186 | L = Test Locality | |
187 | O = Org Name | |
188 | OU = Org Unit Name | |
189 | CN = Common Name | |
190 | emailAddress = test@email.com | |
191 | EOF | |
192 | ||
c9d1c37c | 193 | # Create key pair |
c4eb8887 | 194 | openssl req -config "$OPENSSL_CONFIG" -new -x509 -newkey rsa:1024 -keyout "${image}.key" -out "${image}.crt" -days 365 -nodes |
c9d1c37c LB |
195 | # Sign Verity root hash with it |
196 | openssl smime -sign -nocerts -noattr -binary -in "${image}.roothash" -inkey "${image}.key" -signer "${image}.crt" -outform der -out "${image}.roothash.p7s" | |
197 | # Generate signature partition JSON data | |
7a17e41d | 198 | echo '{"rootHash":"'"${roothash}"'","signature":"'"$(base64 -w 0 <"${image}.roothash.p7s")"'"}' >"${image}.verity-sig" |
c9d1c37c LB |
199 | # Pad it |
200 | truncate -s "${signature_size}" "${image}.verity-sig" | |
201 | # Register certificate in the (userspace) verity key ring | |
202 | mkdir -p /run/verity.d | |
203 | ln -s "${image}.crt" /run/verity.d/ok.crt | |
204 | fi | |
2c424ee0 | 205 | |
38825267 FS |
206 | # Construct a UUID from hash |
207 | # input: 11111111222233334444555566667777 | |
208 | # output: 11111111-2222-3333-4444-555566667777 | |
209 | uuid="$(head -c 32 "${image}.roothash" | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.+)/\1-\2-\3-\4-\5/')" | |
210 | echo -e "label: gpt\nsize=${root_size}, type=${root_guid}, uuid=${uuid}" | sfdisk "${image}.gpt" | |
211 | uuid="$(tail -c 32 "${image}.roothash" | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.+)/\1-\2-\3-\4-\5/')" | |
212 | echo -e "size=${verity_size}, type=${verity_guid}, uuid=${uuid}" | sfdisk "${image}.gpt" --append | |
c9d1c37c LB |
213 | if [ "${HAVE_OPENSSL}" -eq 1 ]; then |
214 | echo -e "size=${signature_size}, type=${signature_guid}" | sfdisk "${image}.gpt" --append | |
215 | fi | |
38825267 FS |
216 | sfdisk --part-label "${image}.gpt" 1 "Root Partition" |
217 | sfdisk --part-label "${image}.gpt" 2 "Verity Partition" | |
c9d1c37c LB |
218 | if [ "${HAVE_OPENSSL}" -eq 1 ]; then |
219 | sfdisk --part-label "${image}.gpt" 3 "Signature Partition" | |
220 | fi | |
38825267 | 221 | loop="$(losetup --show -P -f "${image}.gpt")" |
ba44a5c7 YW |
222 | partitions=( |
223 | "${loop:?}p1" | |
224 | "${loop:?}p2" | |
225 | ) | |
c9d1c37c | 226 | if [ "${HAVE_OPENSSL}" -eq 1 ]; then |
ba44a5c7 YW |
227 | partitions+=( "${loop:?}p3" ) |
228 | fi | |
229 | # The kernel sometimes(?) does not emit "add" uevent for loop block partition devices. | |
230 | # Let's not expect the devices to be initialized. | |
231 | udevadm wait --timeout 60 --settle --initialized=no "${partitions[@]}" | |
232 | udevadm lock --device="${loop}p1" dd if="${image}.raw" of="${loop}p1" | |
233 | udevadm lock --device="${loop}p2" dd if="${image}.verity" of="${loop}p2" | |
234 | if [ "${HAVE_OPENSSL}" -eq 1 ]; then | |
235 | udevadm lock --device="${loop}p3" dd if="${image}.verity-sig" of="${loop}p3" | |
c9d1c37c | 236 | fi |
38825267 | 237 | losetup -d "${loop}" |
a5f1d665 | 238 | |
35afe47a | 239 | # Derive partition UUIDs from root hash, in UUID syntax |
38825267 FS |
240 | ROOT_UUID="$(systemd-id128 -u show "$(head -c 32 "${image}.roothash")" -u | tail -n 1 | cut -b 6-)" |
241 | VERITY_UUID="$(systemd-id128 -u show "$(tail -c 32 "${image}.roothash")" -u | tail -n 1 | cut -b 6-)" | |
a5f1d665 | 242 | |
3dd73ea7 | 243 | systemd-dissect --json=short --root-hash "${roothash}" "${image}.gpt" | grep -q '{"rw":"ro","designator":"root","partition_uuid":"'"$ROOT_UUID"'","partition_label":"Root Partition","fstype":"squashfs","architecture":"'"$architecture"'","verity":"signed",' |
ee8e497d | 244 | systemd-dissect --json=short --root-hash "${roothash}" "${image}.gpt" | grep -q '{"rw":"ro","designator":"root-verity","partition_uuid":"'"$VERITY_UUID"'","partition_label":"Verity Partition","fstype":"DM_verity_hash","architecture":"'"$architecture"'","verity":null,' |
3dd73ea7 DDM |
245 | if [ "${HAVE_OPENSSL}" -eq 1 ]; then |
246 | systemd-dissect --json=short --root-hash "${roothash}" "${image}.gpt" | grep -q -E '{"rw":"ro","designator":"root-verity-sig","partition_uuid":"'".*"'","partition_label":"Signature Partition","fstype":"verity_hash_signature","architecture":"'"$architecture"'","verity":null,' | |
247 | fi | |
38825267 FS |
248 | systemd-dissect --root-hash "${roothash}" "${image}.gpt" | grep -q -F "MARKER=1" |
249 | systemd-dissect --root-hash "${roothash}" "${image}.gpt" | grep -q -F -f <(sed 's/"//g' "$os_release") | |
35afe47a | 250 | |
f1f42aea LP |
251 | # Test image policies |
252 | systemd-dissect --validate "${image}.gpt" | |
253 | systemd-dissect --validate "${image}.gpt" --image-policy='*' | |
254 | (! systemd-dissect --validate "${image}.gpt" --image-policy='~') | |
255 | (! systemd-dissect --validate "${image}.gpt" --image-policy='-') | |
256 | (! systemd-dissect --validate "${image}.gpt" --image-policy=root=absent) | |
257 | (! systemd-dissect --validate "${image}.gpt" --image-policy=swap=unprotected+encrypted+verity) | |
258 | systemd-dissect --validate "${image}.gpt" --image-policy=root=unprotected | |
259 | systemd-dissect --validate "${image}.gpt" --image-policy=root=verity | |
260 | systemd-dissect --validate "${image}.gpt" --image-policy=root=verity:root-verity-sig=unused+absent | |
261 | systemd-dissect --validate "${image}.gpt" --image-policy=root=verity:swap=absent | |
262 | systemd-dissect --validate "${image}.gpt" --image-policy=root=verity:swap=absent+unprotected | |
263 | (! systemd-dissect --validate "${image}.gpt" --image-policy=root=verity:root-verity=unused+absent) | |
264 | systemd-dissect --validate "${image}.gpt" --image-policy=root=signed | |
265 | (! systemd-dissect --validate "${image}.gpt" --image-policy=root=signed:root-verity-sig=unused+absent) | |
266 | (! systemd-dissect --validate "${image}.gpt" --image-policy=root=signed:root-verity=unused+absent) | |
267 | ||
268 | # Test RootImagePolicy= unit file setting | |
269 | systemd-run --wait -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1" | |
270 | systemd-run --wait -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p RootImagePolicy='*' -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1" | |
271 | (! systemd-run --wait -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p RootImagePolicy='~' -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1") | |
272 | (! systemd-run --wait -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p RootImagePolicy='-' -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1") | |
273 | (! systemd-run --wait -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p RootImagePolicy='root=absent' -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1") | |
274 | systemd-run --wait -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p RootImagePolicy='root=verity' -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1" | |
275 | systemd-run --wait -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p RootImagePolicy='root=signed' -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1" | |
276 | (! systemd-run --wait -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p RootImagePolicy='root=encrypted' -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1") | |
277 | ||
38825267 FS |
278 | systemd-dissect --root-hash "${roothash}" --mount "${image}.gpt" "${image_dir}/mount" |
279 | grep -q -F -f "$os_release" "${image_dir}/mount/usr/lib/os-release" | |
280 | grep -q -F -f "$os_release" "${image_dir}/mount/etc/os-release" | |
281 | grep -q -F "MARKER=1" "${image_dir}/mount/usr/lib/os-release" | |
ac1f1adf | 282 | systemd-dissect --umount "${image_dir}/mount" |
a5f1d665 | 283 | |
971d83a8 LP |
284 | systemd-dissect --root-hash "${roothash}" --mount "${image}.gpt" --in-memory "${image_dir}/mount" |
285 | grep -q -F -f "$os_release" "${image_dir}/mount/usr/lib/os-release" | |
286 | grep -q -F -f "$os_release" "${image_dir}/mount/etc/os-release" | |
287 | grep -q -F "MARKER=1" "${image_dir}/mount/usr/lib/os-release" | |
288 | systemd-dissect --umount "${image_dir}/mount" | |
289 | ||
d583cf45 | 290 | # add explicit -p MountAPIVFS=yes once to test the parser |
43ed3d29 | 291 | systemd-run -P -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1" |
2bc148ad | 292 | |
43ed3d29 LP |
293 | systemd-run -P -p RootImage="${image}.raw" -p RootImageOptions="root:nosuid,dev home:ro,dev ro,noatime" mount | grep -F "squashfs" | grep -q -F "nosuid" |
294 | systemd-run -P -p RootImage="${image}.gpt" -p RootImageOptions="root:ro,noatime root:ro,dev" mount | grep -F "squashfs" | grep -q -F "noatime" | |
18d73705 | 295 | |
38825267 | 296 | mkdir -p "${image_dir}/result" |
d583cf45 | 297 | cat >/run/systemd/system/testservice-50a.service <<EOF |
18d73705 LB |
298 | [Service] |
299 | Type=oneshot | |
d583cf45 | 300 | ExecStart=bash -c "mount >/run/result/a" |
9ece6444 LB |
301 | BindPaths=${image_dir}/result:/run/result |
302 | TemporaryFileSystem=/run | |
18d73705 | 303 | RootImage=${image}.raw |
9ece6444 | 304 | RootImageOptions=root:ro,noatime home:ro,dev relatime,dev |
18d73705 LB |
305 | RootImageOptions=nosuid,dev |
306 | EOF | |
307 | systemctl start testservice-50a.service | |
38825267 FS |
308 | grep -F "squashfs" "${image_dir}/result/a" | grep -q -F "noatime" |
309 | grep -F "squashfs" "${image_dir}/result/a" | grep -q -F -v "nosuid" | |
18d73705 | 310 | |
d583cf45 | 311 | cat >/run/systemd/system/testservice-50b.service <<EOF |
18d73705 LB |
312 | [Service] |
313 | Type=oneshot | |
d583cf45 | 314 | ExecStart=bash -c "mount >/run/result/b" |
9ece6444 LB |
315 | BindPaths=${image_dir}/result:/run/result |
316 | TemporaryFileSystem=/run | |
18d73705 | 317 | RootImage=${image}.gpt |
9ece6444 LB |
318 | RootImageOptions=root:ro,noatime,nosuid home:ro,dev nosuid,dev |
319 | RootImageOptions=home:ro,dev nosuid,dev,%%foo | |
d583cf45 ZJS |
320 | # this is the default, but let's specify once to test the parser |
321 | MountAPIVFS=yes | |
18d73705 LB |
322 | EOF |
323 | systemctl start testservice-50b.service | |
38825267 | 324 | grep -F "squashfs" "${image_dir}/result/b" | grep -q -F "noatime" |
18d73705 | 325 | |
d583cf45 | 326 | # Check that specifier escape is applied %%foo → %foo |
18d73705 LB |
327 | busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/testservice_2d50b_2eservice org.freedesktop.systemd1.Service RootImageOptions | grep -F "nosuid,dev,%foo" |
328 | ||
427353f6 | 329 | # Now do some checks with MountImages, both by itself, with options and in combination with RootImage, and as single FS or GPT image |
43ed3d29 LP |
330 | systemd-run -P -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1" |
331 | systemd-run -P -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1" | |
332 | systemd-run -P -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2:nosuid,dev" mount | grep -F "squashfs" | grep -q -F "nosuid" | |
333 | systemd-run -P -p MountImages="${image}.gpt:/run/img1:root:nosuid ${image}.raw:/run/img2:home:suid" mount | grep -F "squashfs" | grep -q -F "nosuid" | |
334 | systemd-run -P -p MountImages="${image}.raw:/run/img2\:3" cat /run/img2:3/usr/lib/os-release | grep -q -F "MARKER=1" | |
335 | systemd-run -P -p MountImages="${image}.raw:/run/img2\:3:nosuid" mount | grep -F "squashfs" | grep -q -F "nosuid" | |
336 | systemd-run -P -p TemporaryFileSystem=/run -p RootImage="${image}.raw" -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /usr/lib/os-release | grep -q -F "MARKER=1" | |
337 | systemd-run -P -p TemporaryFileSystem=/run -p RootImage="${image}.raw" -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1" | |
338 | systemd-run -P -p TemporaryFileSystem=/run -p RootImage="${image}.gpt" -p RootHash="${roothash}" -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1" | |
427353f6 | 339 | cat >/run/systemd/system/testservice-50c.service <<EOF |
b3d13314 | 340 | [Service] |
427353f6 | 341 | MountAPIVFS=yes |
b3d13314 LB |
342 | TemporaryFileSystem=/run |
343 | RootImage=${image}.raw | |
427353f6 LB |
344 | MountImages=${image}.gpt:/run/img1:root:noatime:home:relatime |
345 | MountImages=${image}.raw:/run/img2\:3:nosuid | |
d583cf45 ZJS |
346 | ExecStart=bash -c "cat /run/img1/usr/lib/os-release >/run/result/c" |
347 | ExecStart=bash -c "cat /run/img2:3/usr/lib/os-release >>/run/result/c" | |
348 | ExecStart=bash -c "mount >>/run/result/c" | |
427353f6 | 349 | BindPaths=${image_dir}/result:/run/result |
b3d13314 LB |
350 | Type=oneshot |
351 | EOF | |
427353f6 | 352 | systemctl start testservice-50c.service |
38825267 FS |
353 | grep -q -F "MARKER=1" "${image_dir}/result/c" |
354 | grep -F "squashfs" "${image_dir}/result/c" | grep -q -F "noatime" | |
355 | grep -F "squashfs" "${image_dir}/result/c" | grep -q -F -v "nosuid" | |
b3d13314 | 356 | |
6faecbd3 LB |
357 | # Adding a new mounts at runtime works if the unit is in the active state, |
358 | # so use Type=notify to make sure there's no race condition in the test | |
0ee99483 | 359 | cat >/run/systemd/system/testservice-50d.service <<EOF |
6faecbd3 LB |
360 | [Service] |
361 | RuntimeMaxSec=300 | |
362 | Type=notify | |
363 | RemainAfterExit=yes | |
364 | MountAPIVFS=yes | |
365 | PrivateTmp=yes | |
63403f07 | 366 | ExecStart=sh -c ' \\ |
759b4b4a | 367 | systemd-notify --ready; \\ |
c7986bc9 | 368 | while [ ! -f /tmp/img/usr/lib/os-release ] || ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do \\ |
759b4b4a YW |
369 | sleep 0.1; \\ |
370 | done; \\ | |
371 | mount; \\ | |
372 | mount | grep -F "on /tmp/img type squashfs" | grep -q -F "nosuid"; \\ | |
373 | ' | |
6faecbd3 LB |
374 | EOF |
375 | systemctl start testservice-50d.service | |
376 | ||
7c83d42e LB |
377 | # Mount twice to exercise mount-beneath (on kernel 6.5+, on older kernels it will just overmount) |
378 | mkdir -p /tmp/wrong/foo | |
379 | mksquashfs /tmp/wrong/foo /tmp/wrong.raw | |
380 | systemctl mount-image --mkdir testservice-50d.service /tmp/wrong.raw /tmp/img | |
381 | test "$(systemctl show -P SubState testservice-50d.service)" = "running" | |
38825267 | 382 | systemctl mount-image --mkdir testservice-50d.service "${image}.raw" /tmp/img root:nosuid |
6faecbd3 LB |
383 | |
384 | while systemctl show -P SubState testservice-50d.service | grep -q running | |
385 | do | |
386 | sleep 0.1 | |
387 | done | |
388 | ||
389 | systemctl is-active testservice-50d.service | |
390 | ||
93f59701 | 391 | # ExtensionImages will set up an overlay |
43ed3d29 LP |
392 | systemd-run -P --property ExtensionImages=/usr/share/app0.raw --property RootImage="${image}.raw" cat /opt/script0.sh | grep -q -F "extension-release.app0" |
393 | systemd-run -P --property ExtensionImages=/usr/share/app0.raw --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" | |
394 | systemd-run -P --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /opt/script0.sh | grep -q -F "extension-release.app0" | |
395 | systemd-run -P --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" | |
9a4b883b | 396 | systemd-run -P --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /opt/script1.sh | grep -q -F "extension-release.app2" |
43ed3d29 | 397 | systemd-run -P --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1" |
ab4d43c5 | 398 | systemd-run -P --property ExtensionImages=/usr/share/app-nodistro.raw --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
b856f1df | 399 | systemd-run -P --property ExtensionImages=/etc/service-scoped-test.raw --property RootImage="${image}.raw" cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" |
e374439f KL |
400 | # Check that using a symlink to NAME-VERSION.raw works as long as the symlink has the correct name NAME.raw |
401 | mkdir -p /usr/share/symlink-test/ | |
402 | cp /usr/share/app-nodistro.raw /usr/share/symlink-test/app-nodistro-v1.raw | |
403 | ln -fs /usr/share/symlink-test/app-nodistro-v1.raw /usr/share/symlink-test/app-nodistro.raw | |
404 | systemd-run -P --property ExtensionImages=/usr/share/symlink-test/app-nodistro.raw --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" | |
b856f1df MG |
405 | |
406 | # Symlink check again but for confext | |
407 | mkdir -p /etc/symlink-test/ | |
408 | cp /etc/service-scoped-test.raw /etc/symlink-test/service-scoped-test-v1.raw | |
409 | ln -fs /etc/symlink-test/service-scoped-test-v1.raw /etc/symlink-test/service-scoped-test.raw | |
410 | systemd-run -P --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw --property RootImage="${image}.raw" cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" | |
f0304df6 LB |
411 | # And again mixing sysext and confext |
412 | systemd-run -P \ | |
413 | --property ExtensionImages=/usr/share/symlink-test/app-nodistro.raw \ | |
414 | --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw \ | |
415 | --property RootImage="${image}.raw" cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" | |
416 | systemd-run -P \ | |
417 | --property ExtensionImages=/usr/share/symlink-test/app-nodistro.raw \ | |
418 | --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw \ | |
419 | --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" | |
b856f1df | 420 | |
93f59701 LB |
421 | cat >/run/systemd/system/testservice-50e.service <<EOF |
422 | [Service] | |
423 | MountAPIVFS=yes | |
3fa80e5e LB |
424 | TemporaryFileSystem=/run /var/lib |
425 | StateDirectory=app0 | |
93f59701 LB |
426 | RootImage=${image}.raw |
427 | ExtensionImages=/usr/share/app0.raw /usr/share/app1.raw:nosuid | |
c335b7c3 FS |
428 | # Relevant only for sanitizer runs |
429 | UnsetEnvironment=LD_PRELOAD | |
63403f07 ZJS |
430 | ExecStart=bash -c '/opt/script0.sh | grep ID' |
431 | ExecStart=bash -c '/opt/script1.sh | grep ID' | |
93f59701 LB |
432 | Type=oneshot |
433 | RemainAfterExit=yes | |
434 | EOF | |
435 | systemctl start testservice-50e.service | |
436 | systemctl is-active testservice-50e.service | |
437 | ||
a07b9926 | 438 | # ExtensionDirectories will set up an overlay |
b856f1df | 439 | mkdir -p "${image_dir}/app0" "${image_dir}/app1" "${image_dir}/app-nodistro" "${image_dir}/service-scoped-test" |
128db0aa ZJS |
440 | (! systemd-run -P --property ExtensionDirectories="${image_dir}/nonexistent" --property RootImage="${image}.raw" cat /opt/script0.sh) |
441 | (! systemd-run -P --property ExtensionDirectories="${image_dir}/app0" --property RootImage="${image}.raw" cat /opt/script0.sh) | |
a07b9926 LB |
442 | systemd-dissect --mount /usr/share/app0.raw "${image_dir}/app0" |
443 | systemd-dissect --mount /usr/share/app1.raw "${image_dir}/app1" | |
ab4d43c5 | 444 | systemd-dissect --mount /usr/share/app-nodistro.raw "${image_dir}/app-nodistro" |
b856f1df | 445 | systemd-dissect --mount /etc/service-scoped-test.raw "${image_dir}/service-scoped-test" |
a07b9926 LB |
446 | systemd-run -P --property ExtensionDirectories="${image_dir}/app0" --property RootImage="${image}.raw" cat /opt/script0.sh | grep -q -F "extension-release.app0" |
447 | systemd-run -P --property ExtensionDirectories="${image_dir}/app0" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" | |
448 | systemd-run -P --property ExtensionDirectories="${image_dir}/app0 ${image_dir}/app1" --property RootImage="${image}.raw" cat /opt/script0.sh | grep -q -F "extension-release.app0" | |
449 | systemd-run -P --property ExtensionDirectories="${image_dir}/app0 ${image_dir}/app1" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" | |
450 | systemd-run -P --property ExtensionDirectories="${image_dir}/app0 ${image_dir}/app1" --property RootImage="${image}.raw" cat /opt/script1.sh | grep -q -F "extension-release.app2" | |
451 | systemd-run -P --property ExtensionDirectories="${image_dir}/app0 ${image_dir}/app1" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1" | |
ab4d43c5 | 452 | systemd-run -P --property ExtensionDirectories="${image_dir}/app-nodistro" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" |
b856f1df | 453 | systemd-run -P --property ExtensionDirectories="${image_dir}/service-scoped-test" --property RootImage="${image}.raw" cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" |
a07b9926 LB |
454 | cat >/run/systemd/system/testservice-50f.service <<EOF |
455 | [Service] | |
456 | MountAPIVFS=yes | |
3fa80e5e LB |
457 | TemporaryFileSystem=/run /var/lib |
458 | StateDirectory=app0 | |
a07b9926 LB |
459 | RootImage=${image}.raw |
460 | ExtensionDirectories=${image_dir}/app0 ${image_dir}/app1 | |
461 | # Relevant only for sanitizer runs | |
462 | UnsetEnvironment=LD_PRELOAD | |
63403f07 ZJS |
463 | ExecStart=bash -c '/opt/script0.sh | grep ID' |
464 | ExecStart=bash -c '/opt/script1.sh | grep ID' | |
a07b9926 LB |
465 | Type=oneshot |
466 | RemainAfterExit=yes | |
467 | EOF | |
468 | systemctl start testservice-50f.service | |
469 | systemctl is-active testservice-50f.service | |
ac1f1adf DDM |
470 | systemd-dissect --umount "${image_dir}/app0" |
471 | systemd-dissect --umount "${image_dir}/app1" | |
a07b9926 | 472 | |
1abe15fe KL |
473 | # Test that an extension consisting of an empty directory under /etc/extensions/ takes precedence |
474 | mkdir -p /var/lib/extensions/ | |
475 | ln -s /usr/share/app-nodistro.raw /var/lib/extensions/app-nodistro.raw | |
476 | systemd-sysext merge | |
477 | grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file | |
478 | systemd-sysext unmerge | |
479 | mkdir -p /etc/extensions/app-nodistro | |
480 | systemd-sysext merge | |
481 | test ! -e /usr/lib/systemd/system/some_file | |
482 | systemd-sysext unmerge | |
483 | rmdir /etc/extensions/app-nodistro | |
6afa5d86 | 484 | |
f5151fb4 LP |
485 | # Similar, but go via varlink |
486 | varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.List '{}' | |
487 | (! grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file ) | |
488 | varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Merge '{}' | |
489 | grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file | |
490 | varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Refresh '{}' | |
491 | grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file | |
492 | varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Unmerge '{}' | |
493 | (! grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file ) | |
494 | ||
6afa5d86 LB |
495 | # Check that extensions cannot contain os-release |
496 | mkdir -p /run/extensions/app-reject/usr/lib/{extension-release.d/,systemd/system} | |
497 | echo "ID=_any" >/run/extensions/app-reject/usr/lib/extension-release.d/extension-release.app-reject | |
498 | echo "ID=_any" >/run/extensions/app-reject/usr/lib/os-release | |
499 | touch /run/extensions/app-reject/usr/lib/systemd/system/other_file | |
128db0aa | 500 | (! systemd-sysext merge) |
6afa5d86 LB |
501 | test ! -e /usr/lib/systemd/system/some_file |
502 | test ! -e /usr/lib/systemd/system/other_file | |
503 | systemd-sysext unmerge | |
504 | rm -rf /run/extensions/app-reject | |
1abe15fe KL |
505 | rm /var/lib/extensions/app-nodistro.raw |
506 | ||
0345366a LP |
507 | # Some super basic test that RootImage= works with .v/ dirs |
508 | VBASE="vtest$RANDOM" | |
509 | VDIR="/tmp/${VBASE}.v" | |
510 | mkdir "$VDIR" | |
511 | ||
512 | ln -s "${image}.raw" "$VDIR/${VBASE}_33.raw" | |
513 | ln -s "${image}.raw" "$VDIR/${VBASE}_34.raw" | |
514 | ln -s "${image}.raw" "$VDIR/${VBASE}_35.raw" | |
515 | ||
516 | systemd-run -P -p RootImage="$VDIR" cat /usr/lib/os-release | grep -q -F "MARKER=1" | |
517 | ||
518 | rm "$VDIR/${VBASE}_33.raw" "$VDIR/${VBASE}_34.raw" "$VDIR/${VBASE}_35.raw" | |
519 | rmdir "$VDIR" | |
520 | ||
0305cf6e LP |
521 | mkdir -p /run/machines /run/portables /run/extensions |
522 | touch /run/machines/a.raw /run/portables/b.raw /run/extensions/c.raw | |
523 | ||
7a17e41d | 524 | systemd-dissect --discover --json=short >/tmp/discover.json |
0305cf6e LP |
525 | grep -q -F '{"name":"a","type":"raw","class":"machine","ro":false,"path":"/run/machines/a.raw"' /tmp/discover.json |
526 | grep -q -F '{"name":"b","type":"raw","class":"portable","ro":false,"path":"/run/portables/b.raw"' /tmp/discover.json | |
8a324d16 | 527 | grep -q -F '{"name":"c","type":"raw","class":"sysext","ro":false,"path":"/run/extensions/c.raw"' /tmp/discover.json |
0305cf6e LP |
528 | rm /tmp/discover.json /run/machines/a.raw /run/portables/b.raw /run/extensions/c.raw |
529 | ||
46012433 LP |
530 | # Check that the /sbin/mount.ddi helper works |
531 | T="/tmp/mounthelper.$RANDOM" | |
532 | mount -t ddi "${image}.gpt" "$T" -o ro,X-mount.mkdir,discard | |
533 | umount -R "$T" | |
534 | rmdir "$T" | |
535 | ||
7a05926f YW |
536 | LOOP="$(systemd-dissect --attach --loop-ref=waldo "${image}.raw")" |
537 | ||
538 | # Wait until the symlinks we want to test are established | |
539 | udevadm trigger -w "$LOOP" | |
540 | ||
541 | # Check if the /dev/loop/* symlinks really reference the right device | |
542 | test /dev/disk/by-loop-ref/waldo -ef "$LOOP" | |
543 | ||
544 | if [ "$(stat -c '%Hd:%Ld' "${image}.raw")" != '?d:?d' ] ; then | |
545 | # Old stat didn't know the %Hd and %Ld specifiers and turned them into ?d | |
546 | # instead. Let's simply skip the test on such old systems. | |
547 | test "$(stat -c '/dev/disk/by-loop-inode/%Hd:%Ld-%i' "${image}.raw")" -ef "$LOOP" | |
548 | fi | |
549 | ||
550 | # Detach by loopback device | |
551 | systemd-dissect --detach "$LOOP" | |
552 | ||
553 | # Test long reference name. | |
554 | # Note, sizeof_field(struct loop_info64, lo_file_name) == 64, | |
555 | # and --loop-ref accepts upto 63 characters, and udev creates symlink | |
556 | # based on the name when it has upto _62_ characters. | |
557 | name="$(for _ in {1..62}; do echo -n 'x'; done)" | |
558 | LOOP="$(systemd-dissect --attach --loop-ref="$name" "${image}.raw")" | |
559 | udevadm trigger -w "$LOOP" | |
560 | ||
561 | # Check if the /dev/disk/by-loop-ref/$name symlink really references the right device | |
562 | test "/dev/disk/by-loop-ref/$name" -ef "$LOOP" | |
563 | ||
564 | # Detach by the /dev/disk/by-loop-ref symlink | |
565 | systemd-dissect --detach "/dev/disk/by-loop-ref/$name" | |
566 | ||
567 | name="$(for _ in {1..63}; do echo -n 'x'; done)" | |
568 | LOOP="$(systemd-dissect --attach --loop-ref="$name" "${image}.raw")" | |
569 | udevadm trigger -w "$LOOP" | |
570 | ||
571 | # Check if the /dev/disk/by-loop-ref/$name symlink does not exist | |
572 | test ! -e "/dev/disk/by-loop-ref/$name" | |
573 | ||
574 | # Detach by backing inode | |
575 | systemd-dissect --detach "${image}.raw" | |
576 | (! systemd-dissect --detach "${image}.raw") | |
577 | ||
c3c6a4f0 | 578 | # check for confext functionality |
579 | mkdir -p /run/confexts/test/etc/extension-release.d | |
580 | echo "ID=_any" >/run/confexts/test/etc/extension-release.d/extension-release.test | |
581 | echo "ARCHITECTURE=_any" >>/run/confexts/test/etc/extension-release.d/extension-release.test | |
582 | echo "MARKER_CONFEXT_123" >/run/confexts/test/etc/testfile | |
128db0aa | 583 | cat <<EOF >/run/confexts/test/etc/testscript |
0607a9f9 LB |
584 | #!/bin/bash |
585 | echo "This should not happen" | |
586 | EOF | |
587 | chmod +x /run/confexts/test/etc/testscript | |
c3c6a4f0 | 588 | systemd-confext merge |
589 | grep -q -F "MARKER_CONFEXT_123" /etc/testfile | |
128db0aa | 590 | (! /etc/testscript) |
c3c6a4f0 | 591 | systemd-confext status |
592 | systemd-confext unmerge | |
593 | rm -rf /run/confexts/ | |
594 | ||
cdad1f14 DDM |
595 | unsquashfs -no-xattrs -d /tmp/img "${image}.raw" |
596 | systemd-run --unit=test-root-ephemeral \ | |
597 | -p RootDirectory=/tmp/img \ | |
598 | -p RootEphemeral=yes \ | |
599 | -p Type=exec \ | |
600 | bash -c "touch /abc && sleep infinity" | |
601 | test -n "$(ls -A /var/lib/systemd/ephemeral-trees)" | |
602 | systemctl stop test-root-ephemeral | |
603 | # shellcheck disable=SC2016 | |
1c5d54b2 | 604 | timeout 10 bash -c 'until test -z "$(ls -A /var/lib/systemd/ephemeral-trees)"; do sleep .5; done' |
cdad1f14 DDM |
605 | test ! -f /tmp/img/abc |
606 | ||
2292fa1e DDM |
607 | systemd-dissect --mtree /tmp/img |
608 | systemd-dissect --list /tmp/img | |
609 | ||
610 | read -r SHA256SUM1 _ < <(systemd-dissect --copy-from /tmp/img etc/os-release | sha256sum) | |
611 | test "$SHA256SUM1" != "" | |
612 | ||
613 | echo abc > abc | |
614 | systemd-dissect --copy-to /tmp/img abc /abc | |
615 | test -f /tmp/img/abc | |
616 | ||
f92256ac MG |
617 | # Test for dissect tool support with systemd-sysext |
618 | mkdir -p /run/extensions/ testkit/usr/lib/extension-release.d/ | |
619 | echo "ID=_any" >testkit/usr/lib/extension-release.d/extension-release.testkit | |
620 | echo "ARCHITECTURE=_any" >>testkit/usr/lib/extension-release.d/extension-release.testkit | |
621 | echo "MARKER_SYSEXT_123" >testkit/usr/lib/testfile | |
622 | mksquashfs testkit/ testkit.raw | |
623 | cp testkit.raw /run/extensions/ | |
624 | unsquashfs -l /run/extensions/testkit.raw | |
a81fe93e LP |
625 | systemd-dissect --no-pager /run/extensions/testkit.raw | grep -q '✓ sysext for portable service' |
626 | systemd-dissect --no-pager /run/extensions/testkit.raw | grep -q '✓ sysext for system' | |
f92256ac MG |
627 | systemd-sysext merge |
628 | systemd-sysext status | |
629 | grep -q -F "MARKER_SYSEXT_123" /usr/lib/testfile | |
630 | systemd-sysext unmerge | |
631 | rm -rf /run/extensions/ testkit/ | |
632 | ||
633 | # Test for dissect tool support with systemd-confext | |
634 | mkdir -p /run/confexts/ testjob/etc/extension-release.d/ | |
635 | echo "ID=_any" >testjob/etc/extension-release.d/extension-release.testjob | |
636 | echo "ARCHITECTURE=_any" >>testjob/etc/extension-release.d/extension-release.testjob | |
637 | echo "MARKER_CONFEXT_123" >testjob/etc/testfile | |
638 | mksquashfs testjob/ testjob.raw | |
639 | cp testjob.raw /run/confexts/ | |
640 | unsquashfs -l /run/confexts/testjob.raw | |
a81fe93e LP |
641 | systemd-dissect --no-pager /run/confexts/testjob.raw | grep -q '✓ confext for system' |
642 | systemd-dissect --no-pager /run/confexts/testjob.raw | grep -q '✓ confext for portable service' | |
f92256ac MG |
643 | systemd-confext merge |
644 | systemd-confext status | |
645 | grep -q -F "MARKER_CONFEXT_123" /etc/testfile | |
646 | systemd-confext unmerge | |
647 | rm -rf /run/confexts/ testjob/ | |
648 | ||
3f37a825 LB |
649 | systemd-run -P -p RootImage="${image}.raw" cat /run/host/os-release | cmp "${os_release}" |
650 | ||
41712cd1 MT |
651 | # Test that systemd-sysext reloads the daemon. |
652 | mkdir -p /var/lib/extensions/ | |
653 | ln -s /usr/share/app-reload.raw /var/lib/extensions/app-reload.raw | |
654 | systemd-sysext merge --no-reload | |
655 | # the service should not be running | |
656 | if systemctl --quiet is-active foo.service; then | |
657 | echo "foo.service should not be active" | |
658 | exit 1 | |
659 | fi | |
660 | systemd-sysext unmerge --no-reload | |
661 | systemd-sysext merge | |
662 | for RETRY in $(seq 60) LAST; do | |
663 | if journalctl --boot --unit foo.service | grep -q -P 'echo\[[0-9]+\]: foo'; then | |
664 | break | |
665 | fi | |
666 | if [ "${RETRY}" = LAST ]; then | |
667 | echo "Output of foo.service not found" | |
668 | exit 1 | |
669 | fi | |
670 | sleep 0.5 | |
671 | done | |
672 | systemd-sysext unmerge --no-reload | |
673 | # Grep on the Warning to find the warning helper mentioning the daemon reload. | |
674 | systemctl status foo.service 2>&1 | grep -q -F "Warning" | |
675 | systemd-sysext merge | |
676 | systemd-sysext unmerge | |
677 | systemctl status foo.service 2>&1 | grep -v -q -F "Warning" | |
d203e5e0 | 678 | rm /var/lib/extensions/app-reload.raw |
41712cd1 | 679 | |
99d9edf0 LP |
680 | # Test systemd-repart --make-ddi=: |
681 | if command -v mksquashfs >/dev/null 2>&1; then | |
682 | ||
c4eb8887 | 683 | openssl req -config "$OPENSSL_CONFIG" -subj="/CN=waldo" -x509 -sha256 -nodes -days 365 -newkey rsa:4096 -keyout /tmp/test-50-privkey.key -out /tmp/test-50-cert.crt |
99d9edf0 LP |
684 | |
685 | mkdir -p /tmp/test-50-confext/etc/extension-release.d/ | |
686 | ||
687 | echo "foobar50" > /tmp/test-50-confext/etc/waldo | |
688 | ||
689 | ( grep -e '^\(ID\|VERSION_ID\)=' /etc/os-release ; echo IMAGE_ID=waldo ; echo IMAGE_VERSION=7 ) > /tmp/test-50-confext/etc/extension-release.d/extension-release.waldo | |
690 | ||
691 | mkdir -p /run/confexts | |
692 | ||
693 | SYSTEMD_REPART_OVERRIDE_FSTYPE=squashfs systemd-repart -C -s /tmp/test-50-confext --certificate=/tmp/test-50-cert.crt --private-key=/tmp/test-50-privkey.key /run/confexts/waldo.confext.raw | |
694 | rm -rf /tmp/test-50-confext | |
695 | ||
696 | mkdir -p /run/verity.d | |
697 | cp /tmp/test-50-cert.crt /run/verity.d/ | |
698 | systemd-dissect --mtree /run/confexts/waldo.confext.raw | |
699 | ||
700 | systemd-confext refresh | |
701 | ||
702 | read -r X < /etc/waldo | |
703 | test "$X" = foobar50 | |
704 | ||
1500fe38 | 705 | rm /run/confexts/waldo.confext.raw |
99d9edf0 LP |
706 | |
707 | systemd-confext refresh | |
708 | ||
1500fe38 DDM |
709 | (! test -f /etc/waldo ) |
710 | ||
711 | mkdir -p /tmp/test-50-sysext/usr/lib/extension-release.d/ | |
712 | ||
713 | # Make sure the sysext is big enough to not fit in the minimum partition size of repart so we know the | |
714 | # Minimize= logic is working. | |
715 | truncate --size=50M /tmp/test-50-sysext/usr/waldo | |
716 | ||
717 | ( grep -e '^\(ID\|VERSION_ID\)=' /etc/os-release ; echo IMAGE_ID=waldo ; echo IMAGE_VERSION=7 ) > /tmp/test-50-sysext/usr/lib/extension-release.d/extension-release.waldo | |
718 | ||
719 | mkdir -p /run/extensions | |
720 | ||
721 | SYSTEMD_REPART_OVERRIDE_FSTYPE=squashfs systemd-repart -S -s /tmp/test-50-sysext --certificate=/tmp/test-50-cert.crt --private-key=/tmp/test-50-privkey.key /run/extensions/waldo.sysext.raw | |
722 | ||
723 | systemd-dissect --mtree /run/extensions/waldo.sysext.raw | |
724 | ||
725 | systemd-sysext refresh | |
726 | ||
727 | test -f /usr/waldo | |
728 | ||
729 | rm /run/verity.d/test-50-cert.crt /run/extensions/waldo.sysext.raw /tmp/test-50-cert.crt /tmp/test-50-privkey.key | |
730 | ||
731 | systemd-sysext refresh | |
732 | ||
733 | (! test -f /usr/waldo) | |
99d9edf0 LP |
734 | fi |
735 | ||
4701425d FS |
736 | # Sneak in a couple of expected-to-fail invocations to cover |
737 | # https://github.com/systemd/systemd/issues/29610 | |
738 | (! systemd-run -P -p MountImages="/this/should/definitely/not/exist.img:/run/img2\:3:nosuid" false) | |
739 | (! systemd-run -P -p ExtensionImages="/this/should/definitely/not/exist.img" false) | |
740 | (! systemd-run -P -p RootImage="/this/should/definitely/not/exist.img" false) | |
741 | (! systemd-run -P -p ExtensionDirectories="/foo/bar /foo/baz" false) | |
742 | ||
07268394 | 743 | touch /testok |