Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die README; an keiner Stelle Bedeutung, nur Zeichensetzung.
76 lines
2.9 KiB
Bash
Executable File
76 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Spielt eine Sicherung in eine Wegwerf-Datenbank ein und prüft, ob alles
|
|
# angekommen ist. Ein ungetestetes Backup ist keins - siehe docs/11-betrieb.md.
|
|
#
|
|
# scripts/restore-test.sh [container] [quelldatenbank]
|
|
#
|
|
# Legt `<db>_restore_test` an, spielt einen frischen Dump hinein, vergleicht
|
|
# Zeilenzahlen, Regeln und Trigger, und räumt danach auf.
|
|
set -euo pipefail
|
|
|
|
CONTAINER="${1:-afis-dev-db}"
|
|
QUELLE="${2:-afis}"
|
|
ZIEL="${QUELLE}_restore_test"
|
|
NUTZER="afis"
|
|
|
|
rot() { printf '\033[31m%s\033[0m\n' "$*"; }
|
|
gruen() { printf '\033[32m%s\033[0m\n' "$*"; }
|
|
info() { printf ' %s\n' "$*"; }
|
|
|
|
psql_in() { docker exec "$CONTAINER" psql -U "$NUTZER" -d "$1" -tA -c "$2"; }
|
|
|
|
docker exec "$CONTAINER" pg_isready -U "$NUTZER" -d "$QUELLE" >/dev/null 2>&1 \
|
|
|| { rot "Container $CONTAINER antwortet nicht."; exit 1; }
|
|
|
|
echo "Wiederherstellung prüfen: ${QUELLE} -> ${ZIEL}"
|
|
|
|
info "Dump erzeugen"
|
|
docker exec "$CONTAINER" pg_dump -U "$NUTZER" -d "$QUELLE" -Fc -f /tmp/restore-test.dump
|
|
|
|
info "Zieldatenbank neu anlegen"
|
|
docker exec "$CONTAINER" psql -U "$NUTZER" -d postgres -q \
|
|
-c "DROP DATABASE IF EXISTS \"${ZIEL}\";" -c "CREATE DATABASE \"${ZIEL}\";"
|
|
|
|
info "Einspielen"
|
|
# pg_restore meldet auf einer frischen Datenbank Warnungen zu Besitzrechten.
|
|
# Die sind erwartbar; entscheidend ist der Vergleich danach.
|
|
docker exec "$CONTAINER" pg_restore -U "$NUTZER" -d "$ZIEL" --no-owner \
|
|
/tmp/restore-test.dump >/dev/null 2>&1 || true
|
|
|
|
FEHLER=0
|
|
|
|
info "Zeilen vergleichen"
|
|
for TABELLE in Case CaseEntry Document PersonnelFile AuditLog ChatMessage SearchIndex; do
|
|
A=$(psql_in "$QUELLE" "SELECT count(*) FROM \"$TABELLE\";" 2>/dev/null || echo "-")
|
|
B=$(psql_in "$ZIEL" "SELECT count(*) FROM \"$TABELLE\";" 2>/dev/null || echo "-")
|
|
if [ "$A" = "$B" ]; then
|
|
info "$TABELLE: $A"
|
|
else
|
|
rot " $TABELLE: Quelle $A, Wiederherstellung $B"
|
|
FEHLER=1
|
|
fi
|
|
done
|
|
|
|
# Ohne Regeln und Trigger wäre die Wiederherstellung eine Datenbank ohne die
|
|
# harten Zusicherungen: löschbare Verlaufseinträge, kein Suchindex.
|
|
REGELN=$(psql_in "$ZIEL" "SELECT count(*) FROM pg_rules WHERE schemaname='public';")
|
|
TRIGGER=$(psql_in "$ZIEL" "SELECT count(*) FROM pg_trigger WHERE NOT tgisinternal;")
|
|
info "Regeln: ${REGELN}, Trigger: ${TRIGGER}"
|
|
[ "$REGELN" -ge 5 ] || { rot " Zu wenige Regeln: die Anhängigkeit fehlt."; FEHLER=1; }
|
|
[ "$TRIGGER" -ge 5 ] || { rot " Zu wenige Trigger: Suchindex oder Wächter fehlen."; FEHLER=1; }
|
|
|
|
# Stichprobe auf die wichtigste Regel überhaupt.
|
|
psql_in "$ZIEL" "SELECT 1 FROM pg_rules WHERE rulename='entry_no_delete';" | grep -q 1 \
|
|
|| { rot " entry_no_delete fehlt: Verlaufseinträge wären löschbar."; FEHLER=1; }
|
|
|
|
info "Aufräumen"
|
|
docker exec "$CONTAINER" psql -U "$NUTZER" -d postgres -q -c "DROP DATABASE IF EXISTS \"${ZIEL}\";"
|
|
docker exec "$CONTAINER" rm -f /tmp/restore-test.dump
|
|
|
|
if [ "$FEHLER" = "0" ]; then
|
|
gruen "Wiederherstellung geprüft: alles angekommen."
|
|
else
|
|
rot "Wiederherstellung unvollständig."
|
|
exit 1
|
|
fi
|