#!/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 (util-linux, busybox) # - 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) # - arch-chroot (arch-install-scripts) # # Dependencies of arch-chroot (as of v28): # - cat (coreutils, busybox) # - chroot (coreutils, busybox) # - install (coreutils, busybox) # - ln (coreutils, busybox) # - readlink (coreutils, busybox) # - touch (coreutils, busybox) # - mountpoint (util-linux, busybox) # - umount (util-linux, busybox) # - unshare (util-linux, busybox) # - mount (util-linux) # - grep (grep, busybox) # - bash (bash) set -euE -o pipefail set -x main() { local device rootfs device=$1 rootfs=$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}" ######################################################################## 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}") 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" cleanup+=("vgchange --activate=n vg_umorpha") lvcreate --name=lv_root_a --size="$(stat --format='%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" } main "$@"