#!/bin/sh # Praxis — Rollback a failed LXC deployment. # # Stops (graceful, then force) and destroys the CT. Idempotent: # a 404 (CT already gone) is not an error. # # Praxis v0.2 has no proxy/traefik tier, so there is no backend-route # removal step here (unlike the coreci rollback which referenced # PROXY_VMID and proxy/backend-remove.sh). If a proxy tier is added in # a later slice, restore that step from coreci/scripts/proxmox/rollback.sh. # # Env: PROXMOX_API_URL, PROXMOX_API_TOKEN, PROXMOX_NODE # Args: $1 = VMID # Exit: 0 on success (including already-gone), 1 on failure set -eu SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # shellcheck source=api.sh disable=SC1091 . "${SCRIPT_DIR}/api.sh" pve_env PROXMOX_API_URL PROXMOX_API_TOKEN PROXMOX_NODE vmid="${1:?usage: rollback.sh }" node="${PROXMOX_NODE}" echo "rollback: cleaning up VMID ${vmid}" >&2 # Graceful shutdown shutdown_path="/nodes/${node}/lxc/${vmid}/status/shutdown" upid=$(pve_curl POST "$shutdown_path" "timeoutStop=30" 2>/dev/null || true) if [ -n "$upid" ] && [ "$upid" != "null" ]; then pve_poll "$upid" 2>/dev/null || true fi # Check if still running; force stop if so status=$(pve_get "/nodes/${node}/lxc/${vmid}/status/current" 2>/dev/null || true) if [ -n "$status" ] && [ "$status" != "null" ]; then running=$(printf '%s' "$status" | jq -r '.status' 2>/dev/null || true) if [ "$running" = "running" ]; then echo "rollback: force-stopping VMID ${vmid}" >&2 stop_path="/nodes/${node}/lxc/${vmid}/status/stop" upid=$(pve_curl POST "$stop_path" 2>/dev/null || true) if [ -n "$upid" ] && [ "$upid" != "null" ]; then pve_poll "$upid" 2>/dev/null || true fi fi fi # Destroy (idempotent — 404 is fine) echo "rollback: destroying VMID ${vmid}" >&2 destroy_path="/nodes/${node}/lxc/${vmid}" upid=$(pve_curl DELETE "$destroy_path" 2>/dev/null || true) if [ -n "$upid" ] && [ "$upid" != "null" ]; then pve_poll "$upid" 2>/dev/null || true fi echo "rollback: VMID ${vmid} cleaned up" >&2