#!/bin/fish function error -d "prints an error and exits" -a error echo $error 1>&2 exit 1 end function check_deps -d "checks if all dependencies are available" set -l dependencies \ "efibootmgr" \ "jq" \ "sed" \ "snapper" \ for dep in $dependencies which $dep >/dev/null 2>/dev/null if test $status != "0" error "missing depenency: $dep" end end end function config -d "sets some configuration variables" set -g CFG_BUILD_DIR "/tmp/snap-pac-uki" set -g CFG_DEFAULT_SUBVOL "@" set -g CFG_EFI_DEV "/dev/nvme0n1" set -g CFG_EFI_PATH "\EFI\Linux" set -g CFG_EFI_PART "1" set -g CFG_SNAPSHOT_CONFIG "root" set -g CFG_SNAPSHOT_PATH "/.snapshots" set -g CFG_SNAPSHOT_SUBVOL "@snapshots" set -g CFG_UKI_DIR "/efi/EFI/Linux" end function find_tasks -d "finds out what the program needs to do" set -ge TASK_UKI for id in (snapper -c $CFG_SNAPSHOT_CONFIG --jsonout ls | jq ".$CFG_SNAPSHOT_CONFIG [] | .number") if test "$id" = "0" continue end if test -f "$CFG_UKI_DIR/arch-linux-$id.efi" continue end set -ga TASK_UKI $id end end function create_uki -d "creates a new uki" -a variant id switch $variant case "rolling" set bd "$CFG_BUILD_DIR/current" case "fallback" set bd "$CFG_BUILD_DIR/current" set fallback "-fallback" case "snapshot" set bd "$CFG_BUILD_DIR/$id" set snid "-$id" set prefix "$CFG_SNAPSHOT_PATH/$id/snapshot" case "*" error "unknown uki variant: $variant" end objcopy \ --add-section .osrel="$bd/os-release$fallback" --change-section-vma .osrel=0x20000 \ --add-section .cmdline="$bd/kernel-cmd$fallback" --change-section-vma .cmdline=0x30000 \ --add-section .splash="$prefix/usr/share/systemd/bootctl/splash-arch.bmp" --change-section-vma .splash=0x40000 \ --add-section .linux="$prefix/boot/vmlinuz-linux" --change-section-vma .linux=0x2000000 \ --add-section .initrd="$prefix/boot/initramfs-linux$fallback.img" --change-section-vma .initrd=0x3000000 \ "$prefix/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "$bp/arch-linux$fallback$snid.efi" end function add_efi_entry -d "adds an efi boot entry for a snapshot uki" -a id efibootmgr -q -C -d $CFG_EFI_DEV -p $CFG_EFI_PART \ -l "$EFI_PATH\arch-linux-$id.efi" \ -L "Arch Linux (Snapshot $id)" end function create_snapshot_uki -d "creates an uki for a snapshot" -a id # create build directory set bd "$CFG_BUILD_DIR/$id" if test -f $bd error "build dir for snapshot $id is a file" else if test -d $bd rm -rf "$bd/*" else mkdir $bd end # prepare files sed "s/BUILD_ID=.*/BUILD_ID=\"snapshot $id\"/;s/PRETTY_NAME=\"\(.*\)\"/PRETTY_NAME=\"\1 (Snapshot $id)\"" <"$CFG_SNAPSHOT_PATH/$id/snapshot/usr/lib/os-release" >"$bd/os-release" sed "s/SNAPSHOT/$CFG_SNAPSHOT_SUBVOL/" <"$CFG_SNAPSHOT_PATH/$id/snapshot/etc/snap-pac-uki/kernel-cmd" >"$bd/kernel-cmd" # create uki create_uki snapshot $id add_efi_entry $id end function main # prepare for execution check_deps config switch $argv[1] case "snapshots" find_tasks for id in $TASK_UKI create_snapshot_uki $id end case "*" error "unknown command" end end main $argv