#!/usr/bin/env bash # Unattended-install both PVE nodes from their auto ISOs, then wait until each # is reachable over SSH with the lab key. set -euo pipefail source "$(dirname "$0")/lab.env" sudo -v # prompt for the sudo password once, up front (the two installs run in parallel) install_node() { local name="$1" mac="$2" ip="$3" log="${BUILD_DIR}/install-${1}.log" local disk="${LIB_DIR}/${name}.qcow2" local iso="${LIB_DIR}/${name}-auto.iso" # Already installed and reachable? Leave it alone. if lab_ssh "$ip" true >/dev/null 2>&1; then echo " $name already up at $ip; skipping install" >&2 echo "SKIP" return fi if sudo virsh dominfo "$name" >/dev/null 2>&1; then echo " $name already defined; destroying + undefining first" >&2 sudo virsh destroy "$name" 2>/dev/null || true sudo virsh undefine "$name" --remove-all-storage --nvram 2>/dev/null || true fi echo " launching virt-install for $name (log: $log)" >&2 # --wait -1 blocks until the installer powers off (reboot-mode=power-off), # at which point virt-install redefines the domain to boot from disk. sudo virt-install \ --connect qemu:///system \ --name "$name" \ --memory "$NODE_RAM_MB" \ --vcpus "$NODE_VCPU" \ --cpu host-passthrough \ --machine q35 \ --osinfo detect=on,name=debian12 \ --disk "path=${disk},size=${NODE_DISK_GB},format=qcow2,bus=virtio" \ --cdrom "$iso" \ --network "network=${NET_NAME},mac=${mac},model=virtio" \ --graphics vnc,listen=127.0.0.1 \ --noautoconsole \ --wait -1 >"$log" 2>&1 & echo $! } echo "==> Installing both nodes in parallel" p1=$(install_node "$PVE1_NAME" "$PVE1_MAC" "$PVE1_IP") sleep 5 # small stagger so the shared storage pool is settled before the 2nd launch p2=$(install_node "$PVE2_NAME" "$PVE2_MAC" "$PVE2_IP") echo " virt-install PIDs: pve1=$p1 pve2=$p2" wait_ssh() { local ip="$1" name="$2" tries=0 echo "==> Waiting for $name ($ip) to come up over SSH (this takes several minutes)" while ! lab_ssh "$ip" true >/dev/null 2>&1; do sleep 10 tries=$((tries+1)) if (( tries % 6 == 0 )); then echo " still waiting for $name ... (${tries}0s)"; fi if (( tries > 180 )); then echo "ERROR: $name not reachable after 30m"; return 1; fi done echo " $name is up: $(lab_ssh "$ip" hostname)" } wait_ssh "$PVE1_IP" "$PVE1_NAME" wait_ssh "$PVE2_IP" "$PVE2_NAME" echo echo "Both nodes installed and reachable." echo " Web UI: https://${PVE1_IP}:8006 and https://${PVE2_IP}:8006 (root / \$ROOT_PASSWORD)" echo "Next: ./05-storage-vm.sh"