Files
vnctalk-prosody/config/migrate.sh
T
Stefan-Sanger e1c78e7358 feat: add pre-upgrade and post-upgrade DB migration hooks
Dockerfile: add postgresql-client and bake db-customization/ SQL scripts
into the image at /vnc/db-customization/.

config/migrate.sh: detection + migration script with two modes:
- pre-upgrade: runs idempotent prosody-13-new-deployment.sql on 13.0.x
  databases; skips 0.11.6 (unsafe pre-upgrade) and new deployments.
- post-upgrade: waits for Prosody table, then runs the appropriate
  scripts — full 0.11.6->13.0.6 migration (rules-triggers + migration-once
  + new-deployment) or idempotent drift correction for 13.0.x.

Helm chart: two Job templates (db-migration-pre-upgrade.yaml,
db-migration-post-upgrade.yaml) gated by dbMigration.enabled (default
true). Both reuse the Prosody image and DB credentials from existing
values. backoffLimit: 0, hook-delete-policy: hook-succeeded.

Also tracks the db-customization SQL files (previously untracked, now
referenced by the Dockerfile ADD).

Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
2026-07-15 17:59:09 +02:00

154 lines
4.4 KiB
Bash
Executable File

#!/bin/sh
set -e
MODE="${1:-pre-upgrade}"
SQL_DIR="/vnc/db-customization"
log() {
echo "[migrate:$MODE] $*"
}
# Map Prosody env vars to PostgreSQL env vars
export PGHOST="${prosodyDBhost}"
export PGPORT="${prosodyDBport:-5432}"
export PGUSER="${prosodyDBuser}"
export PGDATABASE="${prosodyDBname}"
export PGPASSWORD="${prosodyDBpass}"
PSQL="psql -v ON_ERROR_STOP=1"
# ---------------------------------------------------------------------------
# Detection helpers
# ---------------------------------------------------------------------------
prosody_table_exists() {
$PSQL -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'prosody')" 2>/dev/null | tr -d '[:space:]'
}
derived_tables_exist() {
$PSQL -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'processed_messages')" 2>/dev/null | tr -d '[:space:]'
}
room_membership_view_exists() {
$PSQL -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'room_membership')" 2>/dev/null | tr -d '[:space:]'
}
room_membership_uses_old_format() {
$PSQL -tAc "SELECT pg_get_viewdef('room_membership'::regclass, true)" 2>/dev/null | grep -q "_affiliations"
}
wait_for_prosody_table() {
local max="${1:-60}"
local i=0
while [ "$i" -lt "$max" ]; do
if [ "$(prosody_table_exists)" = "t" ]; then
return 0
fi
log "waiting for prosody table to exist ($i/$max)..."
sleep 2
i=$((i + 2))
done
return 1
}
# ---------------------------------------------------------------------------
# Migration runners
# ---------------------------------------------------------------------------
run_new_deployment() {
log "running prosody-13-new-deployment.sql (idempotent)..."
$PSQL -f "$SQL_DIR/prosody-13-new-deployment.sql"
log "prosody-13-new-deployment.sql completed."
}
run_rules_triggers() {
log "running prosody-13-rules-triggers.sql..."
$PSQL -f "$SQL_DIR/prosody-13-rules-triggers.sql"
log "prosody-13-rules-triggers.sql completed."
}
run_migration_once() {
log "running prosody-13-migration-once.sql..."
$PSQL -f "$SQL_DIR/prosody-13-migration-once.sql"
log "prosody-13-migration-once.sql completed."
}
# ---------------------------------------------------------------------------
# Pre-upgrade mode
# ---------------------------------------------------------------------------
migrate_pre_upgrade() {
if [ "$(prosody_table_exists)" != "t" ]; then
log "prosody table does not exist. Prosody has not started yet. Skipping."
return 0
fi
if [ "$(derived_tables_exist)" != "t" ]; then
log "no derived tables found. Skipping (will be handled post-install)."
return 0
fi
if [ "$(room_membership_view_exists)" = "t" ]; then
if room_membership_uses_old_format; then
log "WARNING: 0.11.6 format detected (room_membership uses _affiliations)."
log "Running 13.0 rules/triggers against 0.11.6 data is unsafe pre-upgrade."
log "The migration will run in the post-upgrade hook after the new image starts."
return 0
fi
fi
log "13.0 format detected. Running idempotent schema check..."
run_new_deployment
}
# ---------------------------------------------------------------------------
# Post-upgrade mode
# ---------------------------------------------------------------------------
migrate_post_upgrade() {
if ! wait_for_prosody_table 120; then
log "prosody table still does not exist after 120s. Skipping."
return 0
fi
if [ "$(derived_tables_exist)" != "t" ]; then
log "new deployment detected (no derived tables)."
run_new_deployment
return 0
fi
if [ "$(room_membership_view_exists)" = "t" ] && room_membership_uses_old_format; then
log "0.11.6 format detected (room_membership uses _affiliations)."
log "Running full 0.11.6 -> 13.0.6 migration..."
run_rules_triggers
run_migration_once
run_new_deployment
log "0.11.6 -> 13.0.6 migration completed."
return 0
fi
log "13.0 format detected. Running idempotent schema check..."
run_new_deployment
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
log "starting (mode=$MODE)"
case "$MODE" in
pre-upgrade)
migrate_pre_upgrade
;;
post-upgrade)
migrate_post_upgrade
;;
*)
log "ERROR: unknown mode '$MODE'. Use 'pre-upgrade' or 'post-upgrade'."
exit 1
;;
esac
log "done."