175 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
#!/usr/bin/env bash
 | 
						|
# Copyright (C) 2023  Umorpha Systems
 | 
						|
# SPDX-License-Identifier: AGPL-3.0-or-later
 | 
						|
 | 
						|
# Dependencies:
 | 
						|
#  - /usr/bin/env       (coreutils, busybox)
 | 
						|
#  - cat                (coreutils, busybox)
 | 
						|
#  - dd                 (coreutils, busybox)
 | 
						|
#  - install            (coreutils, busybox)
 | 
						|
#  - mkdir              (coreutils, busybox)
 | 
						|
#  - mktemp             (coreutils, busybox)
 | 
						|
#  - rm                 (coreutils, busybox)
 | 
						|
#  - rmdir              (coreutils, busybox)
 | 
						|
#  - losetup (optional) (util-linux; the busybox one doesn't work)
 | 
						|
#  - umount             (util-linux, busybox)
 | 
						|
#  - blkid              (util-linux)
 | 
						|
#  - mount              (util-linux)
 | 
						|
#  - bash               (bash)
 | 
						|
#  - systemd-repart     (systemd)
 | 
						|
#  - lvcreate           (lvm2)
 | 
						|
#  - pvcreate           (lvm2)
 | 
						|
#  - vgchange           (lvm2)
 | 
						|
#  - vgcreate           (lvm2)
 | 
						|
#  - pv                 (pv)
 | 
						|
#  - mkfs.ext4          (e2fsprogs)
 | 
						|
#  - mkfs.vfat          (dosfstools)
 | 
						|
#  - arch-chroot        (arch-install-scripts)
 | 
						|
#
 | 
						|
# Dependencies of arch-chroot (as of v28):
 | 
						|
#  - cat        (coreutils, busybox)
 | 
						|
#  - install    (coreutils, busybox)
 | 
						|
#  - ln         (coreutils, busybox)
 | 
						|
#  - touch      (coreutils, busybox)
 | 
						|
#  - chroot     (coreutils; the busybox one doesn't work)
 | 
						|
#  - readlink   (coreutils; the busybox one doesn't work)
 | 
						|
#  - mountpoint (util-linux, busybox)
 | 
						|
#  - umount     (util-linux, busybox)
 | 
						|
#  - unshare    (util-linux, busybox)
 | 
						|
#  - mount      (util-linux)
 | 
						|
#  - grep       (grep, busybox)
 | 
						|
#  - bash       (bash)
 | 
						|
#
 | 
						|
# Of those, these are the ones that aren't already in an initcpio:
 | 
						|
#  - arch-chroot    (arch-install-scripts)
 | 
						|
#  - bash           (bash)
 | 
						|
#  - chroot         (coreutils)
 | 
						|
#  - readlink       (coreutils)
 | 
						|
#  - pv             (pv)
 | 
						|
#  - systemd-repart (systemd)
 | 
						|
#  - mkfs.ext4      (e2fsprogs)
 | 
						|
#  - mkfs.vfat      (dosfstools)
 | 
						|
#  - pvcreate       (lvm2)
 | 
						|
#  - vgchange       (lvm2)
 | 
						|
#  - vgcreate       (lvm2)
 | 
						|
#  - lvcreate       (lvm2)
 | 
						|
 | 
						|
set -euE -o pipefail
 | 
						|
 | 
						|
main() {
 | 
						|
	local device rootfs
 | 
						|
	rootfs=$1
 | 
						|
	device=$2
 | 
						|
 | 
						|
	echo ":: Installing '${rootfs}' to '${device}'"
 | 
						|
 | 
						|
	cleanup=()
 | 
						|
	#trap 'for (( i=${#cleanup[@]}-1; i >= 0; i-- )); do eval "${cleanup[$i]}"; done' EXIT
 | 
						|
 | 
						|
	local tmpdir
 | 
						|
	tmpdir="$(mktemp -dt "${0##*/}.XXXXXXXXXX")"
 | 
						|
	cleanup+="rmdir -- ${tmpdir@Q}"
 | 
						|
 | 
						|
	########################################################################
 | 
						|
 | 
						|
	local is_loop=false
 | 
						|
	if [[ -f "$device" ]]; then
 | 
						|
		echo "   file '${device}' is not a block device, setting up a loopback device..."
 | 
						|
		device=$(losetup --find --show --partscan -- "$device")
 | 
						|
		echo "   ... '${device}'"
 | 
						|
		cleanup+=("losetup --detach ${device@Q}")
 | 
						|
		is_loop=true
 | 
						|
	fi
 | 
						|
	local devicep="$device"
 | 
						|
	if [[ "$devicep" == *[0-9] ]]; then
 | 
						|
		devicep+='p'
 | 
						|
	fi
 | 
						|
 | 
						|
	########################################################################
 | 
						|
 | 
						|
	echo ":: Setting up GPT"
 | 
						|
 | 
						|
	#dd if=/dev/zero of="$device" bs=512 count=4
 | 
						|
 | 
						|
	cat >"$tmpdir/00-esp.conf" <<-EOF
 | 
						|
		[Partition]
 | 
						|
		Type=esp
 | 
						|
		Format=vfat
 | 
						|
		Label=Umorpha EFI System Partition
 | 
						|
		SizeMinBytes=512M
 | 
						|
		SizeMaxBytes=512M
 | 
						|
	EOF
 | 
						|
	cat >"$tmpdir/10-lvm.conf" <<-EOF
 | 
						|
		[Partition]
 | 
						|
		# https://en.wikipedia.org/w/index.php?title=User_talk:Claunia&diff=prev&oldid=1182832243
 | 
						|
		Type=E6D6D379-F507-44C2-A23C-238F2A3DF928
 | 
						|
		Label=Umorpha LVM Partition
 | 
						|
	EOF
 | 
						|
 | 
						|
	systemd-repart \
 | 
						|
		--empty=allow --dry-run=no \
 | 
						|
		--no-pager \
 | 
						|
		--definitions="$tmpdir" \
 | 
						|
		"$device"
 | 
						|
 | 
						|
	rm -- "$tmpdir"/*.conf
 | 
						|
 | 
						|
	########################################################################
 | 
						|
 | 
						|
	echo ":: Setting up LVM"
 | 
						|
 | 
						|
	pvcreate "${devicep}2"
 | 
						|
	vgcreate vg_umorpha "${devicep}2"
 | 
						|
	if $is_loop; then
 | 
						|
		cleanup+=("vgchange --activate=n vg_umorpha")
 | 
						|
	fi
 | 
						|
 | 
						|
	# Use short `-c` instead of `--format` so this works with busybox.
 | 
						|
	lvcreate --name=lv_root_a --size="$(stat -c '%s' -- "$rootfs")b" vg_umorpha
 | 
						|
	pv -- "$rootfs" >/dev/mapper/vg_umorpha-lv_root_a
 | 
						|
 | 
						|
	lvcreate --name=lv_root_overlay --size=1G vg_umorpha
 | 
						|
	mkfs.ext4 /dev/mapper/vg_umorpha-lv_root_overlay
 | 
						|
 | 
						|
	########################################################################
 | 
						|
 | 
						|
	echo ":: Configuring boot"
 | 
						|
 | 
						|
	local selector_boot selector_root selector_overlay
 | 
						|
	selector_boot="$(   blkid --output=export "${devicep}1"                          | grep ^UUID=)"
 | 
						|
	selector_root="$(   blkid --output=export /dev/mapper/vg_umorpha-lv_root_a       | grep ^UUID=)"
 | 
						|
	selector_overlay="$(blkid --output=export /dev/mapper/vg_umorpha-lv_root_overlay | grep ^UUID=)"
 | 
						|
 | 
						|
	mkdir "$tmpdir/root"
 | 
						|
	cleanup+=("rmdir -- ${tmpdir@Q}/root")
 | 
						|
	mount -o ro -- /dev/mapper/vg_umorpha-lv_root_a "$tmpdir/root"
 | 
						|
	cleanup+=("umount ${tmpdir@Q}/root")
 | 
						|
 | 
						|
	mkdir "$tmpdir/overlay"
 | 
						|
	cleanup+=("rmdir -- ${tmpdir@Q}/overlay")
 | 
						|
	mount -- /dev/mapper/vg_umorpha-lv_root_overlay "$tmpdir/overlay"
 | 
						|
	cleanup+=("umount ${tmpdir@Q}/overlay")
 | 
						|
 | 
						|
	mkdir  "$tmpdir/mnt" "$tmpdir/overlay/upperdir" "$tmpdir/overlay/workdir"
 | 
						|
	cleanup+=("rmdir -- ${tmpdir@Q}/mnt")
 | 
						|
	mount -t overlay -o "lowerdir=${tmpdir}/root,upperdir=${tmpdir}/overlay/upperdir,workdir=${tmpdir}/overlay/workdir" umorpha-rootfs \
 | 
						|
	      "${tmpdir}/mnt"
 | 
						|
	cleanup+=("umount ${tmpdir@Q}/mnt")
 | 
						|
 | 
						|
	mount -- "${devicep}1" "$tmpdir/mnt/boot"
 | 
						|
	cleanup+=("umount ${tmpdir@Q}/mnt/boot")
 | 
						|
 | 
						|
	mkdir -p "$tmpdir/mnt/etc/kernel"
 | 
						|
	echo root=$selector_root overlay_root=$selector_overlay boot=$selector_boot rw >"$tmpdir/mnt/etc/kernel/cmdline"
 | 
						|
 | 
						|
	mkdir -p -- "$tmpdir/mnt/boot/EFI/Linux"
 | 
						|
	arch-chroot -- "$tmpdir/mnt" sh -c "printf '%s\n' usr/lib/modules/*/vmlinuz | /usr/share/libalpm/scripts/mkinitcpio install"
 | 
						|
	install -D "$tmpdir/mnt/usr/lib/systemd/boot/efi/systemd-bootx64.efi" "$tmpdir/mnt/boot/EFI/BOOT/BOOTX64.EFI"
 | 
						|
 | 
						|
	arch-chroot -- "$tmpdir/mnt" ldconfig
 | 
						|
	arch-chroot -- "$tmpdir/mnt" systemd-machine-id-setup
 | 
						|
	arch-chroot -- "$tmpdir/mnt" update-ca-trust
 | 
						|
}
 | 
						|
 | 
						|
main "$@"
 |