#!/usr/bin/env bash set -euo pipefail # --- Defaults --- HOSTNAME=$(hostname) USB_DEVICE="" REPO_URL="git@codeberg.org:adikro/nixos-config.git" KEY_LOCATION="" USE_FACTER=true # --- Parse Arguments --- PARSED_ARGS=$(getopt -o u:h:r:k:g --long usb:,hostname:,repo:,key:,generate-config -- "$@") eval set -- "$PARSED_ARGS" while true; do case "$1" in -u|--usb) USB_DEVICE="$2"; shift 2 ;; -h|--hostname) HOSTNAME="$2"; shift 2 ;; -r|--repo) REPO_URL="$2"; shift 2 ;; -k|--key) KEY_LOCATION="$2"; shift 2 ;; -g|--generate-config) USE_FACTER=false; shift ;; --) shift; break ;; *) echo "Internal error!"; exit 1 ;; esac done echo "### 1. GPG Key Preparation ###" export GPG_TTY=$(tty) if [[ -n "$KEY_LOCATION" ]]; then gpg --import "$KEY_LOCATION" elif [[ -n "$USB_DEVICE" ]]; then echo "Mounting $USB_DEVICE..." sudo mkdir -p /mnt/usb findmnt -rno SOURCE "$USB_DEVICE" >/dev/null || sudo mount "$USB_DEVICE" /mnt/usb echo "Searching USB for private.asc..." KEY_FILE=$(sudo fd -H -t f "private.asc" /mnt/usb --max-results 1) if [[ -n "$KEY_FILE" ]]; then KEY_DIR=$(dirname "$KEY_FILE") echo "Found keys in $KEY_DIR. Importing..." ( cd "$KEY_DIR" gpg --import private.asc [[ -f "public.asc" ]] && gpg --import public.asc [[ -f "trust.txt" ]] && gpg --import-ownertrust trust.txt ) else echo "Error: private.asc not found on $USB_DEVICE" sudo umount /mnt/usb; exit 1 fi sudo umount /mnt/usb else gpg -K | grep -q "sec" || { echo "No keys found. Use --usb or --key."; exit 1; } fi echo "### 2. Repo Setup ###" sudo mkdir -p /etc/nixos sudo chown -R "$USER":users /etc/nixos [[ ! -d "/etc/nixos/.git" ]] && git clone "$REPO_URL" /etc/nixos cd /etc/nixos echo "### 3. Hardware Refresh ###" HOST_DIR="./hosts/$HOSTNAME" mkdir -p "$HOST_DIR" if [ "$USE_FACTER" = true ]; then nixos-facter -o "$HOST_DIR/facter.json" else sudo nixos-generate-config --no-filesystems --root / mv /etc/nixos/hardware-configuration.nix "$HOST_DIR/hardware-configuration.nix" fi echo "### 4. SOPS Rotation ###" NEW_AGE=$(ssh-to-age < /etc/ssh/ssh_host_ed25519_key.pub) if grep -q "&host_$HOSTNAME" .sops.yaml; then sd "(&host_$HOSTNAME\s+-) age1.*" "\$1 $NEW_AGE" .sops.yaml else sd "(keys:\n)" "\$1 - &host_$HOSTNAME $NEW_AGE\n" .sops.yaml sd "(age:\n(.*\n)*?\s+age:\n)" "\$1 - *host_$HOSTNAME\n" .sops.yaml fi sops updatekeys secrets/secrets.yaml -y echo "### 5. System Rebuild ###" git add . nh os switch . -u -H "$HOSTNAME" echo "### 6. Git Finalization ###" [[ $(git remote) =~ "origin" ]] && git remote rename origin codeberg git remote set-url codeberg "$REPO_URL" git add . git commit -m "chore($HOSTNAME): hardware refresh and sops rotation" || echo "No changes." read -p "Push to Codeberg? (y/N): " push_confirm [[ "$push_confirm" == [yY] ]] && git push -u codeberg main echo "SETUP COMPLETE. Rebooting is recommended."