From 7093a338f4bff3d23320c56c84e1ef7fd95caead Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Thu, 12 Jun 2025 17:37:01 +0800 Subject: [PATCH] feat(packages/deploy): add deployment script --- README.md | 12 +++ homes/x86_64-linux/rafiq/default.nix | 1 + packages/deploy/default.nix | 123 +++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 packages/deploy/default.nix diff --git a/README.md b/README.md index 0e7a183..d42a44f 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,10 @@ - Federation with ActivityPub - Wakapi - Add a way to define services per host and refer to them by hostname + - helios as file and db server, apollo as services and reverse proxy - 0.3.0 - Integration tests for all services + - Set directory permissions properly for impermanence - Easier way to add proxyPass, web server independent - Migrate services from helios @@ -49,6 +51,16 @@ The following files are **required** for system activation: This private key will be used by sops-nix to decrypt the secrets in [this encrypted file](secrets/secrets.yaml). The secrets inside the yaml file should also be set, or otherwise removed alongside their declarations , found [here](modules/nixos/system/secrets.nix) and references. +```bash +# On the target machine +# Boot into the NixOS installer + +sudo passwd + +# On the host machine +deploy --user "rafiq" --ip "10.10.0.102" --hostname "apollo" +``` + # Impermanence System and user state is stored under /persist. Anything not declared under diff --git a/homes/x86_64-linux/rafiq/default.nix b/homes/x86_64-linux/rafiq/default.nix index 9337801..cb09374 100644 --- a/homes/x86_64-linux/rafiq/default.nix +++ b/homes/x86_64-linux/rafiq/default.nix @@ -61,6 +61,7 @@ in stremio tor-browser pantheon.rebuild + pantheon.deploy pantheon.edit inputs.nixspect.packages."x86_64-linux".nixspect ]; diff --git a/packages/deploy/default.nix b/packages/deploy/default.nix new file mode 100644 index 0000000..f9280e8 --- /dev/null +++ b/packages/deploy/default.nix @@ -0,0 +1,123 @@ +{ pkgs, ... }: +pkgs.writeShellScriptBin "deploy" # sh + '' + while [[ $# -gt 0 ]]; do + case "$1" in + --user) + USER="$2" + shift 2 + ;; + --ip) + IP="$2" + shift 2 + ;; + --hostname) + HOSTNAME="$2" + shift 2 + ;; + *) + echo "Error: Unknown parameter: $1" + exit 1 + ;; + esac + done + + # Check if required arguments are provided + if [[ -z "$USER" || -z "$IP" || -z "$HOSTNAME" ]]; then + echo "Usage: $0 --user --ip --hostname [--wait-timeout ]" + exit 1 + fi + + # --- Helper Functions --- + + wait_for_ping() { + local ip="$1" + + echo "Waiting for ping to $ip..." + while true; do + if ping -c 1 -W 1 "$ip"; then + echo "Ping successful." + return 0 + fi + sleep 2 + done + } + + wait_for_ssh() { + local ip="$1" + + echo "Waiting for SSH to $ip..." + while true; do + ssh-keygen -R "$ip" || true # Suppress error if key doesn't exist + if ssh -o StrictHostKeyChecking=no root@"$ip" exit; then + echo "SSH connection successful." + return 0 + fi + sleep 2 + done + } + + retry_rebuild() { + local ip="$1" + + echo "Attempting rebuild..." + while true; do + if nixos-rebuild switch --flake . --target-host root@"$ip"; then + echo "Rebuild successful." + return 0 + fi + sleep 2 + done + } + + test_connection() { + local ip="$1" + # Wait for the server to come back up after the reboot. Ping first. + if ! wait_for_ping $ip; then + echo "Error: Server did not respond to ping after reboot." + exit 1 + fi + + # Wait for SSH access after reboot + if ! wait_for_ssh $ip; then + echo "Error: SSH access not available after reboot." + exit 1 + fi + } + + # --- Deployment Steps --- + + test_connection "$IP" + + # Copy SSH key to remote server + ssh-copy-id -o StrictHostKeyChecking=no root@"$IP" || { echo "Error: Failed to copy SSH key."; exit 1; } + + # Deploy NixOS configuration using nixos-anywhere + nix run github:nix-community/nixos-anywhere -- \ + -i ~/.ssh/id_ed25519 --ssh-option StrictHostKeyChecking=no \ + --flake .#"$HOSTNAME" --target-host root@"$IP" || { echo "Error: nixos-anywhere failed."; exit 1; } + + test_connection "$IP" + + # Create SSH directory on the remote server (if not already present) + ssh root@"$IP" -o StrictHostKeyChecking=no mkdir -p "/persist/home/$USER/.ssh" || { echo "Error: Failed to create SSH directory."; exit 1; } + + # Set owner of the user's home directory + ssh root@"$IP" -o StrictHostKeyChecking=no chown -R "$USER:users" "/persist/home/$USER" || { echo "Error: Failed to set ownership."; exit 1; } + + # Copy SSH keys to the remote server + scp -r ~/.ssh root@"$IP":/persist/home/"$USER" || { echo "Error: Failed to copy SSH keys."; exit 1; } + + #TODO: remove device from tailscale + + # Build and switch the configuration + retry_rebuild "$IP" + + # Reboot the system + ssh root@"$IP" -o StrictHostKeyChecking=no systemctl reboot || { echo "Error: Failed to reboot."; exit 1; } + + test_connection "$IP" + test_connection "$HOSTNAME" + + echo "Deployment complete. System should be ready." + ''