kexec/run rebuilds an initrd via cpio|gzip from PATH — absent on ZimaOS, so run aborted before kexec and the box stayed on ZimaOS. Ship GNU static cpio + busybox (as gzip) into /tmp/bin, prepend PATH. SSH ControlMaster = one password prompt.
92 lines
3.7 KiB
Bash
Executable File
92 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Deploy the jupiter NixOS config.
|
|
#
|
|
# ./deploy kexec <host> headless-only: for a read-only-root box (ZimaOS)
|
|
# where nixos-anywhere can't ssh-copy-id. Uploads a
|
|
# kexec installer (our SSH key baked in) to /tmp and
|
|
# boots into it. Then run `install`.
|
|
# ./deploy install <ip> first install onto a fresh box / running installer
|
|
# (nixos-anywhere). Wipes the OS disk. Ships host key.
|
|
# ./deploy [switch] [host] rebuild + activate on a running jupiter (default).
|
|
# ./deploy boot [host] stage for next boot, don't activate now.
|
|
# ./deploy test [host] activate without adding a boot entry.
|
|
#
|
|
# Runs from a non-NixOS host too (nixos-rebuild / nixos-anywhere via `nix run`).
|
|
set -euo pipefail
|
|
|
|
REPO="$(cd "$(dirname "$0")" && pwd)"
|
|
cd "$REPO"
|
|
export PATH="/nix/var/nix/profiles/default/bin:$PATH"
|
|
|
|
HOSTKEY="$HOME/.config/homelab/jupiter/ssh_host_ed25519_key"
|
|
|
|
cmd="${1:-switch}"
|
|
case "$cmd" in
|
|
switch|boot|test|install|kexec) shift || true ;;
|
|
*) cmd="switch" ;;
|
|
esac
|
|
|
|
case "$cmd" in
|
|
kexec)
|
|
host="${1:-}"
|
|
[ -n "$host" ] || { echo "usage: ./deploy kexec <ip-or-host>" >&2; exit 1; }
|
|
|
|
echo ">> building kexec installer + static tools"
|
|
nix build .#nixosConfigurations.kexec.config.system.build.kexecInstallerTarball \
|
|
-o result-kexec
|
|
tb="$(ls result-kexec/*.tar.gz | head -1)"
|
|
# kexec/run rebuilds an initrd with `cpio` + `gzip` from PATH — ZimaOS lacks
|
|
# both. Ship static ones: GNU cpio (reliable -o -H newc), busybox as gzip.
|
|
cpio="$(nix build --no-link --print-out-paths nixpkgs#pkgsStatic.cpio)/bin/cpio"
|
|
bbox="$(nix build --no-link --print-out-paths nixpkgs#pkgsStatic.busybox)/bin/busybox"
|
|
|
|
# One password prompt: multiplex scp + ssh over a shared control connection.
|
|
cm="/tmp/homelab-cm-%r@%h:%p"
|
|
o=(-o ControlMaster=auto -o "ControlPath=$cm" -o ControlPersist=300 \
|
|
-o StrictHostKeyChecking=accept-new)
|
|
|
|
echo ">> connecting to root@$host (enter the ZimaOS root password once)"
|
|
ssh "${o[@]}" "root@$host" 'mkdir -p /tmp/bin'
|
|
scp "${o[@]}" "$cpio" "root@$host:/tmp/bin/cpio"
|
|
scp "${o[@]}" "$bbox" "root@$host:/tmp/bin/gzip" # busybox as gzip (argv0)
|
|
|
|
echo ">> streaming installer + kexec-ing. SSH drops as the box jumps into the"
|
|
echo " RAM installer. Disks are untouched."
|
|
ssh "${o[@]}" "root@$host" \
|
|
'chmod +x /tmp/bin/*; mkdir -p /tmp/k && tar -C /tmp/k -xzf - && PATH=/tmp/bin:$PATH /tmp/k/kexec/run' \
|
|
< "$tb" || true
|
|
|
|
ssh "${o[@]}" -O exit "root@$host" 2>/dev/null || true # close control socket
|
|
echo ">> box is kexec-ing. Wait ~1-2 min for the installer + network, then:"
|
|
echo " ./deploy install $host"
|
|
;;
|
|
|
|
install)
|
|
host="${1:-}"
|
|
[ -n "$host" ] || { echo "usage: ./deploy install <ip-or-host>" >&2; exit 1; }
|
|
[ -f "$HOSTKEY" ] || { echo "missing host key: $HOSTKEY" >&2; exit 1; }
|
|
|
|
# Stage the pre-generated SSH host key so sops can decrypt on boot #1.
|
|
stage="$(mktemp -d)"
|
|
trap 'rm -rf "$stage"' EXIT
|
|
install -Dm600 "$HOSTKEY" "$stage/etc/ssh/ssh_host_ed25519_key"
|
|
install -Dm644 "$HOSTKEY.pub" "$stage/etc/ssh/ssh_host_ed25519_key.pub"
|
|
|
|
echo ">> nixos-anywhere onto root@$host (OS disk WILL be wiped)"
|
|
nix run github:nix-community/nixos-anywhere -- \
|
|
--flake ".#jupiter" \
|
|
--extra-files "$stage" \
|
|
--generate-hardware-config nixos-generate-config ./jupiter/hardware-configuration.nix \
|
|
--target-host "root@$host"
|
|
;;
|
|
|
|
switch|boot|test)
|
|
host="${1:-jupiter}"
|
|
echo ">> nixos-rebuild $cmd on darman@$host"
|
|
nix run nixpkgs#nixos-rebuild -- "$cmd" \
|
|
--flake ".#jupiter" \
|
|
--target-host "darman@$host" \
|
|
--use-remote-sudo
|
|
;;
|
|
esac
|