umorpha-boxes/bin/umorpha-install

258 lines
7.7 KiB
Plaintext
Raw Normal View History

2023-10-31 23:18:47 +00:00
#!/usr/bin/env bash
# Copyright (C) 2023 Umorpha Systems
# SPDX-License-Identifier: AGPL-3.0-or-later
2023-11-04 07:12:14 +00:00
# Dependencies:
2023-11-08 05:07:45 +00:00
# - /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)
2023-11-09 08:20:55 +00:00
# - vgremove (lvm2)
2023-11-08 05:07:45 +00:00
# - pv (pv)
# - mkfs.ext4 (e2fsprogs)
# - mkfs.vfat (dosfstools)
# - arch-chroot (arch-install-scripts)
2023-11-04 07:12:14 +00:00
#
# Dependencies of arch-chroot (as of v28):
# - cat (coreutils, busybox)
# - install (coreutils, busybox)
# - ln (coreutils, busybox)
# - touch (coreutils, busybox)
2023-11-08 05:07:45 +00:00
# - chroot (coreutils; the busybox one doesn't work)
# - readlink (coreutils; the busybox one doesn't work)
2023-11-04 07:12:14 +00:00
# - mountpoint (util-linux, busybox)
# - umount (util-linux, busybox)
# - unshare (util-linux, busybox)
# - mount (util-linux)
# - grep (grep, busybox)
# - bash (bash)
2023-11-05 07:51:34 +00:00
#
# Of those, these are the ones that aren't already in an initcpio:
2023-11-08 05:07:45 +00:00
# - 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)
2023-11-09 08:20:55 +00:00
# - vgremove (lvm2)
2023-11-08 05:07:45 +00:00
# - lvcreate (lvm2)
2023-11-05 07:51:34 +00:00
2023-10-31 23:18:47 +00:00
set -euE -o pipefail
2023-11-08 22:02:54 +00:00
v() {
2023-11-09 21:03:55 +00:00
printf >&2 ' $ %s\n' "${*@Q}"
2023-11-08 22:02:54 +00:00
"$@"
}
2023-10-31 23:18:47 +00:00
main() {
2023-11-13 04:52:10 +00:00
local typ device rootfs
typ=$1
rootfs=$2
device=$3
2023-10-31 23:18:47 +00:00
2023-11-13 04:52:10 +00:00
echo ":: Installing '${rootfs}' to '${device}' for '${typ}'"
2023-11-09 21:55:25 +00:00
if [[ "$rootfs" != *rootfs* ]]; then
echo >&2 "!! Filename '${rootfs}' does not look like a rootfs filename"
return 2
fi
2023-11-13 04:52:10 +00:00
case "$typ" in
uefi|bios) :;;
*)
echo >&2 "!! Install type '${typ}' is not valid"
return 2
;;
esac
2023-10-31 23:18:47 +00:00
2023-12-01 17:28:10 +00:00
########################################################################
2023-10-31 23:18:47 +00:00
cleanup=()
2023-11-09 21:55:25 +00:00
_do_cleanup() {
2023-12-01 17:28:10 +00:00
if [[ $? == 0 ]]; then
echo "::Cleaning up..."
else
echo >&2 "!! ERROR! Cleaning up..."
fi
2023-11-09 21:55:25 +00:00
for (( i=${#cleanup[@]}-1; i >= 0; i-- )); do
eval "${cleanup[$i]}"
done
}
trap '_do_cleanup' EXIT
2023-10-31 23:18:47 +00:00
local tmpdir
tmpdir="$(mktemp -dt "${0##*/}.XXXXXXXXXX")"
cleanup+="rmdir -- ${tmpdir@Q}"
########################################################################
2023-11-08 05:07:45 +00:00
local is_loop=false
2023-10-31 23:18:47 +00:00
if [[ -f "$device" ]]; then
echo " file '${device}' is not a block device, setting up a loopback device..."
2023-11-08 22:02:54 +00:00
device=$(v losetup --find --show --partscan -- "$device")
2023-10-31 23:18:47 +00:00
echo " ... '${device}'"
2023-11-08 22:02:54 +00:00
cleanup+=("v losetup --detach ${device@Q}")
2023-11-08 05:07:45 +00:00
is_loop=true
2023-10-31 23:18:47 +00:00
fi
local devicep="$device"
if [[ "$devicep" == *[0-9] ]]; then
devicep+='p'
fi
2023-11-09 08:20:55 +00:00
v vgremove --yes vg_umorpha || true
2023-11-08 22:02:54 +00:00
2023-10-31 23:18:47 +00:00
########################################################################
echo ":: Setting up GPT"
2023-11-13 13:57:48 +00:00
dd if=/dev/zero of="$device" bs=512 count=4
2023-10-31 23:18:47 +00:00
2023-11-13 04:52:10 +00:00
n=0
2023-10-31 23:18:47 +00:00
cat >"$tmpdir/00-esp.conf" <<-EOF
[Partition]
Type=esp
Format=vfat
Label=Umorpha EFI System Partition
SizeMinBytes=512M
SizeMaxBytes=512M
EOF
2023-11-13 04:52:10 +00:00
n_esp=$((++n))
if [[ $typ == bios ]]; then
cat >"$tmpdir/05-bios.conf" <<-EOF
[Partition]
Type=21686148-6449-6E6F-744E-656564454649
Label=Umorpha BIOS Boot Partition
SizeMinBytes=1M
SizeMaxBytes=1M
EOF
n_bios=$((++n))
fi
2023-10-31 23:18:47 +00:00
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
2023-11-13 04:52:10 +00:00
n_lvm=$((++n))
2023-10-31 23:18:47 +00:00
2023-11-08 22:02:54 +00:00
v systemd-repart \
2023-10-31 23:18:47 +00:00
--empty=allow --dry-run=no \
--no-pager \
--definitions="$tmpdir" \
"$device"
rm -- "$tmpdir"/*.conf
########################################################################
echo ":: Setting up LVM"
2023-11-13 04:52:10 +00:00
v pvcreate "${devicep}${n_lvm}"
v vgcreate vg_umorpha "${devicep}${n_lvm}"
2023-11-08 05:07:45 +00:00
if $is_loop; then
2023-11-08 22:02:54 +00:00
cleanup+=("v vgchange --activate=n vg_umorpha")
2023-11-08 05:07:45 +00:00
fi
2023-10-31 23:18:47 +00:00
2023-11-08 05:07:45 +00:00
# Use short `-c` instead of `--format` so this works with busybox.
2023-11-09 08:20:55 +00:00
v lvcreate --zero=y --wipesignatures=y --yes --name=lv_root_a \
--size="$(stat -c '%s' -- "$rootfs")b" vg_umorpha
2023-11-08 22:02:54 +00:00
v pv -- "$rootfs" >/dev/mapper/vg_umorpha-lv_root_a
2023-10-31 23:18:47 +00:00
2023-11-09 08:20:55 +00:00
v lvcreate --zero=y --wipesignatures=y --yes \
--name=lv_root_overlay --size=1G vg_umorpha
2023-11-08 22:02:54 +00:00
v mkfs.ext4 /dev/mapper/vg_umorpha-lv_root_overlay
2023-10-31 23:18:47 +00:00
########################################################################
echo ":: Configuring boot"
local selector_boot selector_root selector_overlay
2023-11-13 04:52:10 +00:00
selector_boot="$( blkid --output=export "${devicep}${n_esp}" | grep ^UUID=)"
2023-10-31 23:18:47 +00:00
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=)"
2023-11-08 22:02:54 +00:00
v declare -p selector_boot selector_root selector_overlay
2023-10-31 23:18:47 +00:00
mkdir "$tmpdir/root"
cleanup+=("rmdir -- ${tmpdir@Q}/root")
2023-11-08 22:02:54 +00:00
v mount -o ro -- /dev/mapper/vg_umorpha-lv_root_a "$tmpdir/root"
cleanup+=("v umount ${tmpdir@Q}/root")
2023-10-31 23:18:47 +00:00
mkdir "$tmpdir/overlay"
cleanup+=("rmdir -- ${tmpdir@Q}/overlay")
2023-11-08 22:02:54 +00:00
v mount -- /dev/mapper/vg_umorpha-lv_root_overlay "$tmpdir/overlay"
cleanup+=("v umount ${tmpdir@Q}/overlay")
2023-10-31 23:18:47 +00:00
2023-12-01 17:28:10 +00:00
mkdir "$tmpdir/mnt" "$tmpdir/overlay/upperdir" "$tmpdir/overlay/workdir"
2023-10-31 23:18:47 +00:00
cleanup+=("rmdir -- ${tmpdir@Q}/mnt")
2023-11-08 22:02:54 +00:00
v mount -t overlay -o "lowerdir=${tmpdir}/root,upperdir=${tmpdir}/overlay/upperdir,workdir=${tmpdir}/overlay/workdir" umorpha-rootfs \
2023-10-31 23:18:47 +00:00
"${tmpdir}/mnt"
2023-11-08 22:02:54 +00:00
cleanup+=("v umount ${tmpdir@Q}/mnt")
2023-10-31 23:18:47 +00:00
2023-11-13 04:52:10 +00:00
v mount -- "${devicep}${n_esp}" "$tmpdir/mnt/boot"
2023-11-08 22:02:54 +00:00
cleanup+=("v umount ${tmpdir@Q}/mnt/boot")
2023-10-31 23:18:47 +00:00
2023-11-13 04:52:10 +00:00
case "$typ" in
uefi)
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"
v install -D "$tmpdir/mnt/usr/lib/systemd/boot/efi/systemd-bootx64.efi" "$tmpdir/mnt/boot/EFI/BOOT/BOOTX64.EFI"
;;
bios)
v arch-chroot -- "$tmpdir/mnt" grub-install --target=i386-pc "$device"
2023-11-30 16:12:36 +00:00
install -Dm600 /dev/stdin "$tmpdir/mnt/boot/grub/grub.cfg" <<-EOF
insmod part_gpt
insmod part_msdos
if [ -s \$prefix/grubenv ]; then
load_env
fi
if [ -s \$prefix/grub_a.cfg ]; then
configfile \$prefix/grub_a.cfg
fi
if [ -s \$prefix/grub_b.cfg ]; then
configfile \$prefix/grub_b.cfg
fi
EOF
2023-11-13 04:52:10 +00:00
{
for krnl in "$tmpdir/mnt"/usr/lib/modules/*/vmlinuz; do
pkgbase=$(cat -- ${krnl%vmlinuz}pkgbase)
cat <<-EOF
2023-12-01 17:28:10 +00:00
menuentry 'Parabola GNU/Linux-libre, slot a, ${pkgbase} kernel'
2023-11-13 04:52:10 +00:00
set search --no-floppy --fs-uuid --set=root ${selector_boot#UUID=}
echo 'Loading ${pkgbase} kernel...'
linux /vmlinuz-${pkgbase} root=$selector_root overlay_root=$selector_overlay boot=$selector_boot rw
echo 'Loading initial ramdisk...'
initrd /initramfs-${pkgbase}.img
2023-11-13 13:57:48 +00:00
echo 'Booting...'
boot
2023-11-13 04:52:10 +00:00
EOF
done
2023-11-30 16:12:36 +00:00
} | install -Dm600 /dev/stdin "$tmpdir/mnt/boot/grub/grub_a.cfg" <<-EOF
2023-11-13 04:52:10 +00:00
;;
esac
2023-10-31 23:18:47 +00:00
2023-11-08 22:02:54 +00:00
v arch-chroot -- "$tmpdir/mnt" sh -c "printf '%s\n' usr/lib/modules/*/vmlinuz | /usr/share/libalpm/scripts/mkinitcpio install"
v arch-chroot -- "$tmpdir/mnt" ldconfig
v arch-chroot -- "$tmpdir/mnt" systemd-machine-id-setup
v arch-chroot -- "$tmpdir/mnt" update-ca-trust
2023-10-31 23:18:47 +00:00
}
main "$@"