Adds /scripts/pct-run.sh that maps CT IDs to PVE nodes and runs pct exec directly. No hardcoded IPs — Proxmox is the source of truth. Updates infrastructure-control with CT access table using pct-run. Usage examples: pct-run 112 cat /etc/hostname # Tanko pct-run 114 grep LITELLM /etc/environment # Mumuni key check pct-run 116 docker ps # LiteLLM containers
97 lines
2.5 KiB
Bash
Executable File
97 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# pct-run — Run commands inside Proxmox CTs by CT ID only. No IPs needed.
|
|
# Usage: pct-run <CT_ID> [command...]
|
|
# If no command given, opens a shell.
|
|
#
|
|
# Source of truth: Proxmox pct config on each node.
|
|
# No hardcoded IPs. No prose contract drift.
|
|
|
|
set -euo pipefail
|
|
|
|
# ── CT ID → PVE Node mapping (maintained HERE, not in prose contracts) ──
|
|
declare -A CT_NODES=(
|
|
# amdpve (192.168.68.15)
|
|
[100]=amdpve # abiba
|
|
[105]=amdpve # kagentz
|
|
[111]=amdpve # tdunna
|
|
[112]=amdpve # tanko
|
|
[113]=amdpve # baggy/koonimo
|
|
[115]=amdpve # scottdenya
|
|
# minipve (192.168.68.12)
|
|
[104]=minipve # authentik
|
|
[110]=minipve # gitea
|
|
[114]=minipve # mumuni
|
|
[116]=minipve # syslog-api
|
|
# storepve (192.168.68.6)
|
|
[106]=storepve # ra-h-os
|
|
[107]=storepve # proxmox-backup
|
|
[108]=storepve # media
|
|
[117]=storepve # zulip
|
|
# acerpve (192.168.68.9)
|
|
[102]=acerpve # adguard
|
|
# ocupve (192.168.68.5) — no CTs (bare metal GPU .110)
|
|
)
|
|
|
|
# Each node must be root-accessible via SSH hostname
|
|
# (Ensure ~/.ssh/config or /etc/hosts has these resolvable)
|
|
|
|
# ── PVE node → IP (needed only because SSH needs an address) ──
|
|
declare -A NODE_IPS=(
|
|
[amdpve]=192.168.68.15
|
|
[minipve]=192.168.68.12
|
|
[storepve]=192.168.68.6
|
|
[acerpve]=192.168.68.9
|
|
[ocupve]=192.168.68.5
|
|
)
|
|
|
|
resolve_node() {
|
|
local ct_id="$1"
|
|
local node="${CT_NODES[$ct_id]:-}"
|
|
if [[ -z "$node" ]]; then
|
|
echo "ERROR: CT $ct_id not found in mapping" >&2
|
|
exit 1
|
|
fi
|
|
echo "$node"
|
|
}
|
|
|
|
node_ip() {
|
|
local node="$1"
|
|
local ip="${NODE_IPS[$node]:-}"
|
|
if [[ -z "$ip" ]]; then
|
|
echo "ERROR: Node $node not found in IP mapping" >&2
|
|
exit 1
|
|
fi
|
|
echo "$ip"
|
|
}
|
|
|
|
main() {
|
|
if [[ $# -lt 1 ]]; then
|
|
echo "Usage: pct-run <CT_ID> [command...]" >&2
|
|
echo " pct-run 112 cat /etc/hostname" >&2
|
|
echo " pct-run 114 systemctl status hermes-gateway" >&2
|
|
echo ""
|
|
echo "Known CTs:" >&2
|
|
for ct in $(echo "${!CT_NODES[@]}" | tr ' ' '\n' | sort -n); do
|
|
echo " CT $ct → ${CT_NODES[$ct]}" >&2
|
|
done
|
|
exit 1
|
|
fi
|
|
|
|
local ct_id="$1"
|
|
shift
|
|
local node
|
|
node=$(resolve_node "$ct_id")
|
|
local ip
|
|
ip=$(node_ip "$node")
|
|
|
|
if [[ $# -eq 0 ]]; then
|
|
# Interactive shell
|
|
exec ssh -t "root@${ip}" "pct enter ${ct_id}"
|
|
else
|
|
# One-shot command
|
|
ssh "root@${ip}" "pct exec ${ct_id} -- $*"
|
|
fi
|
|
}
|
|
|
|
main "$@"
|