#!/bin/bash die() { printf 'Error: %s\n' "$*" >&2 exit 1 } KiB() { printf %s $(("$1" * 1024)) } MiB() { KiB $(KiB "$1") } initialize_target() { rm -f "$target" if [ "$ROOTFS" ] then fallocate -l $(($(KiB 17) + $(MiB $end_keys) + $(MiB $rootfs_size))) "$target" else fallocate -l $(($(KiB 17) + $(MiB $end_keys))) "$target" fi } # TODO: Use GUID type tags for each Samizdat partition type. partition_target() { parted "$target" -sm -a optimal \ unit MiB \ mklabel gpt \ mkpart samizdat-grub 1 8 \ set 1 bios_grub on \ mkpart samizdat-keys btrfs ${start_keys} ${end_keys} if [ "$ROOTFS" ] then parted "$target" -sm -a optimal \ mkpart samizdat-rootfs btrfs ${end_keys}MiB 100% fi } make_target_bootable() { losetup -f "$target" dev=$(losetup -j "$target" -O NAME --noheadings) kpartx -vasas "$dev" kdev=/dev/mapper/${dev##*/} mnt=$target.mnt mkfs.btrfs --mixed "$kdev"p2 mkdir -p "$mnt" mount "$kdev"p2 "$mnt" mkdir -p "$mnt"/boot/grub cp -aL "$GRUB_CONFIG" "$mnt"/boot/grub eatmydata -- grub-install -v --boot-directory "$mnt"/boot "$dev" sync } release_target_kernel_resources() { umount "$mnt" kpartx -d "$dev" losetup -d "$dev" } with_target() { local mnt dev target="$1" shift mnt=$target.mnt mkdir -p "$mnt" losetup -f "$target" -o $(MiB $start_keys) dev=$(losetup -j "$target" -O NAME --noheadings) mount "$dev" "$mnt" "$@" umount "$mnt" losetup -d "$dev" } add_keys() { rsync -a --info=STATS "$GPG_INPUT_DIR"/ "$mnt"/gnupghome/ } initrd_suffix=.samizdat add_initrd() { mkdir -p "$mnt"/linux rsync -aL --info=STATS "${1}vmlinuz${2}" "$mnt"/linux/vmlinuz rsync -aL --info=STATS "${1}initrd.img${2}${initrd_suffix}" "$mnt"/linux/initrd.img } add_grub_cfg() { mkdir -p "$mnt"/boot/grub cp -aL "$GRUB_CONFIG" "$mnt"/boot/grub } individualize() { add_keys add_initrd "$samizdat_linux_dir"/ "${version_suffix}" add_grub_cfg } sanity_checks() { [[ $UID = 0 ]] || die "You are not root." for d in "$samizdat_linux_dir" "$GPG_INPUT_DIR" do [ -d "$d" ] || die "Not a directory: $d" done } create_template() { local target="${1}.tmp" if [ ! -e "${target%.tmp}" ] then initialize_target partition_target make_target_bootable release_target_kernel_resources mv -T "$target" "${target%.tmp}" fi } individualize_target_from() { cp -T --reflink=always "$1" "$target" with_target "$target" individualize } . samizdat-paths.sh || die 'samizdat-paths.sh not found' samizdat_linux_dir=/boot : ${GPG_INPUT_DIR:=/cdrom/gnupghome} : ${GRUB_CONFIG:=conf/grub.cfg} start_keys=64 # megs end_keys=256 # megs if [ "$1" ] then version_suffix=-$1 fi sanity_checks set -e template=boot-disk.template.img target=boot-disk.img.tmp final=${target%.tmp} create_template "$template" individualize_target_from "$template" mv -T "$target" "$final" installer_target=target-disk.img rm -f "$installer_target" if [ ! -e "$installer_target" ] then fallocate -l 10G "$installer_target" fi qemu-system-x86_64 -enable-kvm -smp 2 -m 512 -k en-us -vga qxl -drive file="$final",format=raw -drive file="$installer_target",format=raw