diff --git a/bin/omarchy-iso-test-stop b/bin/omarchy-iso-test-stop new file mode 100755 index 0000000..7b9c7f0 --- /dev/null +++ b/bin/omarchy-iso-test-stop @@ -0,0 +1,101 @@ +#!/bin/bash +# +# Stop the VM a `omarchy-iso-test --keep-running` run left behind: graceful +# guest poweroff over SSH first, escalating to TERM then KILL. The base image +# is untouched either way; only the throwaway run overlay is affected. +# +# Usage: omarchy-iso-test-stop [--kill] [--port PORT] +# +# --kill Skip the graceful poweroff and kill the VM immediately +# --port PORT Host port forwarded to guest SSH (default 2222) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_DIR="$(dirname "$SCRIPT_DIR")" + +GUEST_USER="omarchy" +GUEST_PASSWORD="omarchy" +SSH_PORT=2222 +GRACEFUL=true + +while (($#)); do + case "$1" in + --kill) GRACEFUL=false ;; + --port) SSH_PORT="$2"; shift ;; + -h | --help) + sed -n '3,10p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//' + exit 0 + ;; + *) echo "Unknown option: $1" >&2; exit 1 ;; + esac + shift +done + +# The newest run dir whose qemu is still alive is the VM to stop. +PID="" +PIDFILE="" +while IFS= read -r candidate; do + pid=$(<"$candidate") + if kill -0 "$pid" 2>/dev/null; then + PID="$pid" + PIDFILE="$candidate" + break + fi +done < <(ls -t "$REPO_DIR"/test-runs/*/runs/*/qemu.pid 2>/dev/null) + +if [[ -z $PID ]]; then + echo "No running omarchy-iso-test VM found." >&2 + exit 1 +fi + +BASE_DIR="$(dirname "$(dirname "$(dirname "$PIDFILE")")")" +SSH_KEY="$BASE_DIR/id_ed25519" + +# A harness that is still driving this VM dies with it; make sure that is +# what the caller wants before pulling anything down. +if [[ -t 0 ]]; then + if pgrep -f "bin/omarchy-iso-test .*\.iso" >/dev/null; then + echo "Warning: an omarchy-iso-test run appears to be in progress." + fi + if ! gum confirm "Stop test VM (pid $PID, ${PIDFILE#$REPO_DIR/})?"; then + exit 0 + fi +fi + +echo "Stopping test VM (pid $PID, ${PIDFILE#$REPO_DIR/})" + +if $GRACEFUL && [[ -f $SSH_KEY ]]; then + ssh -i "$SSH_KEY" -p "$SSH_PORT" \ + -o BatchMode=yes \ + -o IdentitiesOnly=yes \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + -o ConnectTimeout=5 \ + -o LogLevel=ERROR \ + "$GUEST_USER@127.0.0.1" \ + "echo $GUEST_PASSWORD | sudo -S systemctl poweroff" >/dev/null 2>&1 || true + + waited=0 + while kill -0 "$PID" 2>/dev/null && ((waited < 15)); do + sleep 1 + ((waited += 1)) + done +fi + +if kill -0 "$PID" 2>/dev/null; then + kill "$PID" 2>/dev/null || true + sleep 1 +fi + +if kill -0 "$PID" 2>/dev/null; then + kill -9 "$PID" 2>/dev/null || true + sleep 1 +fi + +if kill -0 "$PID" 2>/dev/null; then + echo "VM (pid $PID) refused to die." >&2 + exit 1 +fi + +echo "VM stopped; port $SSH_PORT is free."