Files
proxmox/scripts/run-via-proxmox-ssh.sh
defiQUG b3a8fe4496
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
chore: sync all changes to Gitea
- Config, docs, scripts, and backup manifests
- Submodule refs unchanged (m = modified content in submodules)

Made-with: Cursor
2026-03-02 11:37:34 -08:00

188 lines
9.7 KiB
Bash

#!/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 ""