1
0
Files
pve-lab/stop-lab.sh
2026-09-22 23:13:44 -05:00

60 lines
2.1 KiB
Bash
Executable File

#!/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."