diff options
Diffstat (limited to 'src/parted-usb.sh')
-rwxr-xr-x | src/parted-usb.sh | 389 |
1 files changed, 0 insertions, 389 deletions
diff --git a/src/parted-usb.sh b/src/parted-usb.sh deleted file mode 100755 index bd8eeae..0000000 --- a/src/parted-usb.sh +++ /dev/null | |||
@@ -1,389 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | USE_EFI= | ||
3 | die() | ||
4 | { | ||
5 | printf 'Error: %s\n' "$*" >&2 | ||
6 | exit 1 | ||
7 | } | ||
8 | KiB() | ||
9 | { | ||
10 | printf %s $(("$1" * 1024)) | ||
11 | } | ||
12 | MiB() | ||
13 | { | ||
14 | KiB $(KiB "$1") | ||
15 | } | ||
16 | |||
17 | get_size() | ||
18 | { | ||
19 | [ "$1" ] || return | ||
20 | if [ -b "$1" ] | ||
21 | then | ||
22 | blockdev --getsize64 "$1" | ||
23 | else | ||
24 | stat -c'%s' "$1" | ||
25 | fi | ||
26 | } | ||
27 | |||
28 | get_rootfs_size() | ||
29 | { | ||
30 | rootfs_size=$(get_size "$ROOTFS") | ||
31 | } | ||
32 | |||
33 | initialize_target() | ||
34 | { | ||
35 | if [ -b "$target" ] | ||
36 | then return | ||
37 | fi | ||
38 | |||
39 | rm -f "$target" | ||
40 | if [ "$ROOTFS" ] | ||
41 | then | ||
42 | get_rootfs_size | ||
43 | fallocate -l $(($(KiB 17) + $(MiB $end_keys) + rootfs_size + $(KiB 640))) "$target" | ||
44 | else | ||
45 | fallocate -l $(($(KiB 17) + $(MiB $end_keys))) "$target" | ||
46 | fi | ||
47 | } | ||
48 | |||
49 | # TODO: Use GUID type tags for each Samizdat partition type. | ||
50 | partition_target() | ||
51 | { | ||
52 | parted "$target" -sm -a optimal \ | ||
53 | unit MiB \ | ||
54 | mklabel gpt \ | ||
55 | mkpart samizdat-efi 1 8 \ | ||
56 | set 1 esp on \ | ||
57 | mkpart samizdat-grub 8 64 \ | ||
58 | set 2 bios_grub on \ | ||
59 | mkpart samizdat-keys btrfs ${start_keys} ${end_keys} | ||
60 | if [ -b "$target" ] | ||
61 | then | ||
62 | partx -u "$target" | ||
63 | fi | ||
64 | |||
65 | if [ "$ROOTFS" ] | ||
66 | then | ||
67 | parted "$target" -sm -a optimal \ | ||
68 | mkpart samizdat-rootfs btrfs ${end_keys}MiB 100% | ||
69 | fi | ||
70 | } | ||
71 | |||
72 | sex() | ||
73 | { | ||
74 | ( | ||
75 | set -x | ||
76 | "$@" | ||
77 | ) | ||
78 | } | ||
79 | |||
80 | make_target_bootable() | ||
81 | { | ||
82 | mkfs.btrfs -f --mixed "$part"3 | ||
83 | mkdir -p "$mnt" | ||
84 | mount "$part"3 "$mnt" | ||
85 | |||
86 | mkdir -p "$mnt"/boot/grub | ||
87 | cp -avL "$GRUB_CONFIG" "$mnt"/boot/grub | ||
88 | |||
89 | mkdir -p "$mnt"/boot/efi | ||
90 | mkfs.vfat "$part"1 | ||
91 | if [ "$USE_EFI" ] | ||
92 | then | ||
93 | efi_dir="$mnt".efi | ||
94 | mkdir -p "$efi_dir" | ||
95 | mount "$part"1 "$mnt".efi | ||
96 | mkdir "$efi_dir"/boot | ||
97 | boot_dir=$efi_dir/boot | ||
98 | else | ||
99 | boot_dir=$mnt/boot | ||
100 | fi | ||
101 | |||
102 | # https://wiki.archlinux.org/index.php/Multiboot_USB_drive#Hybrid_UEFI_GPT_+_BIOS_GPT/MBR_boot | ||
103 | # grub-install --target=x86_64-efi --removable --boot-directory=/mnt/boot --efi-directory=/mnt | ||
104 | |||
105 | GRUB_LOGFILE=$(mktemp) || exit | ||
106 | set -- eatmydata -- \ | ||
107 | grub-install ${VERBOSE:+ -v} \ | ||
108 | ${USE_EFI:+ --target=i386-efi} \ | ||
109 | ${USE_EFI:+ --recheck} \ | ||
110 | ${USE_EFI:+ --removable} \ | ||
111 | ${USE_EFI:+ --efi-directory "$efi_dir"} \ | ||
112 | --boot-directory "$boot_dir" \ | ||
113 | "$dev" | ||
114 | echo "running: $* >$GRUB_LOGFILE 2>&1" >&2 | ||
115 | if "$@" >"$GRUB_LOGFILE" 2>&1 | ||
116 | then | ||
117 | fail= | ||
118 | else | ||
119 | fail=y | ||
120 | fi | ||
121 | if [ "$USE_EFI" ] | ||
122 | then | ||
123 | umount -l "$mnt"/boot/efi || : | ||
124 | fi | ||
125 | umount -l "$mnt" || : | ||
126 | if [ "$fail" ] | ||
127 | then | ||
128 | set -x | ||
129 | tail -n5 "$GRUB_LOGFILE" | ||
130 | exit 1 | ||
131 | else | ||
132 | rm "$GRUB_LOGFILE" | ||
133 | fi | ||
134 | sync | ||
135 | } | ||
136 | |||
137 | copy_rootfs() | ||
138 | { | ||
139 | if [ -z "$ROOTFS" ] | ||
140 | then | ||
141 | return | ||
142 | fi | ||
143 | [ -e "$ROOTFS" -a -b "$part"4 ] | ||
144 | get_rootfs_size | ||
145 | part_size=$(blockdev --getsize64 "$part"4) | ||
146 | [ "$rootfs_size" -le "$part_size" ] || die "rootfs_size=$rootfs_size > part_size=$part_size" | ||
147 | |||
148 | ( | ||
149 | set -x | ||
150 | dd if="$ROOTFS" of="$part"4 | ||
151 | # dd if=rootfs/samizdat.patch.seed.btrfs of="$part"5 | ||
152 | ) | ||
153 | } | ||
154 | |||
155 | acquire_target_block_devices() | ||
156 | { | ||
157 | if [ -b "$target" ] | ||
158 | then | ||
159 | dev=$target | ||
160 | part=$target | ||
161 | mnt=/mnt/${target#/dev/} | ||
162 | partx -u "$target" | ||
163 | else | ||
164 | trap release_target_block_devices EXIT | ||
165 | losetup -f "$target" | ||
166 | dev=$(losetup -j "$target" -O NAME --noheadings) | ||
167 | |||
168 | btrfs device scan -u || : | ||
169 | kpartx -vasas "$dev" | ||
170 | btrfs device scan | ||
171 | part=/dev/mapper/${dev##*/}p | ||
172 | |||
173 | mnt=$target.mnt | ||
174 | fi | ||
175 | } | ||
176 | |||
177 | release_target_block_devices() | ||
178 | { | ||
179 | ( | ||
180 | set +e | ||
181 | [ -z "$mnt" ] || ! mountpoint -q "$mnt" || umount "$mnt" | ||
182 | case "$dev" in | ||
183 | /dev/loop*) | ||
184 | kpartx -d "$dev" | ||
185 | losetup -d "$dev" | ||
186 | ;; | ||
187 | esac | ||
188 | true | ||
189 | ) | ||
190 | unset mnt dev | ||
191 | } | ||
192 | |||
193 | add_keys() | ||
194 | { | ||
195 | rsync -a --info=STATS "$GPG_INPUT_DIR"/ "$mnt"/gnupghome/ | ||
196 | } | ||
197 | |||
198 | add_initrd() | ||
199 | { | ||
200 | initrd_suffix=.samizdat | ||
201 | mkdir -p "$mnt"/linux | ||
202 | rsync -aL --info=STATS "${1}vmlinuz${2}" "$mnt"/linux/vmlinuz | ||
203 | rsync -aL --info=STATS "${1}initrd.img${2}${2:+$initrd_suffix}" "$mnt"/linux/initrd.img | ||
204 | } | ||
205 | |||
206 | add_grub_cfg() | ||
207 | { | ||
208 | mkdir -p "$mnt"/boot/grub | ||
209 | cp -aL "$GRUB_CONFIG" "$mnt"/boot/grub | ||
210 | } | ||
211 | |||
212 | individualize() | ||
213 | { | ||
214 | mkdir -p "$mnt" | ||
215 | ( | ||
216 | set +e | ||
217 | losetup -a >&2 | ||
218 | lsblk >&2 | ||
219 | mount|grep $PWD >&2 | ||
220 | : OK | ||
221 | ) | ||
222 | mountpoint "$mnt" || mount "$part"3 "$mnt" | ||
223 | add_keys | ||
224 | add_initrd "$samizdat_linux_dir"/ "${version_suffix}" | ||
225 | add_grub_cfg | ||
226 | } | ||
227 | |||
228 | globalize() | ||
229 | { | ||
230 | initialize_target | ||
231 | partition_target | ||
232 | acquire_target_block_devices | ||
233 | make_target_bootable | ||
234 | copy_rootfs | ||
235 | } | ||
236 | |||
237 | sanity_checks() | ||
238 | { | ||
239 | [[ $UID = 0 ]] || die "You are not root." | ||
240 | for d in "$samizdat_linux_dir" "$GPG_INPUT_DIR" | ||
241 | do | ||
242 | [ -d "$d" ] || die "Not a directory: $d" | ||
243 | done | ||
244 | } | ||
245 | |||
246 | find_mac() | ||
247 | { | ||
248 | start_mac=$1 | ||
249 | for mac in $(ip link show | grep link/ether | (read _ mac _; echo $mac | tr : -)); do | ||
250 | if [ "${mac%??}" = "${start_mac%??}" ]; then | ||
251 | prefix=${mac%??} | ||
252 | suffix=$(printf %x $(( 0x${mac##*-} + 1 ))) | ||
253 | MAC=${prefix}${suffix} | ||
254 | return | ||
255 | fi | ||
256 | done | ||
257 | MAC=$start_mac | ||
258 | } | ||
259 | |||
260 | boot_vm() | ||
261 | { | ||
262 | boot_drive=$1 | ||
263 | installer_target=samizdat.disk.img | ||
264 | |||
265 | if [ ! -e "$installer_target" ] | ||
266 | then | ||
267 | fallocate -l 10G "$installer_target" | ||
268 | fi | ||
269 | |||
270 | find_mac 52-54-00-12-34-56 | ||
271 | qemu-system-x86_64 \ | ||
272 | -enable-kvm \ | ||
273 | ${USE_EFI:+ -bios /usr/share/OVMF/OVMF_CODE.fd} \ | ||
274 | -smp 2 \ | ||
275 | -m 512 \ | ||
276 | -k en-us \ | ||
277 | -net nic,model=virtio,macaddr="$MAC" \ | ||
278 | -net tap,ifname=tap0,script=no,downscript=no \ | ||
279 | -curses \ | ||
280 | -drive file="$boot_drive",format=raw \ | ||
281 | -drive file="$installer_target",format=raw | ||
282 | } | ||
283 | |||
284 | do_build() | ||
285 | { | ||
286 | if [ -b "$target" ] | ||
287 | then | ||
288 | globalize | ||
289 | individualize | ||
290 | release_target_block_devices | ||
291 | elif [ -f "$target" -o ! -e "$target" ] | ||
292 | then | ||
293 | template=${target%.img}.template.img | ||
294 | final=$target | ||
295 | ( | ||
296 | target=$target.tmp | ||
297 | if [ ! -e "$template" ] | ||
298 | then | ||
299 | target="$template".tmp globalize | ||
300 | release_target_block_devices | ||
301 | mv -T "$template".tmp "$template" | ||
302 | fi | ||
303 | |||
304 | cp -T --reflink=always "$template" "$target" | ||
305 | acquire_target_block_devices | ||
306 | individualize | ||
307 | release_target_block_devices | ||
308 | |||
309 | mv -T "$target" "$final" | ||
310 | ) | ||
311 | else | ||
312 | die "Target must be a file or block device." | ||
313 | fi | ||
314 | } | ||
315 | |||
316 | . samizdat-paths.sh || die 'samizdat-paths.sh not found' | ||
317 | samizdat_linux_dir=/ | ||
318 | |||
319 | DEFAULT_ROOTFS=rootfs/samizdat.seed.btrfs | ||
320 | #DEFAULT_PATCHFS=rootfs/samizdat.patch.btrfs | ||
321 | |||
322 | if [ "$ROOTFS" = none ] | ||
323 | then | ||
324 | ROOTFS= | ||
325 | elif [ "$ROOTFS" ] | ||
326 | then | ||
327 | [ -f "$ROOTFS" ] || die "Not a file: $ROOTFS" | ||
328 | elif [ -f "$DEFAULT_ROOTFS" ] | ||
329 | then | ||
330 | ROOTFS=$DEFAULT_ROOTFS | ||
331 | fi | ||
332 | |||
333 | if [ ! "$GPG_INPUT_DIR" ] | ||
334 | then | ||
335 | for d in $GPG_INPUT_DIR /root/.gnupg /cdrom/gnupghome | ||
336 | do | ||
337 | [ -d "$d" ] || continue | ||
338 | GPG_INPUT_DIR=$d | ||
339 | break | ||
340 | done | ||
341 | fi | ||
342 | |||
343 | : ${GRUB_CONFIG:=conf/grub.cfg} | ||
344 | start_keys=64 # megs | ||
345 | end_keys=256 # megs | ||
346 | |||
347 | if [ "$KERNEL_VERSION" ] | ||
348 | then | ||
349 | version_suffix=-$KERNEL_VERSION | ||
350 | fi | ||
351 | |||
352 | sanity_checks | ||
353 | set -e | ||
354 | |||
355 | if [ "$1" = -n ] | ||
356 | then | ||
357 | shift | ||
358 | DO_BUILD= | ||
359 | else | ||
360 | DO_BUILD=y | ||
361 | fi | ||
362 | |||
363 | default_target=boot-disk.img | ||
364 | |||
365 | USB=$(which usb || echo ./src/usb) | ||
366 | |||
367 | if [ "$1" ] | ||
368 | then | ||
369 | if [ "$1" = USB ] | ||
370 | then | ||
371 | [ "$DO_BUILD" ] && arg= || arg=-n | ||
372 | target=$($USB $arg) || exit 1 | ||
373 | elif [ -f "$1" ] | ||
374 | then | ||
375 | case "$1" in | ||
376 | *.img) ;; | ||
377 | *) die "Invalid image filename. Use *.img";; | ||
378 | esac | ||
379 | target=$1 | ||
380 | fi | ||
381 | else | ||
382 | target=$default_target | ||
383 | fi | ||
384 | |||
385 | if [ "$DO_BUILD" ] | ||
386 | then | ||
387 | do_build | ||
388 | fi | ||
389 | boot_vm "$target" | ||