summaryrefslogtreecommitdiff
path: root/src/parted-usb.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/parted-usb.sh')
-rwxr-xr-xsrc/parted-usb.sh389
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
2USE_EFI=
3die()
4{
5 printf 'Error: %s\n' "$*" >&2
6 exit 1
7}
8KiB()
9{
10 printf %s $(("$1" * 1024))
11}
12MiB()
13{
14 KiB $(KiB "$1")
15}
16
17get_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
28get_rootfs_size()
29{
30 rootfs_size=$(get_size "$ROOTFS")
31}
32
33initialize_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.
50partition_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
72sex()
73{
74 (
75 set -x
76 "$@"
77 )
78}
79
80make_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
137copy_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
155acquire_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
177release_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
193add_keys()
194{
195 rsync -a --info=STATS "$GPG_INPUT_DIR"/ "$mnt"/gnupghome/
196}
197
198add_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
206add_grub_cfg()
207{
208 mkdir -p "$mnt"/boot/grub
209 cp -aL "$GRUB_CONFIG" "$mnt"/boot/grub
210}
211
212individualize()
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
228globalize()
229{
230 initialize_target
231 partition_target
232 acquire_target_block_devices
233 make_target_bootable
234 copy_rootfs
235}
236
237sanity_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
246find_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
260boot_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
284do_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'
317samizdat_linux_dir=/
318
319DEFAULT_ROOTFS=rootfs/samizdat.seed.btrfs
320#DEFAULT_PATCHFS=rootfs/samizdat.patch.btrfs
321
322if [ "$ROOTFS" = none ]
323then
324 ROOTFS=
325elif [ "$ROOTFS" ]
326then
327 [ -f "$ROOTFS" ] || die "Not a file: $ROOTFS"
328elif [ -f "$DEFAULT_ROOTFS" ]
329then
330 ROOTFS=$DEFAULT_ROOTFS
331fi
332
333if [ ! "$GPG_INPUT_DIR" ]
334then
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
341fi
342
343: ${GRUB_CONFIG:=conf/grub.cfg}
344start_keys=64 # megs
345end_keys=256 # megs
346
347if [ "$KERNEL_VERSION" ]
348then
349 version_suffix=-$KERNEL_VERSION
350fi
351
352sanity_checks
353set -e
354
355if [ "$1" = -n ]
356then
357 shift
358 DO_BUILD=
359else
360 DO_BUILD=y
361fi
362
363default_target=boot-disk.img
364
365USB=$(which usb || echo ./src/usb)
366
367if [ "$1" ]
368then
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
381else
382 target=$default_target
383fi
384
385if [ "$DO_BUILD" ]
386then
387 do_build
388fi
389boot_vm "$target"