#!/usr/bin/env bash # Poll Proxmox hypervisor hardware (CPU/RAM/disk/NIC/pvesm) over SSH with key auth. # Also records cluster membership from the first reachable seed host. # # Usage: # bash scripts/verify/poll-proxmox-cluster-hardware.sh # OUT=/path/to/report.txt bash scripts/verify/poll-proxmox-cluster-hardware.sh # # Requires: ping, ssh (BatchMode / keys to root@hosts), optional cluster read via SEED_HOST. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # shellcheck source=/dev/null source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true SEED_HOST="${SEED_HOST:-${PROXMOX_HOST_R630_01:-192.168.11.11}}" HOSTS=( "${PROXMOX_HOST_ML110:-192.168.11.10}" "${PROXMOX_HOST_R630_01:-192.168.11.11}" "${PROXMOX_HOST_R630_02:-192.168.11.12}" "${PROXMOX_HOST_R630_03:-192.168.11.13}" "${PROXMOX_HOST_R630_04:-192.168.11.14}" ) TS="$(date +%Y%m%d_%H%M%S)" OUT="${OUT:-${PROJECT_ROOT}/reports/status/hardware_poll_${TS}.txt}" mkdir -p "$(dirname "$OUT")" REMOTE_BODY=$(cat <<'EOS' echo "=== HOST === $(hostname -f 2>/dev/null || hostname)" echo "=== DMI ===" if command -v dmidecode >/dev/null 2>&1; then printf '%s | %s | SN:%s\n' \ "$(dmidecode -s system-manufacturer 2>/dev/null)" \ "$(dmidecode -s system-product-name 2>/dev/null)" \ "$(dmidecode -s system-serial-number 2>/dev/null)" fi echo "=== CPU ===" lscpu 2>/dev/null | grep -E '^(Architecture|CPU op-mode|Model name|Socket|Core|Thread|CPU\\(s\\)|CPU max MHz|CPU min MHz)' || true echo "=== RAM ===" free -h echo "=== DISKS ===" lsblk -d -o NAME,SIZE,TYPE,MODEL,ROTA,SERIAL 2>/dev/null || true echo "=== PVE ===" pveversion -v 2>/dev/null | head -3 || echo "not pve" echo "=== pvesm ===" pvesm status 2>/dev/null || true echo "=== NIC PCI ===" lspci -nn 2>/dev/null | grep -iE 'ethernet|network' || true echo "=== vmbr0 addr ===" ip -br addr show vmbr0 2>/dev/null || true EOS ) { echo "hardware_poll $(date -Is)" echo "SSH BatchMode=yes root@HOST" echo "========================================" echo "" echo "=== Cluster (from seed ${SEED_HOST}) ===" if ping -c1 -W1 "${SEED_HOST}" >/dev/null 2>&1; then ssh -o BatchMode=yes -o ConnectTimeout=10 -o StrictHostKeyChecking=no \ "root@${SEED_HOST}" "pvecm status 2>/dev/null; echo '---'; pvecm nodes 2>/dev/null; echo '---'; grep ring0_addr /etc/pve/corosync.conf 2>/dev/null" \ || echo "(cluster query failed)" else echo "(seed unreachable)" fi echo "" for ip in "${HOSTS[@]}"; do echo "" echo "########################################" echo "# ${ip}" echo "########################################" if ! ping -c1 -W1 "${ip}" >/dev/null 2>&1; then echo "(no ping)" continue fi if ! ssh -o BatchMode=yes -o ConnectTimeout=12 -o StrictHostKeyChecking=no \ "root@${ip}" "bash -lc $(printf '%q' "$REMOTE_BODY")" 2>/dev/null; then echo "(SSH failed — keys or root login)" fi done } | tee "${OUT}" echo "" echo "Wrote: ${OUT}"