#!/bin/sh
# ci/install.sh — keyboot bootstrap installer (ADR 0008, SPEC §13.10).
#
# The signed `curl | sh` entry point. Published at packages.osterman.co/keyboot/install;
# fetches the versioned artifacts, VERIFIES them with minisign against a pinned
# public key, and installs the userland tools (and, with --rescue, the installer
# + boot image). Runs from any live/rescue env (POSIX sh).
#
#   curl -fsSL https://packages.osterman.co/keyboot/install | sh
#   curl -fsSL .../install | sh -s -- --rescue          # also installer+boot img
#   KEYBOOT_VERSION=1.2.3 ... | sh                       # pin a version
#   KEYBOOT_PKG_BASE=https://host/keyboot ... | sh       # override host (pre-prod)
#
# Security: every artifact is covered by SHA256SUMS, which is minisign-signed.
# We verify the signature with the pinned KEYBOOT_MINISIGN_PUBKEY before trusting
# or executing anything. No verification => no install.

set -eu

PKG_BASE="${KEYBOOT_PKG_BASE:-https://packages.osterman.co/keyboot}"
VERSION="${KEYBOOT_VERSION:-}"
RESCUE=0
PREFIX="${KEYBOOT_PREFIX:-/usr}"
WORK=
# Pinned minisign public key (project signing key; replace with the real one at
# release-cut time and bake the same value into the keyboot image for pre-fetch).
KEYBOOT_MINISIGN_PUBKEY="${KEYBOOT_MINISIGN_PUBKEY:-RWTrhJW+9h/jDQZkoGzVdqZnMvkRwjdmMeeimbc39fj/kyAg54+2J9BZ}"

say()  { printf 'keyboot-install: %s\n' "$*" >&2; }
die()  { printf 'keyboot-install: ERROR: %s\n' "$*" >&2; exit 1; }
cleanup() { [ -n "$WORK" ] && rm -rf "$WORK"; }
trap cleanup EXIT

for a in "$@"; do case "$a" in
    --rescue) RESCUE=1 ;;
    --prefix=*) PREFIX="${a#*=}" ;;
    -h|--help) sed -n '2,16p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) die "unknown arg: $a" ;;
esac; done

[ "$(id -u)" = 0 ] || die "must run as root (installs into $PREFIX/sbin)"
command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || die "need curl or wget"
fetch() { if command -v curl >/dev/null 2>&1; then curl -fsSL "$1" -o "$2"; else wget -qO "$2" "$1"; fi; }

arch="$(uname -m)"; case "$arch" in x86_64|amd64) arch=x86_64 ;; *) die "unsupported arch: $arch (x86_64 only for now)" ;; esac

# Resolve version (latest pointer unless pinned).
if [ -z "$VERSION" ]; then
    WORK="$(mktemp -d)"; fetch "$PKG_BASE/latest" "$WORK/latest" || die "cannot reach $PKG_BASE/latest (host up? set KEYBOOT_PKG_BASE)"
    VERSION="$(tr -d ' \n\r' < "$WORK/latest")"
    [ -n "$VERSION" ] || die "empty version pointer"
else
    WORK="$(mktemp -d)"
fi
BASE="$PKG_BASE/$VERSION"
say "installing keyboot $VERSION from $BASE (arch $arch)"

# Fetch checksums + signature and VERIFY before trusting any artifact.
fetch "$BASE/SHA256SUMS" "$WORK/SHA256SUMS" || die "fetch SHA256SUMS"
fetch "$BASE/SHA256SUMS.minisig" "$WORK/SHA256SUMS.minisig" || die "fetch signature"
if command -v minisign >/dev/null 2>&1; then
    minisign -Vm "$WORK/SHA256SUMS" -P "$KEYBOOT_MINISIGN_PUBKEY" -x "$WORK/SHA256SUMS.minisig" >/dev/null 2>&1 \
        || die "SIGNATURE VERIFICATION FAILED — refusing to install"
    say "signature verified (minisign)"
else
    die "minisign not found — install it first; keyboot refuses to install unverified artifacts"
fi

# Download + checksum each artifact.
get() {  # get <remote-name> <local>
    fetch "$BASE/$1" "$2" || die "fetch $1"
    want="$(grep " $1\$" "$WORK/SHA256SUMS" | awk '{print $1}')"
    [ -n "$want" ] || die "$1 not in SHA256SUMS"
    have="$(sha256sum "$2" | awk '{print $1}')"
    [ "$want" = "$have" ] || die "$1 checksum mismatch"
}

install -d "$PREFIX/sbin" "$PREFIX/local/sbin" 2>/dev/null || true
get "keyboot-$arch-musl" "$WORK/keyboot";           install -m0755 "$WORK/keyboot" "$PREFIX/sbin/keyboot"
get "keyboot-autosnap"   "$WORK/keyboot-autosnap";  install -m0755 "$WORK/keyboot-autosnap" "$PREFIX/sbin/keyboot-autosnap"
get "keyboot-be-upgrade" "$WORK/keyboot-be-upgrade";install -m0755 "$WORK/keyboot-be-upgrade" "$PREFIX/local/sbin/keyboot-be-upgrade"
get "keyboot-be-rollback" "$WORK/keyboot-be-rollback";install -m0755 "$WORK/keyboot-be-rollback" "$PREFIX/local/sbin/keyboot-be-rollback"
say "installed keyboot, keyboot-autosnap, keyboot-be-upgrade, keyboot-be-rollback"

if [ "$RESCUE" = 1 ]; then
    get "keyboot-install-$arch-musl" "$WORK/keyboot-install"; install -m0755 "$WORK/keyboot-install" "$PREFIX/sbin/keyboot-install"
    get "keyboot-vmlinuz" "$WORK/keyboot-vmlinuz"
    get "keyboot-initramfs.img" "$WORK/keyboot-initramfs.img"
    install -d /var/lib/keyboot/staged
    install -m0644 "$WORK/keyboot-vmlinuz" "$WORK/keyboot-initramfs.img" /var/lib/keyboot/staged/
    say "installed keyboot-install + staged boot image at /var/lib/keyboot/staged (commit with: keyboot install)"
fi

say "done. (cron for keyboot-autosnap: see tools/keyboot-autosnap/README.md)"
