2026-02-12 15:46:57 -08:00
#!/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.
2026-03-02 11:37:34 -08:00
# validate - Copy + run shellcheck (full) on scripts/verify and genesis validation on smom-dbis-138.
2026-02-12 15:46:57 -08:00
# bash scripts/run-via-proxmox-ssh.sh wave0 --host 192.168.11.11 # r630-01 (same host as NPMplus)
#
2026-03-02 11:37:34 -08:00
# Requires: SSH access to the Proxmox host. Remote host must have: bash, curl, jq (for npmplus/wave0). For validate: jq; shellcheck installable.
2026-02-12 15:46:57 -08:00
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
2026-02-21 15:46:06 -08:00
# 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"
2026-02-12 15:46:57 -08:00
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
2026-03-02 11:37:34 -08:00
wave0| npmplus| backup| copy| secure-keys| request-cert| validate) MODE = " $1 " ; ;
2026-02-12 15:46:57 -08:00
--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
2026-03-02 11:37:34 -08:00
echo " Usage: $0 wave0|npmplus|backup|copy|secure-keys|request-cert|validate [--dry-run] [--skip-backup] [--host IP] [--apply (for secure-keys)] "
2026-02-12 15:46:57 -08:00
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)."
2026-03-02 11:37:34 -08:00
echo " validate - Copy and run shellcheck (full) on scripts/verify and genesis validation on smom-dbis-138."
2026-02-12 15:46:57 -08:00
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"
)
2026-03-02 11:37:34 -08:00
# 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"
)
2026-02-12 15:46:57 -08:00
do_copy( ) {
local host = " $1 "
local list_name = " $2 "
log_info " Creating $REMOTE_DIR and copying files to ${ REMOTE_USER } @ ${ host } ... "
2026-03-02 11:37:34 -08:00
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 "
2026-02-12 15:46:57 -08:00
[ " $list_name " = "request-cert" ] && ssh -o ConnectTimeout = 10 " ${ REMOTE_USER } @ ${ host } " " mkdir -p $REMOTE_DIR /scripts "
2026-03-02 11:37:34 -08:00
[ " $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
2026-02-12 15:46:57 -08:00
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/ " ; ; ;
2026-03-02 11:37:34 -08:00
validate) ; ; # already copied above
2026-02-12 15:46:57 -08:00
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" ; ;
2026-03-02 11:37:34 -08:00
validate) echo " (install shellcheck if needed) bash scripts/verify/run-shellcheck.sh; cd smom-dbis-138 && bash scripts/validation/validate-genesis.sh" ; ;
2026-02-12 15:46:57 -08:00
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"
; ;
2026-03-02 11:37:34 -08:00
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"
; ;
2026-02-12 15:46:57 -08:00
esac
log_ok "Done."
echo ""