Files
praxis/scripts/proxmox/ct-exists.sh
T
Praxis CI bb17615f41 feat(P01): SLICE-03+04 — PVE API layer (8 scripts) + health-check
SLICE-03 (devops-engineer): ported from coreci/scripts/proxmox/:
  api.sh (verbatim), ct-exists.sh, lxc-clone.sh (4GB/16GB, hostname=praxis),
  lxc-config.sh (praxis env vars, praxis-firstboot.sh snippet), lxc-start.sh,
  stage-snippet.sh (G-101 FIX: bakes GITEA_TOKEN into snippet via sed),
  timing.sh (verbatim), rollback.sh (proxy code removed)
SLICE-04 (devops-engineer): health-check.sh adapted for /health:8789
  (G-104 FIX: timeout bumped 300s→600s for Docker build margin)

REQ-DEPLOY-03, 04, 05, 07, 08 covered.

---ci---
project: praxis
phase: 1
milestone: v0.2
status: execute
slice: 03-04
wave: 2
---/ci---
2026-08-01 14:18:23 +00:00

59 lines
2.6 KiB
Bash
Executable File

#!/bin/sh
# Praxis — CT existence + running-state helpers (P16 — deploy idempotency).
#
# Sourced by the deploy orchestrator (lxc-deploy.sh) to detect an
# existing CT before clone. Idempotent re-deploy:
# - healthy + running → skip clone/config/start (exit 0 / continue)
# - exists but unhealthy → error with guidance (--recreate / --reconfigure)
# - not exists → proceed with clone (current path)
#
# These helpers wrap pve_get against GET /nodes/{node}/lxc/{vmid}/status/current.
# A 404 (CT not found) returns HTTP non-200 → pve_get exits non-zero; the
# helpers translate that into the 0/1 return codes the orchestrators branch on.
# `set -eu` is NOT used here (the caller is set -eu; this file defines
# functions that intentionally swallow non-zero pve_get returns).
#
# Env: PROXMOX_API_URL, PROXMOX_API_TOKEN, PROXMOX_NODE (via api.sh)
# Functions:
# ct_exists <vmid> → 0 if the CT exists (200), 1 if not (404/other)
# ct_running <vmid> → 0 if the CT exists AND status == "running",
# 1 otherwise (not exists, or not running)
# ct_status <vmid> → echoes the raw status string (e.g. "running",
# "stopped") on stdout; empty if not exists
#
# Source this file AFTER api.sh:
# . "${SCRIPT_DIR}/ct-exists.sh"
# ct_exists <vmid> → 0 if the CT exists, 1 if not.
# Uses pve_get against /status/current; a non-200 (404) is "not found".
# Under `set -eu` in the caller, the `|| true` prevents an exit on the
# pve_get failure path.
ct_exists() {
vmid="$1"
node="${PROXMOX_NODE:?PROXMOX_NODE is required}"
status_json=$(pve_get "/nodes/${node}/lxc/${vmid}/status/current" 2>/dev/null || true)
[ -n "$status_json" ] && [ "$status_json" != "null" ]
}
# ct_running <vmid> → 0 if the CT exists AND status == "running", else 1.
ct_running() {
vmid="$1"
node="${PROXMOX_NODE:?PROXMOX_NODE is required}"
status_json=$(pve_get "/nodes/${node}/lxc/${vmid}/status/current" 2>/dev/null || true)
if [ -z "$status_json" ] || [ "$status_json" = "null" ]; then
return 1
fi
running=$(printf '%s' "$status_json" | jq -r '.status // empty' 2>/dev/null || true)
[ "$running" = "running" ]
}
# ct_status <vmid> → echoes the status string on stdout; empty if not exists.
ct_status() {
vmid="$1"
node="${PROXMOX_NODE:?PROXMOX_NODE is required}"
status_json=$(pve_get "/nodes/${node}/lxc/${vmid}/status/current" 2>/dev/null || true)
if [ -z "$status_json" ] || [ "$status_json" = "null" ]; then
return 0
fi
printf '%s' "$(printf '%s' "$status_json" | jq -r '.status // empty' 2>/dev/null || true)"
}