feat: Automate new NixOS installations
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
set positional-arguments
|
||||
|
||||
host := `hostname`
|
||||
key_services := "github gradescope"
|
||||
|
||||
# Default: list available recipes.
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Rebuild the system and switch immediately
|
||||
rebuild:
|
||||
sudo nixos-rebuild switch --flake .#{{host}}
|
||||
@@ -33,3 +39,101 @@ gen-keys:
|
||||
ssh-keygen -t ed25519 -f "$file" -N "" -C "$service@$(hostname -s)"
|
||||
done
|
||||
|
||||
# Build a bootable NixOS installer USB (writes ISO + optional extras partition).
|
||||
# Pass arguments through to scripts/make-usb.sh, e.g.:
|
||||
# just make-usb --iso ~/Downloads/nixos.iso
|
||||
# Re-executes itself under sudo if not already root. Quoting is preserved
|
||||
# via `set positional-arguments` + "$@".
|
||||
make-usb *args:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ ! -x scripts/make-usb.sh ]]; then
|
||||
chmod +x scripts/make-usb.sh
|
||||
fi
|
||||
if (( EUID == 0 )); then
|
||||
exec ./scripts/make-usb.sh "$@"
|
||||
else
|
||||
exec sudo --preserve-env=PATH ./scripts/make-usb.sh "$@"
|
||||
fi
|
||||
|
||||
# Register a new host: scaffold hosts/<name>/ and add a flake.nix entry.
|
||||
# Example: just register-host blackbear
|
||||
register-host name:
|
||||
@python3 scripts/register-host.py --repo-root . "{{name}}"
|
||||
|
||||
# Capture the current machine's hardware config into hosts/<name>/hardware.nix.
|
||||
# Run this on the *new* machine. Two contexts work:
|
||||
# 1. Already-installed NixOS: just runs nixos-generate-config against /.
|
||||
# 2. Booted from installer with target mounted at /mnt: detected
|
||||
# automatically and --root /mnt is used.
|
||||
# Example: just capture-hardware blackbear
|
||||
capture-hardware name:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
name="{{name}}"
|
||||
target="hosts/$name/hardware.nix"
|
||||
|
||||
if [[ ! -d "hosts/$name" ]]; then
|
||||
echo "[-] hosts/$name does not exist. Run \`just register-host $name\` first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v nixos-generate-config >/dev/null 2>&1; then
|
||||
echo "[-] nixos-generate-config not found." >&2
|
||||
echo " Run this command on a NixOS machine (or inside the installer)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Detect whether we're in the installer with a target mounted at /mnt.
|
||||
extra_args=()
|
||||
if mountpoint -q /mnt 2>/dev/null && [[ -d /mnt/etc ]]; then
|
||||
echo "[+] Detected mounted target at /mnt — using --root /mnt"
|
||||
extra_args+=(--root /mnt)
|
||||
elif mountpoint -q /mnt 2>/dev/null; then
|
||||
echo "[!] /mnt is mounted but doesn't look like a NixOS target (no /mnt/etc)."
|
||||
echo " Continuing as if on a running system. Pass --no-filesystems by editing"
|
||||
echo " hardware.nix afterwards if disks aren't permanent."
|
||||
fi
|
||||
|
||||
# Confirm before overwriting a non-placeholder hardware.nix.
|
||||
if [[ -f "$target" ]] && ! grep -q 'PLACEHOLDER hardware.nix' "$target"; then
|
||||
echo "[!] $target already exists and doesn't look like a placeholder." >&2
|
||||
read -r -p "Overwrite? (yes/[no]) " confirm
|
||||
[[ "$confirm" == "yes" ]] || { echo "aborted."; exit 1; }
|
||||
fi
|
||||
|
||||
echo "[+] Generating hardware config..."
|
||||
# The redirect runs in the user's shell BEFORE sudo, so the file is
|
||||
# owned by you, not root. sudo is needed because nixos-generate-config
|
||||
# reads /proc, /sys, and may probe mounted filesystems.
|
||||
sudo nixos-generate-config --show-hardware-config "${extra_args[@]}" > "$target"
|
||||
echo "[+] Wrote $target"
|
||||
if command -v git >/dev/null && git -C . rev-parse >/dev/null 2>&1; then
|
||||
echo "[+] git diff:"
|
||||
git --no-pager diff -- "$target" || true
|
||||
fi
|
||||
|
||||
# Show which hosts are currently registered in flake.nix (parses the file directly).
|
||||
hosts:
|
||||
#!/usr/bin/env python3
|
||||
import re, sys
|
||||
src = open('flake.nix').read()
|
||||
m = re.search(r'nixosConfigurations\s*=\s*\{', src)
|
||||
if not m:
|
||||
sys.exit(0)
|
||||
# Brace-match to find the closing }.
|
||||
depth, i, close = 0, m.end() - 1, None
|
||||
while i < len(src):
|
||||
c = src[i]
|
||||
if c == '{': depth += 1
|
||||
elif c == '}':
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
close = i
|
||||
break
|
||||
i += 1
|
||||
block = src[m.end():close] if close else ''
|
||||
for name in re.findall(r'^[ \t]*([A-Za-z_][\w-]*)\s*=\s*nixpkgs\.lib\.nixosSystem', block, re.M):
|
||||
print(name)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user