#!/bin/sh set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") . "$script_dir/mouse-arch.sh" cheesed_dir="$repo_dir/base/cheesed" build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} target=${CHEESED_TARGET:-$MOUSE_RUST_TARGET} test_fixtures=${MOUSE_INCLUDE_TEST_FIXTURES:-0} kernel_modules=${MOUSE_KERNEL_MODULES:-"$build_dir/kernel/modules"} device_firmware=${MOUSE_DEVICE_FIRMWARE:-"$build_dir/device-firmware"} staging= image_staging= cleanup() { for directory in "$staging" "$image_staging"; do if [ -n "$directory" ] && [ -d "$directory" ]; then rm -rf "$directory" fi done } trap cleanup EXIT HUP INT TERM case "$test_fixtures" in 0|1) ;; *) printf '%s\n' "MOUSE_INCLUDE_TEST_FIXTURES must be 0 or 1" >&2 exit 1 ;; esac base_root="$build_dir/static/rootfs" ports_seed=${MOUSE_PORTS_SEED:-"$build_dir/mouse-ports-seed"} for input in "$base_root" "$build_dir/vmlinuz-virt" \ "$device_firmware/lib/firmware"; do if [ ! -e "$input" ]; then printf '%s\n' "missing prepared image input: $input" >&2 exit 1 fi done if [ ! -d "$ports_seed/usr/local" ]; then printf '%s\n' "missing mouse-ports seed directory: $ports_seed/usr/local" >&2 exit 1 fi btrfs_image_tool=${MOUSE_BTRFS_IMAGE_TOOL:-"$base_root/sbin/mkfs.btrfs"} if [ ! -x "$btrfs_image_tool" ]; then printf '%s\n' "missing btrfs image tool: $btrfs_image_tool" >&2 exit 1 fi if [ -n "${MOUSE_CHEESED_BINARY:-}" ]; then cheesed_binary=$MOUSE_CHEESED_BINARY else cheesed_binary=$(CHEESED_TARGET="$target" "$cheesed_dir/scripts/build-static.sh") fi staging=$(mktemp -d "${TMPDIR:-/tmp}/mouse-rootfs.XXXXXX") image_staging=$(mktemp -d "${TMPDIR:-/tmp}/mouse-btrfs.XXXXXX") install -d -m 0755 \ "$staging/dev" \ "$staging/bin" \ "$staging/etc" \ "$staging/etc/default" \ "$staging/etc/rc.d" \ "$staging/etc/skel" \ "$staging/home" \ "$staging/media" \ "$staging/mnt" \ "$staging/proc" \ "$staging/root" \ "$staging/run" \ "$staging/sbin" \ "$staging/srv" \ "$staging/sys" \ "$staging/usr/bin" \ "$staging/usr/local/etc/rc.d" \ "$staging/usr/lib/mouse" \ "$staging/usr/sbin" \ "$staging/var/cache/mouse/ports/distfiles" \ "$staging/var/cache/mouse/packages" \ "$staging/var/db" \ "$staging/var/lib/dhcpcd" \ "$staging/var/empty" \ "$staging/var/log" \ "$staging/var/mail" \ "$staging/var/spool/cron" chmod 0755 "$staging" chmod 0700 "$staging/root" chmod 0755 "$staging/var/empty" chmod 0700 "$staging/var/spool/cron" install -d -m 1777 \ "$staging/tmp" \ "$staging/var/tmp" \ "$staging/var/tmp/vi.recover" ln -s /run "$staging/var/run" cp -R "$base_root/." "$staging/" cp -R "$ports_seed/usr/local/." "$staging/usr/local/" if [ ! -d "$kernel_modules/lib/modules" ]; then printf '%s\n' "missing kernel module tree: $kernel_modules/lib/modules" >&2 exit 1 fi cp -R "$kernel_modules/lib/." "$staging/lib/" cp -R "$device_firmware/lib/firmware" "$staging/lib/" if [ "$test_fixtures" -eq 1 ] && [ -d "$kernel_modules/usr/local" ]; then cp -R "$kernel_modules/usr/local/." "$staging/usr/local/" fi install -m 0755 "$cheesed_binary" "$staging/sbin/cheesed" for command in service shutdown poweroff reboot; do ln -s cheesed "$staging/sbin/$command" done cp -R "$repo_dir/base/rootfs/." "$staging/" install -d -m 0700 -o 1000 -g 1000 "$staging/home/mouse" sed "s/@MOUSE_ARCH@/$MOUSE_ARCH/g" \ "$staging/etc/mouse-release" >"$staging/etc/mouse-release.new" mv "$staging/etc/mouse-release.new" "$staging/etc/mouse-release" sed "s/@MOUSE_ARCH@/$MOUSE_ARCH/g" \ "$staging/etc/motd" >"$staging/etc/motd.new" mv "$staging/etc/motd.new" "$staging/etc/motd" for console_file in \ "$staging/etc/rc.d/console_login" \ "$staging/etc/securetty" do sed "s/@MOUSE_CONSOLE@/$MOUSE_CONSOLE/g" \ "$console_file" >"$console_file.new" mv "$console_file.new" "$console_file" done if [ "$test_fixtures" -eq 1 ]; then cp -R "$repo_dir/tests/fixtures/mouse-echo/rootfs/." "$staging/" install -m 0755 \ "${MOUSE_MOUSE_ECHO_BINARY:?missing test mouse-echo binary}" \ "$staging/usr/libexec/mouse-echo" printf '%s\n' "enable_mouse_echo=YES" >>"$staging/etc/rc.conf" test_password_hash='$6$mouse$LofYSsSObtmx/zmS97A.TFONKSQSATXE4bD6dY1H7JSBSayuyAuc4Qwpm7JdfW9lUnri9DrQfUKGiLTNKA3v81' awk -F: -v OFS=: -v password_hash="$test_password_hash" ' $1 == "root" || $1 == "toor" { $2 = password_hash } { print } ' "$staging/etc/shadow" >"$staging/etc/shadow.test" mv "$staging/etc/shadow.test" "$staging/etc/shadow" fi install -d -m 0755 "$staging/usr/share/mouse" install -m 0444 \ "${MOUSE_PORTS_REVISION_FILE:-/work/mouse-ports-revision}" \ "$staging/usr/share/mouse/ports.revision" patch "$staging/etc/rc.subr" \ <"$repo_dir/base/patches/rc.subr-cgroup.patch" chmod 0444 "$staging/etc/rc.subr" ln -s mouse-release "$staging/etc/os-release" chmod 0755 \ "$staging/etc/rc.d/console_login" \ "$staging/etc/rc.d/cron" \ "$staging/etc/rc.d/daemon" \ "$staging/etc/rc.d/login" \ "$staging/etc/rc.d/loopback" \ "$staging/etc/rc.d/machine_identity" \ "$staging/etc/rc.d/gardendevd" \ "$staging/etc/rc.d/network" \ "$staging/etc/rc.d/ntpd" \ "$staging/etc/rc.d/servers" \ "$staging/etc/rc.d/syslogd" \ "$staging/etc/rc.d/wpa_supplicant" \ "$staging/usr/libexec/mouse-dhcpcd-hook" \ "$staging/usr/libexec/mouse-wpa-supplicant" if [ "$test_fixtures" -eq 1 ]; then chmod 0755 "$staging/etc/rc.d/mouse_echo" fi chown 0:0 \ "$staging/bin/ping" \ "$staging/bin/su" \ "$staging/usr/bin/crontab" \ "$staging/usr/bin/doas" \ "$staging/usr/bin/passwd" chmod 4755 \ "$staging/bin/ping" \ "$staging/bin/su" \ "$staging/usr/bin/crontab" \ "$staging/usr/bin/doas" \ "$staging/usr/bin/passwd" chmod 0600 "$staging/etc/shadow" chmod 0600 "$staging/etc/wpa_supplicant/wpa_supplicant.conf" "$script_dir/audit-static-base.sh" "$staging" for desktop_input in \ /usr/local/bin/bmake \ /usr/local/bin/dwl \ /usr/local/bin/havoc \ /usr/local/bin/mouse-dwl-session \ /usr/local/bin/seatd \ /usr/local/bin/tuigreet \ /usr/local/lib/libudev.so \ /usr/local/lib/libwlroots-0.19.so \ /usr/local/sbin/greetd \ /usr/local/etc/rc.d/greetd \ /usr/local/etc/rc.d/seatd do [ -e "$staging$desktop_input" ] || { printf '%s\n' "missing mouse-ports seed input: $desktop_input" >&2 exit 1 } done mkdir -p "$build_dir" btrfs_image="$build_dir/mouse-rootfs.btrfs" rootfs_size=${MOUSE_ROOTFS_SIZE:-8G} install -d -m 0755 \ "$image_staging/ROOT/default" \ "$image_staging/ROOT/alternate" \ "$image_staging/usr-local" \ "$image_staging/var" \ "$image_staging/home" \ "$image_staging/srv" cp -a "$staging/." "$image_staging/ROOT/default/" cp -a "$staging/." "$image_staging/ROOT/alternate/" printf '%s\n' default \ >"$image_staging/ROOT/default/etc/mouse-boot-environment" printf '%s\n' alternate \ >"$image_staging/ROOT/alternate/etc/mouse-boot-environment" for persistent in \ usr/local:usr-local \ var:var \ home:home \ srv:srv do root_path=${persistent%%:*} subvolume=${persistent#*:} cp -a "$staging/$root_path/." "$image_staging/$subvolume/" for environment in default alternate; do rm -rf "$image_staging/ROOT/$environment/$root_path" install -d -m 0755 \ "$image_staging/ROOT/$environment/$root_path" done done for environment in default alternate; do metadata=$(stat -c '%a %u %g' \ "$image_staging/ROOT/$environment/usr/bin/doas") if [ "$metadata" != "4755 0 0" ]; then printf '%s\n' \ "image staging lost doas setuid metadata in $environment" >&2 exit 1 fi done metadata=$(stat -c '%a %u %g' "$image_staging/home/mouse") if [ "$metadata" != "700 1000 1000" ]; then printf '%s\n' "image staging lost mouse home ownership" >&2 exit 1 fi rm -f "$btrfs_image" truncate -s "$rootfs_size" "$btrfs_image" "$btrfs_image_tool" \ --force \ --label MOUSE_ROOT \ --uuid 4d4f5553-4500-4000-8000-00000000000b \ --rootdir "$image_staging" \ --subvol default:ROOT/default \ --subvol rw:ROOT/alternate \ --subvol rw:usr-local \ --subvol rw:var \ --subvol rw:home \ --subvol rw:srv \ "$btrfs_image" printf '%s\n' "built $build_dir/vmlinuz-virt" sh "$script_dir/build-boot-disk.sh" rm -f "$btrfs_image"