ESPO-22 kopiert bei gestopptem Stack den Anwendungsstand (mariadb, data, custom, client-custom) nach /srv/espo-baseline - ohne secrets, Compose, bin, data/config-override.php und data/logs, die von Tasks gepflegt werden bzw. als Verlauf bleiben. Dazu ein Manifest mit EspoCRM-Version, MariaDB-Image und den Extension-Kennungen; der neue Grundstand ersetzt den alten erst, wenn er vollstaendig ist. ESPO-23 spielt den Grundstand per rsync zurueck (taeglich 02:00) und bricht ab, wenn seit dem Sichern ESPO-10 oder ESPO-30 gelaufen ist oder ein Snapshot offen ist. Beide Skripte laufen nur auf Hostnamen espo-demo*; nach einem Fehler startet die Demo in jedem Fall wieder. In einer Sandbox mit allen Sperren und dem Fehlerfall nach dem Stoppen getestet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
99 lines
5.0 KiB
Bash
99 lines
5.0 KiB
Bash
#!/bin/bash
|
|
# ESPO-23-Demo-zuruecksetzen - setzt eine Demo-Instanz auf den mit ESPO-22 gesicherten Grundstand zurueck.
|
|
# Aufruf: ohne Argumente, taeglich um 02:00 ueber den Zeitplan des RMM.
|
|
# Zwei unabhaengige Riegel gegen einen Lauf auf einer Kundeninstanz: Der Task ist nur auf der Demo eingeplant,
|
|
# und dieses Skript laeuft nur auf Hostnamen espo-demo* - ein Fehlgriff wuerde sonst Kundendaten loeschen
|
|
# (bewusste Abweichung von ADR 0012, siehe ADR 0014).
|
|
set -u
|
|
|
|
# Standzeile: zeigt im Protokoll, welche Fassung tatsaechlich gelaufen ist.
|
|
echo "ESPO-23-Demo-zuruecksetzen, Skriptstand 2026-10-01"
|
|
|
|
BASIS=/srv/espo
|
|
GRUNDSTAND=/srv/espo-baseline
|
|
COMPOSE=$BASIS/docker-compose.yml
|
|
VG=ubuntu-vg
|
|
SNAPSHOT=srv-vor-update
|
|
WARTE_MAX=600
|
|
# Dieselbe Auswahl wie in ESPO-22: secrets/, Compose, bin/, data/config-override.php und data/logs/ bleiben,
|
|
# wie sie sind.
|
|
VERZEICHNISSE="mariadb data custom client-custom"
|
|
|
|
fehler() { echo "FEHLER: $*"; echo "ESPO23_ERGEBNIS: FEHLER"; exit 1; }
|
|
|
|
# Wartet, bis alle vier Container "healthy" melden - "starting" ist keine Aussage.
|
|
alle_gesund() {
|
|
local c
|
|
for c in espocrm-db espocrm espocrm-daemon espocrm-websocket; do
|
|
[ "$(docker inspect -f '{{.State.Health.Status}}' "$c" 2>/dev/null)" = "healthy" ] || return 1
|
|
done
|
|
return 0
|
|
}
|
|
|
|
# Nennt die Container, die noch nicht gesund sind - fuer die Fehlermeldung.
|
|
nicht_gesund() {
|
|
local c z=""
|
|
for c in espocrm-db espocrm espocrm-daemon espocrm-websocket; do
|
|
[ "$(docker inspect -f '{{.State.Health.Status}}' "$c" 2>/dev/null)" = "healthy" ] \
|
|
|| z="$z $c=$(docker inspect -f '{{.State.Health.Status}}' "$c" 2>/dev/null || echo fehlt)"
|
|
done
|
|
printf '%s' "${z# }"
|
|
}
|
|
|
|
# Dieselben Merkmale wie in ESPO-22 - alle aus Dateien lesbar, also auch dann, wenn die Demo gerade klemmt.
|
|
espo_version() { sed -n "s/^[[:space:]]*'version' => '\([^']*\)'.*/\1/p" "$1/data/state.php" 2>/dev/null | head -n 1; }
|
|
db_image() { sed -n 's/^[[:space:]]*image:[[:space:]]*\(mariadb:[^[:space:]]*\).*/\1/p' "$COMPOSE" 2>/dev/null | head -n 1; }
|
|
extension_ids() { ls -1 "$1/data/.backup/extensions" 2>/dev/null | sort | paste -sd ' '; }
|
|
gesichert() { sed -n "s/^$1=//p" "$GRUNDSTAND/manifest" 2>/dev/null | head -n 1; }
|
|
|
|
# 1. Vorbedingungen. Die Instanz muss dafuer nicht gesund sein - eine klemmende Demo soll der Reset ja reparieren.
|
|
[ "$(id -u)" -eq 0 ] || fehler "nicht als root gestartet"
|
|
[[ "$(hostname -s)" == espo-demo* ]] || fehler "nur auf Demo-Instanzen (Hostname espo-demo*), hier: $(hostname -s)"
|
|
command -v docker >/dev/null && docker info >/dev/null 2>&1 || fehler "Docker laeuft nicht"
|
|
command -v rsync >/dev/null || fehler "rsync fehlt - ESPO-22 installiert es beim Sichern"
|
|
[ -f "$COMPOSE" ] || fehler "$COMPOSE fehlt - ist die Instanz deployt?"
|
|
[ -s "$GRUNDSTAND/manifest" ] || fehler "kein Grundstand unter $GRUNDSTAND - zuerst ESPO-22 ausfuehren"
|
|
for V in $VERZEICHNISSE; do
|
|
[ -d "$GRUNDSTAND/$V" ] || fehler "Grundstand unvollstaendig: $V fehlt - ESPO-22 erneut ausfuehren"
|
|
done
|
|
if lvs --noheadings -o lv_name "$VG" 2>/dev/null | grep -qw "$SNAPSHOT"; then
|
|
fehler "Snapshot '$SNAPSHOT' besteht - eine Aenderung ist noch nicht mit ESPO-11 bestaetigt"
|
|
fi
|
|
|
|
# 2. Passt der Grundstand noch? ESPO-10 aendert Version oder Image, ESPO-30 die Extensions. Ein Zuruecksetzen
|
|
# wuerde das still rueckgaengig machen - dann lieber abbrechen und neu sichern lassen.
|
|
IST="$(espo_version "$BASIS")"; SOLL="$(gesichert espo_version)"
|
|
[ "$IST" = "$SOLL" ] || fehler "EspoCRM ist ${IST:-unbekannt}, der Grundstand ${SOLL:-unbekannt} - nach dem Update erst ESPO-22 ausfuehren"
|
|
IST="$(db_image)"; SOLL="$(gesichert db_image)"
|
|
[ "$IST" = "$SOLL" ] || fehler "MariaDB laut Compose ${IST:-unbekannt}, im Grundstand ${SOLL:-unbekannt} - erst ESPO-22 ausfuehren"
|
|
[ "$(extension_ids "$BASIS")" = "$(gesichert extension_ids)" ] \
|
|
|| fehler "die Extensions haben sich seit dem Grundstand geaendert (ESPO-30?) - erst ESPO-22 ausfuehren"
|
|
|
|
# 3. Stoppen, zurueckkopieren, starten. Was auch passiert: Am Ende laeuft die Demo wieder.
|
|
GESTOPPT=0
|
|
trap '[ "$GESTOPPT" -eq 1 ] && docker compose -f "$COMPOSE" up -d >/dev/null 2>&1' EXIT
|
|
docker compose -f "$COMPOSE" stop >/dev/null 2>&1 || fehler "Stack nicht stoppbar"
|
|
GESTOPPT=1
|
|
for V in $VERZEICHNISSE; do
|
|
AUSNAHMEN=()
|
|
[ "$V" = "data" ] && AUSNAHMEN=(--exclude=/logs/ --exclude=/config-override.php)
|
|
rsync -a --numeric-ids --delete "${AUSNAHMEN[@]}" "$GRUNDSTAND/$V/" "$BASIS/$V/" || fehler "Zurueckkopieren von $V fehlgeschlagen"
|
|
done
|
|
START="$(docker compose -f "$COMPOSE" up -d 2>&1)" || { printf '%s\n' "$START" | tail -n 10; fehler "Start fehlgeschlagen"; }
|
|
GESTOPPT=0
|
|
ENDE=$(( SECONDS + WARTE_MAX ))
|
|
while [ "$SECONDS" -lt "$ENDE" ]; do
|
|
alle_gesund && break
|
|
sleep 10
|
|
done
|
|
alle_gesund || fehler "nach ${WARTE_MAX}s nicht alle Container gesund: $(nicht_gesund)"
|
|
|
|
# 4. Bericht.
|
|
echo "--- Zurueckgesetzt auf den Grundstand"
|
|
echo "gesichert: $(gesichert created)"
|
|
echo "EspoCRM: $(gesichert espo_version)"
|
|
echo "Extensions: $(gesichert extensions)"
|
|
echo "--- Container"
|
|
docker compose -f "$COMPOSE" ps --format 'table {{.Name}}\t{{.Status}}' 2>/dev/null
|
|
echo "ESPO23_ERGEBNIS: OK"
|