#!/usr/bin/env bash # Gracefully shut down the lab's VMs without destroying anything — libvirt # domains, the network, and storage pools are left defined so ./start-lab.sh # can bring the lab back up later. Use ./teardown.sh instead to remove it all. # # Shuts down the PVE nodes first, then the storage VM last, so nothing is # still relying on its NFS/iSCSI when it disappears (mirrors the storage-first # order start-lab.sh uses on the way up). set -uo pipefail source "$(dirname "$0")/lab.env" sudo -v # prompt for the sudo password once, up front request_shutdown() { local name="$1" state state=$(sudo virsh domstate "$name" 2>/dev/null || echo "missing") case "$state" in "shut off") echo " $name already shut off" ;; missing) echo " $name is not defined in libvirt; skipping" ;; *) echo " sending ACPI shutdown to $name (state: $state)"; sudo virsh shutdown "$name" >/dev/null 2>&1 ;; esac } wait_shutoff() { local name="$1" tries=0 while true; do local state state=$(sudo virsh domstate "$name" 2>/dev/null || echo "missing") [[ "$state" == "shut off" || "$state" == "missing" ]] && { echo " $name is down"; return 0; } sleep 5 tries=$((tries+1)) if (( tries % 6 == 0 )); then echo " still waiting for $name to power off... (${tries}0s)"; fi if (( tries > 36 )); then return 1; fi # ~3 minutes done } force_off_if_needed() { local name="$1" if ! wait_shutoff "$name"; then echo " WARN: $name didn't shut down cleanly after 3m; forcing off" sudo virsh destroy "$name" >/dev/null 2>&1 || true fi } echo "==> Shutting down PVE nodes" request_shutdown "$PVE1_NAME" request_shutdown "$PVE2_NAME" echo "==> Waiting for PVE nodes to power off" force_off_if_needed "$PVE1_NAME" force_off_if_needed "$PVE2_NAME" echo "==> Shutting down storage VM (after the PVE nodes, so nothing still depends on its NFS/iSCSI)" request_shutdown "$STORE_NAME" echo "==> Waiting for $STORE_NAME to power off" force_off_if_needed "$STORE_NAME" echo echo "Lab stopped. VMs, network, and storage pools are still defined (nothing was destroyed)." echo "Run ./start-lab.sh to bring it back up."