1#!/usr/bin/env bash
2# SPDX-License-Identifier: LGPL-2.1-or-later
3set -eux
4set -o pipefail
5
6[[ -e /dev/loop-control ]] || exit 77
7
8repart="${1:?}"
9udevadm="${2:?}"
10test -x "$repart"
11test -x "$udevadm"
12
13PATH=$PATH:/sbin:/usr/sbin
14
15D="$(mktemp --tmpdir --directory "test-repart.XXXXXXXXXX")"
16
17# shellcheck disable=SC2064
18trap "rm -rf '$D'" EXIT INT QUIT PIPE
19mkdir -p "$D/definitions"
20
21SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8
22
23echo "### Testing systemd-repart --empty=create ###"
24
25"$repart" "$D/zzz" --empty=create --size=1G --seed="$SEED" --no-pager
26
27sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/empty"
28
29cmp "$D/empty" - <<EOF
30label: gpt
31label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
32device: $D/zzz
33unit: sectors
34first-lba: 2048
35last-lba: 2097118
36EOF
37
38echo "### Testing with root, root2, home, & swap ###"
39
40cat >"$D/definitions/root.conf" <<EOF
41[Partition]
42Type=root-x86-64
43EOF
44
45ln -s root.conf "$D/definitions/root2.conf"
46
47cat >"$D/definitions/home.conf" <<EOF
48[Partition]
49Type=home
50Label=home-first
51Label=home-always-too-long-xxxxxxxxxxxxxx-%v
52EOF
53
54cat >"$D/definitions/swap.conf" <<EOF
55[Partition]
56Type=swap
57SizeMaxBytes=64M
58PaddingMinBytes=92M
59EOF
60
61"$repart" "$D/zzz" --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager
62
63sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated"
64
65cmp "$D/populated" - <<EOF
66label: gpt
67label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
68device: $D/zzz
69unit: sectors
70first-lba: 2048
71last-lba: 2097118
72$D/zzz1 : start=        2048, size=      591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59"
73$D/zzz2 : start=      593904, size=      591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59"
74$D/zzz3 : start=     1185760, size=      591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59"
75$D/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap"
76EOF
77
78echo "### Testing with root, root2, home, swap, & another partition ###"
79
80cat >"$D/definitions/swap.conf" <<EOF
81[Partition]
82Type=swap
83SizeMaxBytes=64M
84EOF
85
86cat >"$D/definitions/extra.conf" <<EOF
87[Partition]
88Type=linux-generic
89Label=custom_label
90UUID=a0a1a2a3a4a5a6a7a8a9aaabacadaeaf
91EOF
92
93echo "Label=ignored_label" >>"$D/definitions/home.conf"
94echo "UUID=b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" >>"$D/definitions/home.conf"
95
96"$repart" "$D/zzz" --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager
97
98sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated2"
99
100cmp "$D/populated2" - <<EOF
101label: gpt
102label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
103device: $D/zzz
104unit: sectors
105first-lba: 2048
106last-lba: 2097118
107$D/zzz1 : start=        2048, size=      591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59"
108$D/zzz2 : start=      593904, size=      591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59"
109$D/zzz3 : start=     1185760, size=      591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59"
110$D/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap"
111$D/zzz5 : start=     1908696, size=      188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label"
112EOF
113
114echo "### Resizing to 2G ###"
115
116"$repart" "$D/zzz" --size=2G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager
117
118sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated3"
119
120cmp "$D/populated3" - <<EOF
121label: gpt
122label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
123device: $D/zzz
124unit: sectors
125first-lba: 2048
126last-lba: 4194270
127$D/zzz1 : start=        2048, size=      591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59"
128$D/zzz2 : start=      593904, size=      591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59"
129$D/zzz3 : start=     1185760, size=      591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59"
130$D/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap"
131$D/zzz5 : start=     1908696, size=     2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label"
132EOF
133
134dd if=/dev/urandom of="$D/block-copy" bs=4096 count=10240
135
136echo "### Testing with root, root2, home, swap, another partition, & partition copy ###"
137
138cat >"$D/definitions/extra2.conf" <<EOF
139[Partition]
140Type=linux-generic
141Label=block-copy
142UUID=2a1d97e1d0a346cca26eadc643926617
143CopyBlocks=$D/block-copy
144EOF
145
146"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager
147
148sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated4"
149
150cmp "$D/populated4" - <<EOF
151label: gpt
152label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
153device: $D/zzz
154unit: sectors
155first-lba: 2048
156last-lba: 6291422
157$D/zzz1 : start=        2048, size=      591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59"
158$D/zzz2 : start=      593904, size=      591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59"
159$D/zzz3 : start=     1185760, size=      591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59"
160$D/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap"
161$D/zzz5 : start=     1908696, size=     2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label"
162$D/zzz6 : start=     4194264, size=     2097152, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=2A1D97E1-D0A3-46CC-A26E-ADC643926617, name="block-copy"
163EOF
164
165cmp --bytes=41943040 --ignore-initial=0:$((512*4194264)) "$D/block-copy" "$D/zzz"
166
167if [ "$(id -u)" -eq 0 ] && type -P cryptsetup diff losetup >/dev/null ; then
168    echo "### Testing Format=/Encrypt=/CopyFiles="
169
170    # These tests require privileges unfortunately
171
172    cat >"$D/definitions/extra3.conf" <<EOF
173[Partition]
174Type=linux-generic
175Label=luks-format-copy
176UUID=7b93d1f2-595d-4ce3-b0b9-837fbd9e63b0
177Format=ext4
178Encrypt=yes
179CopyFiles=$D/definitions:/def
180SizeMinBytes=48M
181EOF
182
183    "$repart" "$D/zzz" --size=auto --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager
184
185    sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated5"
186
187    cmp "$D/populated5" - <<EOF
188label: gpt
189label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
190device: $D/zzz
191unit: sectors
192first-lba: 2048
193last-lba: 6389726
194$D/zzz1 : start=        2048, size=      591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59"
195$D/zzz2 : start=      593904, size=      591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59"
196$D/zzz3 : start=     1185760, size=      591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59"
197$D/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap"
198$D/zzz5 : start=     1908696, size=     2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label"
199$D/zzz6 : start=     4194264, size=     2097152, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=2A1D97E1-D0A3-46CC-A26E-ADC643926617, name="block-copy"
200$D/zzz7 : start=     6291416, size=       98304, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=7B93D1F2-595D-4CE3-B0B9-837FBD9E63B0, name="luks-format-copy"
201EOF
202
203    LOOP="$(losetup -P --show --find "$D/zzz")"
204    "${udevadm:?}" wait --timeout 60 --settle "${LOOP:?}"
205
206    VOLUME="test-repart-$RANDOM"
207
208    touch "$D/empty-password"
209    cryptsetup open --type=luks2 --key-file="$D/empty-password" "${LOOP}p7" "$VOLUME"
210    mkdir "$D/mount"
211    mount -t ext4 "/dev/mapper/$VOLUME" "$D/mount"
212    # Use deferred closing on the mapper and autoclear on the loop, so they are cleaned up on umount
213    cryptsetup close --deferred "$VOLUME"
214    losetup -d "$LOOP"
215    diff -r "$D/mount/def" "$D/definitions" >/dev/null
216    umount "$D/mount"
217else
218    echo "### Skipping Format=/Encrypt=/CopyFiles= test, lacking privileges or missing cryptsetup/diff/losetup"
219fi
220
221echo "### Testing json output ###"
222"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager --json=help
223"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager --json=pretty
224"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager --json=short
225