From ac38b4269db2fa5937186e72dd63b125030d2c9d Mon Sep 17 00:00:00 2001 From: jessikitty Date: Wed, 27 May 2026 15:37:48 +1000 Subject: [PATCH] fix: Guacamole DB reinit + NPM data migration via supervisor backup API --- fix-guac-npm.sh | 163 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 fix-guac-npm.sh diff --git a/fix-guac-npm.sh b/fix-guac-npm.sh new file mode 100644 index 0000000..178f0de --- /dev/null +++ b/fix-guac-npm.sh @@ -0,0 +1,163 @@ +#!/bin/bash +# ===================================================================== +# Fix: Guacamole DB schema + NPM data migration +# ===================================================================== +# Guacamole: The initdb.sh docker run failed due to the AppArmor issue, +# so postgres got garbage instead of the schema SQL. This script +# wipes the DB volume, re-generates the schema, and restarts clean. +# +# NPM: SSH to HAOS failed, so no data was migrated. This script pulls +# the addon data via the HA Supervisor partial backup API. +# +# Prerequisites: Run fix-docker-lxc.sh first to fix the AppArmor issue. +# Run on Proxmox host (10.0.0.240) as root. +# ===================================================================== + +set -euo pipefail + +HA_URL="http://10.0.0.55:8123" +HA_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJlMDY2YmRhYTc0OGU0Yjg2YmIwNTAyOWRkZmVjOGUwOSIsImlhdCI6MTc3OTg0MjE5NywiZXhwIjoyMDk1MjAyMTk3fQ.xA0UVpgbOxrvtMVZVnI45vhy7IxDhD2vCAT4mgJcYgk" + +echo "============================================" +echo " Fixing Guacamole (CT 121) + NPM (CT 122)" +echo "============================================" + +# ================================================================= +# FIX 1: GUACAMOLE +# ================================================================= +echo "" +echo "=== [1/2] Fixing Guacamole (CT 121) ===" + +echo " Stopping stack and wiping broken DB volume..." +pct exec 121 -- bash -c 'cd /opt/guacamole && docker compose down -v' 2>/dev/null || true +sleep 3 + +echo " Regenerating database schema..." +pct exec 121 -- bash -c ' + rm -f /opt/guacamole/initdb/001-init.sql + docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql \ + > /opt/guacamole/initdb/001-init.sql 2>/dev/null + SCHEMA_SIZE=$(wc -c < /opt/guacamole/initdb/001-init.sql) + echo " Schema file: ${SCHEMA_SIZE} bytes" + if [ "${SCHEMA_SIZE}" -lt 1000 ]; then + echo " ERROR: Schema too small, docker run may still be failing" + exit 1 + fi +' + +echo " Starting fresh stack..." +pct exec 121 -- bash -c 'cd /opt/guacamole && docker compose up -d' +echo " Waiting 30s for postgres init..." +sleep 30 + +HTTP_GUAC=$(pct exec 121 -- curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/guacamole/ 2>/dev/null || echo "000") +if [ "$HTTP_GUAC" = "200" ] || [ "$HTTP_GUAC" = "302" ]; then + echo " Guacamole is UP" +else + echo " HTTP ${HTTP_GUAC} - checking logs..." + pct exec 121 -- docker logs guacamole 2>&1 | tail -15 +fi + +# ================================================================= +# FIX 2: NPM DATA MIGRATION +# ================================================================= +echo "" +echo "=== [2/2] Migrating NPM data (CT 122) ===" + +NPM_MIGRATED=false +TMPDIR=$(mktemp -d) + +# Try SSH first (ports 22222 and 22) +for PORT in 22222 22; do + if ssh -o ConnectTimeout=3 -o StrictHostKeyChecking=no -p ${PORT} \ + root@10.0.0.55 "test -d /addon_data/a0d7b954_nginxproxymanager" 2>/dev/null; then + echo " SSH connected (port ${PORT}), copying data..." + scp -P ${PORT} -r -o StrictHostKeyChecking=no \ + root@10.0.0.55:/addon_data/a0d7b954_nginxproxymanager/ \ + "${TMPDIR}/npm_data/" 2>/dev/null + NPM_MIGRATED=true + break + fi +done + +# Try HA Supervisor partial backup if SSH failed +if [ "$NPM_MIGRATED" = false ]; then + echo " SSH failed. Trying HA Supervisor partial backup..." + BACKUP_RESPONSE=$(curl -s -X POST \ + -H "Authorization: Bearer ${HA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"name":"npm-migration","addons":["a0d7b954_nginxproxymanager"],"folders":[]}' \ + "${HA_URL}/api/hassio/backups/new/partial" 2>/dev/null) + + BACKUP_SLUG=$(echo "${BACKUP_RESPONSE}" | python3 -c " +import sys,json +try: + d=json.load(sys.stdin); print(d.get('data',{}).get('slug','')) +except: + print('') +" 2>/dev/null) + + if [ -n "${BACKUP_SLUG}" ] && [ "${BACKUP_SLUG}" != "" ]; then + echo " Backup created (${BACKUP_SLUG}), downloading..." + curl -s -o "${TMPDIR}/npm-backup.tar" \ + -H "Authorization: Bearer ${HA_TOKEN}" \ + "${HA_URL}/api/hassio/backups/${BACKUP_SLUG}/download" 2>/dev/null + + if [ -f "${TMPDIR}/npm-backup.tar" ] && [ -s "${TMPDIR}/npm-backup.tar" ]; then + mkdir -p "${TMPDIR}/npm_data" + cd "${TMPDIR}" && tar xf npm-backup.tar 2>/dev/null || true + ADDON_TAR=$(find "${TMPDIR}" -name "*nginxproxymanager*" -name "*.tar.gz" 2>/dev/null | head -1) + if [ -n "${ADDON_TAR}" ]; then + tar xzf "${ADDON_TAR}" -C "${TMPDIR}/npm_data/" 2>/dev/null || true + NPM_MIGRATED=true + fi + fi + curl -s -X DELETE -H "Authorization: Bearer ${HA_TOKEN}" \ + "${HA_URL}/api/hassio/backups/${BACKUP_SLUG}" 2>/dev/null || true + fi +fi + +# Apply migrated data +if [ "$NPM_MIGRATED" = true ]; then + echo " Applying NPM data..." + pct exec 122 -- bash -c 'cd /opt/npm && docker compose down' 2>/dev/null || true + sleep 3 + + DB_FILE=$(find "${TMPDIR}/npm_data" -name "database.sqlite" -type f 2>/dev/null | head -1) + [ -n "${DB_FILE}" ] && pct push 122 "${DB_FILE}" /opt/npm/data/database.sqlite && echo " DB migrated" + + CERT_DIR=$(find "${TMPDIR}/npm_data" -type d -name "letsencrypt" 2>/dev/null | head -1) + if [ -n "${CERT_DIR}" ]; then + tar -czf "${TMPDIR}/c.tar.gz" -C "${CERT_DIR}" . 2>/dev/null + pct push 122 "${TMPDIR}/c.tar.gz" /tmp/c.tar.gz + pct exec 122 -- bash -c 'tar xzf /tmp/c.tar.gz -C /opt/npm/letsencrypt/ && rm /tmp/c.tar.gz' + echo " Certs migrated" + fi + + pct exec 122 -- bash -c 'cd /opt/npm && docker compose up -d' + sleep 10 + echo " NPM restarted with migrated data" +else + echo "" + echo " AUTO-MIGRATION FAILED. Manual steps:" + echo " 1. HA > Settings > Backups > Create > Partial" + echo " Select ONLY 'Nginx Proxy Manager', create it" + echo " 2. Download the backup .tar file" + echo " 3. Copy to Proxmox: scp backup.tar root@10.0.0.240:/tmp/" + echo " 4. Run:" + echo " cd /tmp && tar xf *.tar" + echo " tar xzf *nginxproxymanager*.tar.gz -C /tmp/npm_extract/" + echo " find /tmp/npm_extract -name database.sqlite" + echo " pct exec 122 -- bash -c 'cd /opt/npm && docker compose down'" + echo " pct push 122 /tmp/npm_extract/.../database.sqlite /opt/npm/data/database.sqlite" + echo " pct exec 122 -- bash -c 'cd /opt/npm && docker compose up -d'" +fi + +rm -rf "${TMPDIR}" +echo "" +echo "============================================" +echo " Guacamole: http://10.0.0.225:8080/guacamole/" +echo " Login: guacadmin / guacadmin" +echo " NPM: http://10.0.0.226:81" +[ "$NPM_MIGRATED" = true ] && echo " Login: existing credentials" || echo " Login: admin@example.com / changeme" +echo "============================================"