#!/usr/bin/env bash # Start specific stopped LXC containers on ONE Proxmox host — scoped, production-safe. # Default: dry-run only. No host-wide "start everything" without explicit VMIDs. # # Usage: # ./scripts/operator/start-stopped-lxc-scoped.sh --host 192.168.11.13 --vmid 2400 --vmid 2402 # ./scripts/operator/start-stopped-lxc-scoped.sh --host 192.168.11.13 --vmid 2400 --apply # # Env (optional): # PROXMOX_OPS_APPLY=1 Same as --apply # PROXMOX_OPS_ALLOWED_VMIDS="2400,2402" Refuse any --vmid not in this set # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # shellcheck source=../lib/proxmox-production-guard.sh source "$SCRIPT_DIR/../lib/proxmox-production-guard.sh" SSH_OPTS=( -o BatchMode=yes -o ConnectTimeout=20 -o StrictHostKeyChecking=no ) SSH_USER="${PROXMOX_SSH_USER:-root}" HOST="" declare -a VMIDS=() APPLY=false usage() { sed -n '1,20p' "$0" | tail -n +2 echo "" echo "Options:" echo " --host IP|NAME Required. Single Proxmox node (no multi-host sweep)." echo " --vmid N Required (repeatable). Only these CTs are considered." echo " --apply Actually run pct start (otherwise print plan only)." echo " -h, --help" exit "${1:-0}" } while [[ $# -gt 0 ]]; do case "$1" in --host) HOST="${2:?}"; shift 2 ;; --vmid) VMIDS+=("${2:?}"); shift 2 ;; --apply) APPLY=true; shift ;; -h|--help) usage 0 ;; *) echo "Unknown arg: $1" >&2; usage 1 ;; esac done [[ -n "$HOST" ]] || { echo "ERROR: --host required" >&2; usage 1; } [[ "${#VMIDS[@]}" -gt 0 ]] || { echo "ERROR: at least one --vmid required (refusing host-wide start-all)" >&2; usage 1; } if ! pguard_require_apply_flag "$APPLY"; then MODE="DRY-RUN" else MODE="APPLY" export PROXMOX_OPS_APPLY=1 fi echo "=== start-stopped-lxc-scoped ($MODE) ===" echo " host=$HOST user=$SSH_USER" echo " vmids=${VMIDS[*]}" for vmid in "${VMIDS[@]}"; do pguard_vmid_allowed "$vmid" || exit 2 done run_ssh() { ssh "${SSH_OPTS[@]}" "${SSH_USER}@${HOST}" "$@"; } for vmid in "${VMIDS[@]}"; do st="$(run_ssh "pct status $vmid 2>/dev/null | awk '/^status:/{print \$2}'" || echo "unknown")" echo " VMID $vmid status: ${st:-unknown}" if [[ "$st" != "stopped" ]]; then echo " skip (not stopped)" continue fi if [[ "$MODE" == "DRY-RUN" ]]; then echo " [DRY-RUN] would: pct start $vmid" continue fi run_ssh "pct start $vmid" && echo " ok: pct start $vmid" || echo " FAIL: pct start $vmid" >&2 done if [[ "$MODE" == "DRY-RUN" ]]; then echo "" echo "No changes made. Re-run with --apply or PROXMOX_OPS_APPLY=1 to execute." fi