mirror of
https://github.com/GoodOlClint/PSProxmoxVE.git
synced 2026-09-03 18:55:33 +00:00
08ee3ae249
The local dev environment had drifted badly from CI. Remove the parts that no longer describe anything real, and make the rest match how CI actually runs. Delete tests/dev.ps1. It wrapped run-integration.sh, which CI calls directly, and duplicated the module build that script already performs internally. As a second entry point it drifted: it still offered the PVE 8 leg retired in #88, mounted the Docker socket for storage containers replaced by the storage VM in #87, and pointed its remote-host examples at a runner decommissioned in the ARC migration. All four documents describing it used a positional syntax that bound the bare word to -Tests and then fell through to -Shell, so every documented command silently opened a container shell. Recorded as D019. Delete tests/infrastructure/runner/, a self-hosted-runner-in-Docker superseded by Actions Runner Controller. Make disk_storage and iso_storage required. Their defaults named a NAS that the lab replaced with Ceph, and CI overrides both from repository variables, so the defaults only ever misled local runs. require_env now fails at the top of a run rather than at terraform apply, and the descriptions point at tests/.env.test because cmd_provision deletes terraform.tfvars before applying. preflight-cleanup.sh no longer falls back to the literal "local" storage. An unset TF_VAR_iso_storage now skips only the ISO branch, leaving VM destroy and state cleanup intact, and emits a workflow annotation: force-cleanup is the only cleanup CI runs and it wipes Terraform state, so a silent skip strands the uploaded ISO with nothing left to reclaim it. Drop docker-ce-cli and the /var/run/docker.sock mount. Nothing in the container has called docker since #87 moved storage into a VM; the remaining docker calls run inside that VM over SSH. The CI job image is built from the same target, so this also removes a third-party apt repository from its supply chain. Rewrite tests/.env.test.example against what the code now requires, and fix the documented commands in CLAUDE.md, README.md, copilot-instructions.md and the integration README.
105 lines
4.2 KiB
Bash
Executable File
105 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Pre-flight cleanup for CI runs.
|
|
# Ensures no leftover resources from a previous failed run before starting fresh.
|
|
#
|
|
# Usage: preflight-cleanup.sh <pve-endpoint> <api-token> <vm-id> <iso-filename> <terraform-dir>
|
|
set -uo pipefail
|
|
# Note: not using -e — we want to attempt all cleanup steps even if some fail
|
|
|
|
PVE_ENDPOINT="${1%/}"
|
|
API_TOKEN="$2"
|
|
VM_ID="$3"
|
|
ISO_FILENAME="$4"
|
|
TF_DIR="$5"
|
|
API_BASE="${PVE_ENDPOINT}/api2/json"
|
|
|
|
# Node: PVE_TARGET_NODE when set (a pool-scoped token cannot list /nodes), else the first node.
|
|
NODE="${PVE_TARGET_NODE:-}"
|
|
if [ -z "$NODE" ]; then
|
|
NODES_JSON=$(curl -sk -H "Authorization: PVEAPIToken=${API_TOKEN}" "${API_BASE}/nodes" 2>/dev/null)
|
|
NODE=$(echo "$NODES_JSON" | python3 -c "import json,sys; print(json.load(sys.stdin)['data'][0]['node'])" 2>/dev/null || echo "pve")
|
|
fi
|
|
ISO_STORAGE="${TF_VAR_iso_storage:-}"
|
|
|
|
echo "=== Pre-flight cleanup (node: ${NODE}, vmid: ${VM_ID}) ==="
|
|
|
|
# --- Clean up orphaned VM ---
|
|
VM_STATUS=$(curl -sk -H "Authorization: PVEAPIToken=${API_TOKEN}" \
|
|
"${API_BASE}/nodes/${NODE}/qemu/${VM_ID}/status/current" 2>/dev/null \
|
|
| python3 -c "import json,sys; print(json.load(sys.stdin).get('data',{}).get('status',''))" 2>/dev/null || true)
|
|
|
|
if [ -n "$VM_STATUS" ]; then
|
|
echo "Found orphaned VM ${VM_ID} (status: ${VM_STATUS})"
|
|
if [ "$VM_STATUS" = "running" ]; then
|
|
echo " Stopping VM..."
|
|
curl -sk -X POST -H "Authorization: PVEAPIToken=${API_TOKEN}" \
|
|
"${API_BASE}/nodes/${NODE}/qemu/${VM_ID}/status/stop" >/dev/null 2>&1
|
|
# Wait for stop
|
|
for i in $(seq 1 12); do
|
|
sleep 5
|
|
S=$(curl -sk -H "Authorization: PVEAPIToken=${API_TOKEN}" \
|
|
"${API_BASE}/nodes/${NODE}/qemu/${VM_ID}/status/current" 2>/dev/null \
|
|
| python3 -c "import json,sys; print(json.load(sys.stdin).get('data',{}).get('status',''))" 2>/dev/null || true)
|
|
if [ "$S" = "stopped" ]; then break; fi
|
|
done
|
|
fi
|
|
echo " Deleting VM..."
|
|
curl -sk -X DELETE -H "Authorization: PVEAPIToken=${API_TOKEN}" \
|
|
"${API_BASE}/nodes/${NODE}/qemu/${VM_ID}?destroy-unreferenced-disks=1&purge=1" >/dev/null 2>&1
|
|
sleep 3
|
|
echo " VM cleanup done"
|
|
else
|
|
echo "No orphaned VM ${VM_ID} found"
|
|
fi
|
|
|
|
# --- Clean up orphaned ISO ---
|
|
if [ -z "$ISO_FILENAME" ]; then
|
|
echo "No ISO filename specified, skipping ISO cleanup"
|
|
elif [ -z "$ISO_STORAGE" ]; then
|
|
# force-cleanup is the only cleanup CI runs and it wipes Terraform state, so a
|
|
# skipped ISO delete here strands the upload with nothing left to reclaim it.
|
|
if [ "${GITHUB_ACTIONS:-}" = "true" ]; then
|
|
echo "::warning::TF_VAR_iso_storage is unset — ISO cleanup skipped; the uploaded auto-install ISO is stranded"
|
|
fi
|
|
echo "WARNING: TF_VAR_iso_storage is unset — skipping ISO cleanup rather than guessing a storage pool"
|
|
else
|
|
ISO_EXISTS=$(curl -sk -H "Authorization: PVEAPIToken=${API_TOKEN}" \
|
|
"${API_BASE}/nodes/${NODE}/storage/${ISO_STORAGE}/content" 2>/dev/null \
|
|
| python3 -c "
|
|
import json, sys
|
|
data = json.load(sys.stdin).get('data', [])
|
|
for item in data:
|
|
if item.get('volid', '').endswith('/${ISO_FILENAME}'):
|
|
print(item['volid'])
|
|
break
|
|
" 2>/dev/null || true)
|
|
|
|
if [ -n "$ISO_EXISTS" ]; then
|
|
echo "Found orphaned ISO: ${ISO_EXISTS}"
|
|
echo " Deleting..."
|
|
ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${ISO_EXISTS}', safe=''))")
|
|
curl -sk -X DELETE -H "Authorization: PVEAPIToken=${API_TOKEN}" \
|
|
"${API_BASE}/nodes/${NODE}/storage/${ISO_STORAGE}/content/${ENCODED}" >/dev/null 2>&1
|
|
sleep 2
|
|
echo " ISO cleanup done"
|
|
else
|
|
echo "No orphaned ISO found"
|
|
fi
|
|
fi # end ISO_FILENAME check
|
|
|
|
# --- Clean up stale Terraform state ---
|
|
if [ -d "$TF_DIR" ]; then
|
|
if [ -f "${TF_DIR}/.terraform.tfstate.lock.info" ]; then
|
|
echo "Found stale Terraform lock, removing..."
|
|
rm -f "${TF_DIR}/.terraform.tfstate.lock.info"
|
|
fi
|
|
if [ -f "${TF_DIR}/terraform.tfstate" ]; then
|
|
echo "Found stale Terraform state, removing..."
|
|
rm -f "${TF_DIR}/terraform.tfstate" "${TF_DIR}/terraform.tfstate.backup"
|
|
fi
|
|
else
|
|
echo "Terraform dir not found (clean checkout)"
|
|
fi
|
|
|
|
echo "=== Pre-flight cleanup complete ==="
|