#!/usr/bin/env bash set -Euo pipefail SCRIPT_DIR=$(dirname "$(readlink -f "$0")") PROJECT_ROOT=$(readlink -f "$SCRIPT_DIR/..") TARGET_DIR="/tmp/cloonar-config" SSH_PORT=2222 SSH_HOST="localhost" SSH_USER="root" SSH_PASS="linux" SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" ARCHIVE_PATH="/tmp/cloonar-config.tar.gz" # Parse command line options START_VM=0 KEEP_FILES=0 VERBOSE=0 NO_REBOOT=0 while [[ $# -gt 0 ]]; do case $1 in --start-vm) START_VM=1 shift ;; --keep-files) KEEP_FILES=1 shift ;; --verbose) VERBOSE=1 shift ;; --no-reboot) NO_REBOOT=1 shift ;; *) echo "Unknown option: $1" echo "Usage: $0 [--start-vm] [--keep-files] [--verbose] [--no-reboot]" exit 1 ;; esac done log() { echo "==> $1" } error() { echo "ERROR: $1" >&2 exit 1 } verbose() { if [[ $VERBOSE -eq 1 ]]; then echo "$1" fi } cleanup() { if [[ $KEEP_FILES -eq 0 ]]; then log "Cleaning up temporary files..." rm -f "$ARCHIVE_PATH" sshpass -p "$SSH_PASS" ssh $SSH_OPTIONS -p $SSH_PORT $SSH_USER@$SSH_HOST "rm -rf $TARGET_DIR" || true fi } trap cleanup EXIT # Check if VM is running by testing SSH connection check_vm_running() { sshpass -p "$SSH_PASS" ssh $SSH_OPTIONS -p $SSH_PORT $SSH_USER@$SSH_HOST "echo 2>/dev/null" >/dev/null } # Wait for SSH to become available wait_for_ssh() { local retries=60 local wait_time=2 log "Waiting for SSH connection..." while [[ $retries -gt 0 ]]; do if check_vm_running; then log "SSH connection established" return 0 fi verbose "Waiting... ($retries attempts remaining)" retries=$((retries - 1)) sleep $wait_time done return 1 } # Check if sshpass is installed if ! command -v sshpass >/dev/null; then error "sshpass is required but not installed. Please install it first." fi # Start VM if requested or not running if [[ $START_VM -eq 1 ]] || ! check_vm_running; then log "Starting VM..." "$SCRIPT_DIR/run-vm" >/dev/null 2>&1 || error "Failed to start VM" log "VM started, waiting 10 seconds for initial boot..." sleep 10 wait_for_ssh || error "Failed to establish SSH connection" fi # Create archive of project files log "Creating project archive..." cd "$PROJECT_ROOT" tar czf "$ARCHIVE_PATH" \ example/ \ modules/ \ .sops.yaml \ 2>/dev/null || true if [[ ! -f "$ARCHIVE_PATH" ]]; then error "Failed to create archive at $ARCHIVE_PATH" fi # Copy files to VM log "Copying files to VM..." sshpass -p "$SSH_PASS" ssh $SSH_OPTIONS -p $SSH_PORT $SSH_USER@$SSH_HOST "rm -rf $TARGET_DIR; mkdir -p $TARGET_DIR" || error "Failed to create target directory" sshpass -p "$SSH_PASS" scp $SSH_OPTIONS -P $SSH_PORT "$ARCHIVE_PATH" "$SSH_USER@$SSH_HOST:$TARGET_DIR/cloonar-config.tar.gz" || error "Failed to copy archive" # Extract files and build configuration log "Extracting files and building configuration..." sshpass -p "$SSH_PASS" ssh $SSH_OPTIONS -p $SSH_PORT $SSH_USER@$SSH_HOST "cd $TARGET_DIR && \ tar xzf cloonar-config.tar.gz && \ nixos-rebuild switch \ -I nixpkgs=\$(cat example/channel)/nixexprs.tar.xz \ -I nixos-config=$TARGET_DIR/example/configuration.nix" || error "Build failed" BUILD_EXIT=$? if [[ $BUILD_EXIT -eq 0 ]]; then log "Configuration built and activated successfully!" if [[ $NO_REBOOT -eq 0 ]]; then log "Rebooting VM..." sshpass -p "$SSH_PASS" ssh $SSH_OPTIONS -p $SSH_PORT $SSH_USER@$SSH_HOST "systemctl reboot" log "Waiting for VM to reboot..." sleep 30 wait_for_ssh || error "Failed to reconnect after reboot" log "VM is back online" fi else error "Build failed with exit code $BUILD_EXIT" fi if [[ $KEEP_FILES -eq 1 ]]; then log "Files kept in $TARGET_DIR on VM" fi