feat(nixos): add phantom-ship host and streamline server installer ✨
- New host config: phantom-ship.nix (SSH, auto-rebuild, nix-ld, Ethernet) - Hardware stub: phantom-ship-hardware.nix (replaced by install script) - Add phantom-ship to flake.nix with home-manager - Install script now auto-provisions post-install: - Clones dotfiles to /etc/dotfiles - Installs SSH public key (SSH_PUBKEY_FILE env var) - Generates hardware config - Supports INSTALLER_HOSTNAME and INSTALLER_DISK env vars - Fix bootstrap-install.sh default branch to main - Update CLAUDE.md and server-installer-usb.md
This commit is contained in:
parent
2c9cf1e8b4
commit
d4dbd73a8c
7 changed files with 314 additions and 183 deletions
|
|
@ -1,13 +1,13 @@
|
|||
#!/bin/bash
|
||||
# Fetch with curl and run to install NixOS (clone + run nixos-server-install.sh).
|
||||
# On the live system, run only:
|
||||
# curl -sL https://raw.githubusercontent.com/DannyDannyDanny/dotfiles/server-installer-usb/scripts/bootstrap-install.sh | sudo bash
|
||||
# curl -sL https://raw.githubusercontent.com/DannyDannyDanny/dotfiles/main/scripts/bootstrap-install.sh | sudo bash
|
||||
#
|
||||
# Optional: REPO_URL=... BRANCH=... (default repo and server-installer-usb)
|
||||
set -euo pipefail
|
||||
|
||||
REPO_URL="${REPO_URL:-https://github.com/DannyDannyDanny/dotfiles.git}"
|
||||
BRANCH="${BRANCH:-server-installer-usb}"
|
||||
BRANCH="${BRANCH:-main}"
|
||||
DEST="/tmp/dotfiles"
|
||||
INSTALL_SCRIPT="$DEST/scripts/nixos-server-install.sh"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
#!/bin/bash
|
||||
# Run on a NixOS minimal live system (or installer ISO) to install NixOS with
|
||||
# disko (LUKS + root). Prompts for hostname and target disk; optionally use
|
||||
# INSTALLER_SYSTEM_CONFIG_FILE for WiFi etc.
|
||||
# Install NixOS with disko (LUKS + root) on a live system.
|
||||
# Prompts for hostname and target disk, then provisions the installed system
|
||||
# (clones dotfiles, installs SSH key, generates hardware config).
|
||||
#
|
||||
# Usage (from repo root, e.g. /tmp/dotfiles):
|
||||
# sudo ./scripts/nixos-server-install.sh
|
||||
# If you see "command not found", use: sudo bash ./scripts/nixos-server-install.sh
|
||||
#
|
||||
# Optional: FLAKE_REF=github:User/dotfiles or path:/path/to/dotfiles/nixos
|
||||
#
|
||||
# Optional: INSTALLER_SYSTEM_CONFIG_FILE=/path/to/json with full --system-config
|
||||
# (e.g. hostName + networking.wireless.networks). If unset, only hostname is passed.
|
||||
# Environment variables (all optional):
|
||||
# INSTALLER_HOSTNAME — skip hostname prompt
|
||||
# INSTALLER_DISK — skip disk prompt (validated as block device)
|
||||
# SSH_PUBKEY_FILE — path to .pub file; installed to danny's authorized_keys
|
||||
# FLAKE_REF — override flake reference (default: auto-detect from repo)
|
||||
# INSTALLER_SYSTEM_CONFIG_FILE — JSON file merged into --system-config
|
||||
set -euo pipefail
|
||||
|
||||
FLAKE_REF="${FLAKE_REF:-}"
|
||||
|
|
@ -30,21 +31,29 @@ if [[ "$EUID" -ne 0 ]]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
read -r -p "Hostname (e.g. my-server): " hostname
|
||||
# --- Hostname ---
|
||||
hostname="${INSTALLER_HOSTNAME:-}"
|
||||
if [[ -z "$hostname" ]]; then
|
||||
read -r -p "Hostname (e.g. phantom-ship): " hostname
|
||||
fi
|
||||
if [[ -z "$hostname" ]]; then
|
||||
echo "Hostname cannot be empty."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -r -p "Target disk [default: /dev/sda]: " disk
|
||||
disk="${disk:-/dev/sda}"
|
||||
# --- Target disk ---
|
||||
disk="${INSTALLER_DISK:-}"
|
||||
if [[ -z "$disk" ]]; then
|
||||
read -r -p "Target disk [default: /dev/sda]: " disk
|
||||
disk="${disk:-/dev/sda}"
|
||||
fi
|
||||
if [[ ! -b "$disk" ]]; then
|
||||
echo "Not a block device: $disk"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- System config (hostname + optional extras) ---
|
||||
if [[ -n "${INSTALLER_SYSTEM_CONFIG_FILE:-}" ]] && [[ -f "$INSTALLER_SYSTEM_CONFIG_FILE" ]]; then
|
||||
# Use provided JSON; ensure hostname is set
|
||||
if command -v jq &>/dev/null; then
|
||||
SYSTEM_CONFIG=$(jq --arg h "$hostname" '.networking.hostName = $h' "$INSTALLER_SYSTEM_CONFIG_FILE")
|
||||
else
|
||||
|
|
@ -55,8 +64,9 @@ else
|
|||
SYSTEM_CONFIG='{"networking":{"hostName":"'"$hostname"'"}}'
|
||||
fi
|
||||
|
||||
# Prompt for password for danny so you can log in at console after reboot (no rescue needed)
|
||||
read -r -p "Set a password for user danny (console/SSH login)? [y/N] " set_pass
|
||||
# --- Optional: danny password ---
|
||||
danny_pass=""
|
||||
read -r -p "Set a password for user danny? [y/N] " set_pass
|
||||
if [[ "${set_pass,,}" == "y" || "${set_pass,,}" == "yes" ]]; then
|
||||
read -s -r -p "Password for danny: " danny_pass
|
||||
echo
|
||||
|
|
@ -70,23 +80,27 @@ if [[ "${set_pass,,}" == "y" || "${set_pass,,}" == "yes" ]]; then
|
|||
echo "Password cannot be empty. Aborted."
|
||||
exit 1
|
||||
fi
|
||||
HASH=$(echo -n "$danny_pass" | openssl passwd -6 -stdin 2>/dev/null) || HASH=$(mkpasswd -6 -m sha-512 "$danny_pass" 2>/dev/null)
|
||||
if [[ -z "$HASH" ]]; then
|
||||
echo "Could not hash password (need openssl or mkpasswd). Skipping password."
|
||||
else
|
||||
HASH=$(echo -n "$danny_pass" | openssl passwd -6 -stdin 2>/dev/null) || HASH=$(mkpasswd -6 -m sha-512 "$danny_pass" 2>/dev/null) || true
|
||||
if [[ -n "${HASH:-}" ]]; then
|
||||
if command -v jq &>/dev/null; then
|
||||
SYSTEM_CONFIG=$(echo "$SYSTEM_CONFIG" | jq --arg h "$HASH" '. + {"users":{"users":{"danny":{"hashedPassword":$h}}}}')
|
||||
else
|
||||
NEW_CONFIG=$(echo "$SYSTEM_CONFIG" | nix run nixpkgs#jq -- --arg h "$HASH" '. + {"users":{"users":{"danny":{"hashedPassword":$h}}}}' 2>/dev/null)
|
||||
[[ -n "$NEW_CONFIG" ]] && SYSTEM_CONFIG="$NEW_CONFIG" || echo "Could not merge password (jq not found). Set after boot: passwd danny"
|
||||
[[ -n "$NEW_CONFIG" ]] && SYSTEM_CONFIG="$NEW_CONFIG" || echo "Could not merge password. Set after boot: passwd danny"
|
||||
fi
|
||||
[[ -n "$SYSTEM_CONFIG" ]] && echo "Password will be set for danny."
|
||||
echo "Password will be set for danny."
|
||||
else
|
||||
echo "Could not hash password (need openssl or mkpasswd). Set after boot: passwd danny"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Confirm and install ---
|
||||
echo ""
|
||||
echo "=== Install Summary ==="
|
||||
echo "Flake: ${FLAKE_REF}#server-install"
|
||||
echo "Disk: $disk"
|
||||
echo "Hostname: $hostname"
|
||||
echo "SSH pubkey: ${SSH_PUBKEY_FILE:-none}"
|
||||
echo "System config: $SYSTEM_CONFIG"
|
||||
read -r -p "Proceed? [y/N] " confirm
|
||||
if [[ "${confirm,,}" != "y" && "${confirm,,}" != "yes" ]]; then
|
||||
|
|
@ -100,33 +114,84 @@ nix run --extra-experimental-features "nix-command flakes" \
|
|||
--disk main "$disk" \
|
||||
--system-config "$SYSTEM_CONFIG"
|
||||
|
||||
# Set danny password directly on disk (Nix merge can fail); re-open LUKS and chroot
|
||||
if [[ -n "${danny_pass:-}" ]]; then
|
||||
echo "Setting password for danny on installed system (re-enter LUKS passphrase once)..."
|
||||
read -s -r -p "LUKS passphrase: " luks_pass
|
||||
echo
|
||||
LUKS_DEV="/dev/disk/by-partlabel/disk-main-luks"
|
||||
ESP_DEV="/dev/disk/by-partlabel/disk-main-ESP"
|
||||
if [[ ! -b "$LUKS_DEV" ]]; then
|
||||
LUKS_DEV="${disk}2"
|
||||
ESP_DEV="${disk}1"
|
||||
fi
|
||||
if [[ -b "$LUKS_DEV" ]]; then
|
||||
if ! echo -n "$luks_pass" | cryptsetup open "$LUKS_DEV" crypted --key-file -; then
|
||||
echo "Wrong LUKS passphrase; set danny password after boot: passwd danny"
|
||||
else
|
||||
mount /dev/mapper/crypted /mnt
|
||||
[[ -b "$ESP_DEV" ]] && mount "$ESP_DEV" /mnt/boot
|
||||
mount --bind /dev /mnt/dev
|
||||
mount --bind /proc /mnt/proc
|
||||
mount --bind /sys /mnt/sys
|
||||
echo "danny:${danny_pass}" | chroot /mnt chpasswd
|
||||
umount -R /mnt
|
||||
cryptsetup close crypted
|
||||
echo "Password for danny set. Reboot and log in."
|
||||
fi
|
||||
unset luks_pass
|
||||
else
|
||||
echo "Could not find LUKS partition; set password after boot: passwd danny"
|
||||
fi
|
||||
echo ""
|
||||
echo "=== Post-install provisioning ==="
|
||||
echo "Re-opening LUKS to provision the installed system..."
|
||||
read -s -r -p "LUKS passphrase: " luks_pass
|
||||
echo
|
||||
|
||||
LUKS_DEV="/dev/disk/by-partlabel/disk-main-luks"
|
||||
ESP_DEV="/dev/disk/by-partlabel/disk-main-ESP"
|
||||
if [[ ! -b "$LUKS_DEV" ]]; then
|
||||
LUKS_DEV="${disk}2"
|
||||
ESP_DEV="${disk}1"
|
||||
fi
|
||||
|
||||
if [[ ! -b "$LUKS_DEV" ]]; then
|
||||
echo "Could not find LUKS partition. Complete these steps manually after boot:"
|
||||
echo " 1. Clone dotfiles: sudo git clone ... /etc/dotfiles"
|
||||
echo " 2. Add SSH key: mkdir -p ~/.ssh && cat /tmp/key.pub >> ~/.ssh/authorized_keys"
|
||||
echo " 3. Generate hardware config: nixos-generate-config --show-hardware-config > /etc/dotfiles/nixos/hosts/${hostname}-hardware.nix"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! echo -n "$luks_pass" | cryptsetup open "$LUKS_DEV" crypted --key-file -; then
|
||||
echo "Wrong LUKS passphrase. Complete provisioning manually after boot."
|
||||
unset luks_pass
|
||||
exit 0
|
||||
fi
|
||||
unset luks_pass
|
||||
|
||||
mount /dev/mapper/crypted /mnt
|
||||
[[ -b "$ESP_DEV" ]] && mount "$ESP_DEV" /mnt/boot
|
||||
mount --bind /dev /mnt/dev
|
||||
mount --bind /proc /mnt/proc
|
||||
mount --bind /sys /mnt/sys
|
||||
|
||||
# 1. Set danny password (belt-and-suspenders; Nix merge can fail)
|
||||
if [[ -n "$danny_pass" ]]; then
|
||||
echo "danny:${danny_pass}" | chroot /mnt chpasswd
|
||||
echo " [ok] danny password set"
|
||||
fi
|
||||
unset danny_pass
|
||||
|
||||
# 2. Clone dotfiles
|
||||
if [[ ! -d /mnt/etc/dotfiles ]]; then
|
||||
chroot /mnt nix run --extra-experimental-features "nix-command flakes" nixpkgs#git -- \
|
||||
clone https://github.com/DannyDannyDanny/dotfiles.git /etc/dotfiles
|
||||
echo " [ok] dotfiles cloned to /etc/dotfiles"
|
||||
else
|
||||
echo " [skip] /etc/dotfiles already exists"
|
||||
fi
|
||||
|
||||
# 3. Install SSH public key
|
||||
if [[ -n "${SSH_PUBKEY_FILE:-}" ]] && [[ -f "$SSH_PUBKEY_FILE" ]]; then
|
||||
mkdir -p /mnt/home/danny/.ssh
|
||||
cat "$SSH_PUBKEY_FILE" >> /mnt/home/danny/.ssh/authorized_keys
|
||||
chmod 700 /mnt/home/danny/.ssh
|
||||
chmod 600 /mnt/home/danny/.ssh/authorized_keys
|
||||
chroot /mnt chown -R danny:users /home/danny/.ssh
|
||||
echo " [ok] SSH public key installed"
|
||||
elif [[ -n "${SSH_PUBKEY_FILE:-}" ]]; then
|
||||
echo " [warn] SSH_PUBKEY_FILE set but file not found: $SSH_PUBKEY_FILE"
|
||||
fi
|
||||
|
||||
# 4. Generate hardware config
|
||||
HW_CONFIG="/mnt/etc/dotfiles/nixos/hosts/${hostname}-hardware.nix"
|
||||
if nixos-generate-config --show-hardware-config --root /mnt > "$HW_CONFIG" 2>/dev/null; then
|
||||
echo " [ok] hardware config saved to hosts/${hostname}-hardware.nix"
|
||||
echo " NOTE: Commit this file to the repo after first boot."
|
||||
else
|
||||
echo " [warn] nixos-generate-config failed; run manually after boot:"
|
||||
echo " nixos-generate-config --show-hardware-config > /etc/dotfiles/nixos/hosts/${hostname}-hardware.nix"
|
||||
fi
|
||||
|
||||
umount -R /mnt
|
||||
cryptsetup close crypted
|
||||
|
||||
echo ""
|
||||
echo "=== Done! ==="
|
||||
echo "Remove the USB and reboot. After unlocking LUKS:"
|
||||
echo " 1. SSH in: ssh danny@${hostname}"
|
||||
echo " 2. First rebuild: cd /etc/dotfiles/nixos && sudo nixos-rebuild switch --flake .#${hostname}"
|
||||
echo " 3. Commit ${hostname}-hardware.nix back to the repo"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue