#!/usr/bin/env bash # Copy scripts and config to a Proxmox VE host and run them via SSH (so they run on LAN and can reach NPMplus, etc.). # NPM_URL in .env must be reachable from the Proxmox host. NPMplus (VMID 10233) runs on r630-01; # use --host 192.168.11.11 if the default (ml110) cannot reach NPMplus at .166/.167:81. # # Usage: # bash scripts/run-via-proxmox-ssh.sh [wave0|npmplus|backup|copy|secure-keys|request-cert] [--dry-run] [--skip-backup] [--host HOST] # wave0 - Copy + run Wave 0 (RPC fix + backup) on Proxmox host (on LAN). # npmplus - Copy + run only update-npmplus-proxy-hosts-api.sh # backup - Copy + run only backup-npmplus.sh # copy - Copy extended set (wave0 + secure-validator-keys + create-missing-containers) to host; run nothing. # secure-keys - Copy + run secure-validator-keys.sh (default --dry-run; use --apply to run for real). # request-cert - Copy + run request-npmplus-certificates.sh (FIRST_ONLY=1) on host so NPMplus at .166/.167 is reachable. # validate - Copy + run shellcheck (full) on scripts/verify and genesis validation on smom-dbis-138. # bash scripts/run-via-proxmox-ssh.sh wave0 --host 192.168.11.11 # r630-01 (same host as NPMplus) # # Requires: SSH access to the Proxmox host. Remote host must have: bash, curl, jq (for npmplus/wave0). For validate: jq; shellcheck installable. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$PROJECT_ROOT" source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true [ -f "${PROJECT_ROOT}/.env" ] && set +u && source "${PROJECT_ROOT}/.env" 2>/dev/null; set -u # SSH user for shell access (use root). PROXMOX_USER in .env may be root@pam for API; that is not valid for SSH. REMOTE_USER="${REMOTE_SSH_USER:-${PROXMOX_USER:-root}}" # If REMOTE_USER contains @ (e.g. root@pam from .env), use root for SSH [[ "$REMOTE_USER" == *"@"* ]] && REMOTE_USER="root" REMOTE_DIR="${REMOTE_RUN_DIR:-/tmp/proxmox-scripts-run}" PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_ML110:-192.168.11.10}}" MODE="" DRY_RUN=false SKIP_BACKUP="" SECURE_KEYS_APPLY="--dry-run" while [[ $# -gt 0 ]]; do case "$1" in wave0|npmplus|backup|copy|secure-keys|request-cert|validate) MODE="$1" ;; --dry-run) DRY_RUN=true ;; --skip-backup) SKIP_BACKUP="--skip-backup" ;; --host) PROXMOX_HOST="${2:-$PROXMOX_HOST}"; shift ;; --apply) SECURE_KEYS_APPLY="" ;; *) ;; esac shift done if [[ -z "$MODE" ]]; then echo "Usage: $0 wave0|npmplus|backup|copy|secure-keys|request-cert|validate [--dry-run] [--skip-backup] [--host IP] [--apply (for secure-keys)]" echo " wave0 - Copy and run Wave 0 (NPMplus RPC fix + optional backup) on Proxmox host (on LAN)." echo " npmplus - Copy and run only update-npmplus-proxy-hosts-api.sh" echo " backup - Copy and run only backup-npmplus.sh" echo " copy - Copy extended set to host (wave0 + secure-validator-keys); run nothing." echo " secure-keys - Copy and run secure-validator-keys.sh (default --dry-run; use --apply to run for real)." echo " request-cert - Copy and run request-npmplus-certificates.sh (FIRST_ONLY=1) on host (LAN)." echo " validate - Copy and run shellcheck (full) on scripts/verify and genesis validation on smom-dbis-138." exit 1 fi log_info() { echo -e "\033[0;34m[INFO]\033[0m $1"; } log_ok() { echo -e "\033[0;32m[✓]\033[0m $1"; } log_warn() { echo -e "\033[0;33m[⚠]\033[0m $1"; } echo "" log_info "Run via Proxmox SSH: mode=$MODE host=${REMOTE_USER}@${PROXMOX_HOST} remote_dir=$REMOTE_DIR" echo "" # Files/dirs to copy (relative to PROJECT_ROOT). Structure must match so PROJECT_ROOT on remote = REMOTE_DIR. copy_always=( ".env" "config/ip-addresses.conf" ) copy_npmplus=( "scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh" ) copy_backup=( "scripts/verify/backup-npmplus.sh" ) copy_wave0=( "scripts/run-wave0-from-lan.sh" "scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh" "scripts/verify/backup-npmplus.sh" "scripts/secure-validator-keys.sh" ) copy_secure_keys=( "scripts/secure-validator-keys.sh" ) copy_extended=( "scripts/run-wave0-from-lan.sh" "scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh" "scripts/verify/backup-npmplus.sh" "scripts/secure-validator-keys.sh" "scripts/maintenance/schedule-npmplus-backup-cron.sh" "scripts/maintenance/schedule-daily-weekly-cron.sh" "scripts/maintenance/daily-weekly-checks.sh" ) # validate: scripts/verify/*.sh, smom-dbis-138 genesis script + config copy_validate=( "scripts/verify/run-shellcheck.sh" "smom-dbis-138/scripts/validation/validate-genesis.sh" "smom-dbis-138/config/genesis.json" ) do_copy() { local host="$1" local list_name="$2" log_info "Creating $REMOTE_DIR and copying files to ${REMOTE_USER}@${host}..." ssh -o ConnectTimeout=10 "${REMOTE_USER}@${host}" "mkdir -p $REMOTE_DIR/config $REMOTE_DIR/scripts/nginx-proxy-manager $REMOTE_DIR/scripts/verify $REMOTE_DIR/scripts/maintenance $REMOTE_DIR/smom-dbis-138/scripts/validation $REMOTE_DIR/smom-dbis-138/config" [ "$list_name" = "request-cert" ] && ssh -o ConnectTimeout=10 "${REMOTE_USER}@${host}" "mkdir -p $REMOTE_DIR/scripts" [ "$list_name" = "validate" ] && for f in "$PROJECT_ROOT"/scripts/verify/*.sh; do [ -f "$f" ] && scp -q -o ConnectTimeout=10 "$f" "${REMOTE_USER}@${host}:$REMOTE_DIR/scripts/verify/"; done [ "$list_name" = "validate" ] && for f in "${copy_validate[@]}"; do [ -f "$PROJECT_ROOT/$f" ] && scp -q -o ConnectTimeout=10 "$PROJECT_ROOT/$f" "${REMOTE_USER}@${host}:$REMOTE_DIR/$f"; done for f in "${copy_always[@]}"; do [ -f "$PROJECT_ROOT/$f" ] || continue scp -q -o ConnectTimeout=10 "$PROJECT_ROOT/$f" "${REMOTE_USER}@${host}:$REMOTE_DIR/$f" || { log_warn "Copy failed: $f"; return 1; } done case "$list_name" in wave0) for f in "${copy_wave0[@]}"; do [ -f "$PROJECT_ROOT/$f" ] && scp -q -o ConnectTimeout=10 "$PROJECT_ROOT/$f" "${REMOTE_USER}@${host}:$REMOTE_DIR/$f"; done ;; npmplus) for f in "${copy_npmplus[@]}"; do [ -f "$PROJECT_ROOT/$f" ] && scp -q -o ConnectTimeout=10 "$PROJECT_ROOT/$f" "${REMOTE_USER}@${host}:$REMOTE_DIR/$f"; done ;; backup) for f in "${copy_backup[@]}"; do [ -f "$PROJECT_ROOT/$f" ] && scp -q -o ConnectTimeout=10 "$PROJECT_ROOT/$f" "${REMOTE_USER}@${host}:$REMOTE_DIR/$f"; done ;; copy) for f in "${copy_extended[@]}"; do [ -f "$PROJECT_ROOT/$f" ] && scp -q -o ConnectTimeout=10 "$PROJECT_ROOT/$f" "${REMOTE_USER}@${host}:$REMOTE_DIR/$f"; done ;; secure-keys) for f in "${copy_secure_keys[@]}"; do [ -f "$PROJECT_ROOT/$f" ] && scp -q -o ConnectTimeout=10 "$PROJECT_ROOT/$f" "${REMOTE_USER}@${host}:$REMOTE_DIR/$f"; done ;; request-cert) [ -f "$PROJECT_ROOT/scripts/request-npmplus-certificates.sh" ] && scp -q -o ConnectTimeout=10 "$PROJECT_ROOT/scripts/request-npmplus-certificates.sh" "${REMOTE_USER}@${host}:$REMOTE_DIR/scripts/"; ;; validate) ;; # already copied above esac log_ok "Files copied." } run_remote() { local host="$1" local cmd="$2" log_info "Running on ${REMOTE_USER}@${host}: $cmd" ssh -o ConnectTimeout=10 "${REMOTE_USER}@${host}" "cd $REMOTE_DIR && $cmd" } if [[ "$DRY_RUN" == true ]]; then echo "[DRY-RUN] Would copy to ${REMOTE_USER}@${PROXMOX_HOST}:$REMOTE_DIR and run:" case "$MODE" in wave0) echo " bash scripts/run-wave0-from-lan.sh $SKIP_BACKUP" ;; npmplus) echo " bash scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh" ;; backup) echo " bash scripts/verify/backup-npmplus.sh" ;; copy) echo " (no run; then ssh and run e.g. bash scripts/run-wave0-from-lan.sh or bash scripts/secure-validator-keys.sh --dry-run)" ;; secure-keys) echo " bash scripts/secure-validator-keys.sh $SECURE_KEYS_APPLY" ;; request-cert) echo " FIRST_ONLY=1 bash scripts/request-npmplus-certificates.sh" ;; validate) echo " (install shellcheck if needed) bash scripts/verify/run-shellcheck.sh; cd smom-dbis-138 && bash scripts/validation/validate-genesis.sh" ;; esac exit 0 fi do_copy "$PROXMOX_HOST" "$MODE" case "$MODE" in wave0) run_remote "$PROXMOX_HOST" "bash scripts/run-wave0-from-lan.sh $SKIP_BACKUP" ;; npmplus) run_remote "$PROXMOX_HOST" "bash scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh" ;; backup) run_remote "$PROXMOX_HOST" "bash scripts/verify/backup-npmplus.sh" ;; copy) log_ok "Copy done. SSH and run from $REMOTE_DIR, e.g.:" echo " ssh ${REMOTE_USER}@${PROXMOX_HOST} 'cd $REMOTE_DIR && bash scripts/run-wave0-from-lan.sh'" echo " ssh ${REMOTE_USER}@${PROXMOX_HOST} 'cd $REMOTE_DIR && bash scripts/secure-validator-keys.sh --dry-run'" echo " ssh ${REMOTE_USER}@${PROXMOX_HOST} 'cd $REMOTE_DIR && bash scripts/maintenance/schedule-npmplus-backup-cron.sh --show'" ;; secure-keys) run_remote "$PROXMOX_HOST" "bash scripts/secure-validator-keys.sh $SECURE_KEYS_APPLY" ;; request-cert) # From Proxmox host use .167 so API is reachable (container often on .167; .166 can be unreachable from host) run_remote "$PROXMOX_HOST" "NPM_URL=https://192.168.11.167:81 FIRST_ONLY=1 bash scripts/request-npmplus-certificates.sh" ;; validate) run_remote "$PROXMOX_HOST" "command -v shellcheck >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y -qq shellcheck)" run_remote "$PROXMOX_HOST" "bash scripts/verify/run-shellcheck.sh" || log_warn "Shellcheck reported issues (see above); continuing to genesis validation." run_remote "$PROXMOX_HOST" "command -v jq >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y -qq jq)" run_remote "$PROXMOX_HOST" "cd smom-dbis-138 && bash scripts/validation/validate-genesis.sh" ;; esac log_ok "Done." echo ""