Update-Weg: ESPO-04 mit Snapshot als Riegel, ESPO-05 zum Verwerfen
ESPO-04 legt zuerst den LVM-Snapshot an und bricht ab, wenn das nicht gelingt - kein Update ohne Rueckweg. Es bricht ausserdem ab, wenn noch ein Snapshot aus einem frueheren Lauf besteht: Das hiesse, dass das vorige Update nie bestaetigt wurde, und zwei Snapshots uebereinander waeren kein Rueckweg mehr. ESPO-05 verwirft den Snapshot, nachdem jemand die Instanz geprueft hat, und haelt vorher Fuellgrad und Gueltigkeit fest - war er bereits vollgelaufen, hat der Rueckweg schon vorher nicht mehr getragen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
20ec54a1aa
commit
449627de30
94
rmm-tasks/ESPO-04-Update.sh
Executable file
94
rmm-tasks/ESPO-04-Update.sh
Executable file
@ -0,0 +1,94 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ESPO-04-Update - hebt EspoCRM auf den Stand des Rings, mit LVM-Snapshot als Rueckweg.
|
||||||
|
# Aufruf: ESPO-04-Update.sh <fqdn> <ring>
|
||||||
|
# Ob der Lauf erlaubt ist, entscheidet der Task per If/Then auf espo_zustand (erwartet DEPLOYED).
|
||||||
|
# Der Snapshot bleibt nach dem Lauf absichtlich bestehen - verworfen wird er erst durch ESPO-05,
|
||||||
|
# nachdem jemand geprueft hat, dass die Instanz nach dem Update noch richtig arbeitet.
|
||||||
|
set -u
|
||||||
|
|
||||||
|
# Standzeile: zeigt im Protokoll, welche Fassung tatsaechlich gelaufen ist.
|
||||||
|
echo "ESPO-04-Update, Skriptstand 2026-09-24"
|
||||||
|
|
||||||
|
BASIS_URL=https://gitea.subcura.net/EspoCRM_Public/espo-deploy/raw/branch/main
|
||||||
|
VG=ubuntu-vg
|
||||||
|
URSPRUNG=/dev/ubuntu-vg/srv-lv
|
||||||
|
SNAPSHOT=srv-vor-update
|
||||||
|
SNAPGROESSE=10G
|
||||||
|
WARTE_MAX=900
|
||||||
|
FQDN="${1:-}"
|
||||||
|
RING="${2:-}"
|
||||||
|
|
||||||
|
fehler() { echo "FEHLER: $*"; echo "ESPO04_ERGEBNIS: FEHLER"; exit 1; }
|
||||||
|
|
||||||
|
# 1. Vorbedingungen - lieber hier abbrechen als auf halbem Weg.
|
||||||
|
[ "$(id -u)" -eq 0 ] || fehler "nicht als root gestartet"
|
||||||
|
command -v docker >/dev/null && docker info >/dev/null 2>&1 || fehler "Docker laeuft nicht"
|
||||||
|
command -v lvcreate >/dev/null || fehler "LVM-Werkzeuge fehlen"
|
||||||
|
[ -n "$FQDN" ] || fehler "kein FQDN uebergeben"
|
||||||
|
[ -n "$RING" ] || fehler "kein Ring uebergeben"
|
||||||
|
[ -b "$URSPRUNG" ] || fehler "$URSPRUNG nicht gefunden - ist /srv wirklich ein eigenes LV?"
|
||||||
|
|
||||||
|
# 2. Ein Snapshot aus einem frueheren Lauf heisst: Das vorige Update ist nicht bestaetigt.
|
||||||
|
# Zwei Snapshots uebereinander waeren kein Rueckweg mehr, sondern ein Ratespiel.
|
||||||
|
if lvs --noheadings -o lv_name "$VG" 2>/dev/null | grep -qw "$SNAPSHOT"; then
|
||||||
|
fehler "Snapshot '$SNAPSHOT' besteht noch - das vorige Update wurde nicht mit ESPO-05 abgeschlossen"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. Ausgangsstand festhalten, damit der Bericht ein Vorher und ein Nachher hat.
|
||||||
|
VORHER_IMAGE="$(docker inspect -f '{{.Config.Image}}' espocrm 2>/dev/null)"
|
||||||
|
VORHER_VERSION="$(docker exec espocrm php -r '$a=@include "data/config.php"; $b=@include "data/config-internal.php"; $c=array_merge(is_array($a)?$a:[], is_array($b)?$b:[]); echo $c["version"] ?? "";' 2>/dev/null)"
|
||||||
|
echo "Vorher: Image ${VORHER_IMAGE:-unbekannt}, Version ${VORHER_VERSION:-unbekannt}"
|
||||||
|
|
||||||
|
# 4. Erst der Rueckweg, dann das Update. Ohne Snapshot wird nichts angefasst.
|
||||||
|
lvcreate -s -n "$SNAPSHOT" -L "$SNAPGROESSE" "$URSPRUNG" >/dev/null 2>&1 \
|
||||||
|
|| fehler "Snapshot nicht anlegbar (freie Extents in der VG?) - kein Update ohne Rueckweg"
|
||||||
|
lvs --noheadings -o lv_name "$VG" 2>/dev/null | grep -qw "$SNAPSHOT" \
|
||||||
|
|| fehler "Snapshot nach dem Anlegen nicht auffindbar"
|
||||||
|
echo "Snapshot: $SNAPSHOT angelegt ($SNAPGROESSE)"
|
||||||
|
|
||||||
|
# 5. Stand des Rings holen: Compose und Grundeinstellungen gehoeren zusammen.
|
||||||
|
# Dieselbe Zuordnung steht in bin/espo-compose-rendern - beide zusammen halten.
|
||||||
|
case "$RING" in
|
||||||
|
0) RINGORDNER="0%20-%20intern" ;;
|
||||||
|
1) RINGORDNER="1%20-%20Pilotkunde" ;;
|
||||||
|
2) RINGORDNER="2%20-%20Produktivkunde" ;;
|
||||||
|
*) fehler "unbekannter Ring '$RING' (erwartet 0, 1 oder 2)" ;;
|
||||||
|
esac
|
||||||
|
curl -fsSL "$BASIS_URL/docker/$RINGORDNER/config-override.php" -o /srv/espo/data/config-override.php \
|
||||||
|
|| fehler "config-override.php fuer Ring '$RING' nicht abrufbar"
|
||||||
|
curl -fsSL "$BASIS_URL/bin/espo-compose-rendern" -o /srv/espo/bin/espo-compose-rendern \
|
||||||
|
|| fehler "Render-Skript nicht abrufbar"
|
||||||
|
chmod 0755 /srv/espo/bin/espo-compose-rendern
|
||||||
|
/srv/espo/bin/espo-compose-rendern "$FQDN" "$RING" || fehler "Compose konnte nicht geschrieben werden"
|
||||||
|
|
||||||
|
# 6. Anwenden. Der Entrypoint startet die Migration von sich aus, sobald das Image wechselt.
|
||||||
|
START_AUSGABE="$(docker compose -f /srv/espo/docker-compose.yml up -d --quiet-pull 2>&1)" || {
|
||||||
|
echo "$START_AUSGABE" | tail -n 20
|
||||||
|
fehler "Start nach dem Update fehlgeschlagen - Snapshot '$SNAPSHOT' steht fuer den Rueckweg bereit"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 7. Auf die Anwendung warten. Waehrend der Migration meldet app-check absichtlich nicht gesund.
|
||||||
|
ENDE=$(( SECONDS + WARTE_MAX ))
|
||||||
|
while [ "$SECONDS" -lt "$ENDE" ]; do
|
||||||
|
[ "$(docker inspect -f '{{.State.Health.Status}}' espocrm 2>/dev/null)" = "healthy" ] && break
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
[ "$(docker inspect -f '{{.State.Health.Status}}' espocrm 2>/dev/null)" = "healthy" ] \
|
||||||
|
|| fehler "espocrm nach ${WARTE_MAX}s nicht gesund - 'docker logs espocrm' ansehen, Snapshot '$SNAPSHOT' steht bereit"
|
||||||
|
|
||||||
|
# 8. Ergebnis zeigen.
|
||||||
|
echo "--- Container"
|
||||||
|
docker compose -f /srv/espo/docker-compose.yml ps --format 'table {{.Name}}\t{{.Status}}'
|
||||||
|
echo "--- Instanz"
|
||||||
|
NACHHER_IMAGE="$(docker inspect -f '{{.Config.Image}}' espocrm 2>/dev/null)"
|
||||||
|
NACHHER_VERSION="$(docker exec espocrm php -r '$a=@include "data/config.php"; $b=@include "data/config-internal.php"; $c=array_merge(is_array($a)?$a:[], is_array($b)?$b:[]); echo $c["version"] ?? "";' 2>/dev/null)"
|
||||||
|
echo "Image: ${VORHER_IMAGE:-unbekannt} -> ${NACHHER_IMAGE:-unbekannt}"
|
||||||
|
echo "Version: ${VORHER_VERSION:-unbekannt} -> ${NACHHER_VERSION:-unbekannt}"
|
||||||
|
echo "Digest: $(docker image inspect --format '{{if .RepoDigests}}{{index .RepoDigests 0}}{{else}}{{.Id}}{{end}}' "$NACHHER_IMAGE" 2>/dev/null)"
|
||||||
|
echo "--- Rueckweg"
|
||||||
|
lvs --noheadings -o lv_name,lv_attr,origin,data_percent "$VG/$SNAPSHOT" 2>/dev/null | sed 's/^ */ /'
|
||||||
|
echo "--- Naechster Schritt von Hand"
|
||||||
|
echo "Instanz pruefen (Anmeldung, ein Datensatz, E-Mail, WebSocket). Erst danach ESPO-05 ausfuehren,"
|
||||||
|
echo "das den Snapshot verwirft. Solange er besteht, kostet jeder Schreibvorgang zusaetzliche Zeit,"
|
||||||
|
echo "und laeuft er voll, verwirft LVM ihn stillschweigend - dann ist der Rueckweg weg."
|
||||||
|
echo "ESPO04_ERGEBNIS: OK"
|
||||||
43
rmm-tasks/ESPO-05-Snapshot-verwerfen.sh
Executable file
43
rmm-tasks/ESPO-05-Snapshot-verwerfen.sh
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ESPO-05-Snapshot-verwerfen - raeumt den Rueckweg weg, nachdem die Instanz von Hand geprueft wurde.
|
||||||
|
# Aufruf: ohne Argumente.
|
||||||
|
# Laeuft bewusst erst nach der Pruefung: Solange der Snapshot besteht, kostet jeder Schreibvorgang
|
||||||
|
# auf /srv einen zusaetzlichen Kopiervorgang, und ein vollgelaufener Snapshot wird still verworfen.
|
||||||
|
set -u
|
||||||
|
|
||||||
|
# Standzeile: zeigt im Protokoll, welche Fassung tatsaechlich gelaufen ist.
|
||||||
|
echo "ESPO-05-Snapshot-verwerfen, Skriptstand 2026-09-24"
|
||||||
|
|
||||||
|
VG=ubuntu-vg
|
||||||
|
SNAPSHOT=srv-vor-update
|
||||||
|
|
||||||
|
fehler() { echo "FEHLER: $*"; echo "ESPO05_ERGEBNIS: FEHLER"; exit 1; }
|
||||||
|
|
||||||
|
# 1. Vorbedingungen.
|
||||||
|
[ "$(id -u)" -eq 0 ] || fehler "nicht als root gestartet"
|
||||||
|
command -v lvremove >/dev/null || fehler "LVM-Werkzeuge fehlen"
|
||||||
|
|
||||||
|
# 2. Ohne Snapshot gibt es nichts zu verwerfen - das ist kein Erfolg, sondern ein Hinweis:
|
||||||
|
# Entweder lief kein Update, oder der Snapshot ist bereits weg (auch stillschweigend, siehe 3).
|
||||||
|
lvs --noheadings -o lv_name "$VG" 2>/dev/null | grep -qw "$SNAPSHOT" \
|
||||||
|
|| fehler "kein Snapshot '$SNAPSHOT' vorhanden - lief ESPO-04 ueberhaupt?"
|
||||||
|
|
||||||
|
# 3. Zustand festhalten, bevor er verschwindet. Ein 'I' im Attributfeld heisst: bereits ungueltig,
|
||||||
|
# der Rueckweg haette also gar nicht mehr getragen. Das gehoert ins Protokoll.
|
||||||
|
echo "--- Zustand vor dem Verwerfen"
|
||||||
|
lvs -o lv_name,lv_attr,origin,lv_size,data_percent "$VG/$SNAPSHOT" 2>/dev/null | sed 's/^/ /'
|
||||||
|
ATTR="$(lvs --noheadings -o lv_attr "$VG/$SNAPSHOT" 2>/dev/null | tr -d ' ')"
|
||||||
|
case "$ATTR" in
|
||||||
|
*I*) echo "HINWEIS: Der Snapshot war bereits ungueltig (vollgelaufen) - ein Rueckweg bestand nicht mehr." ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 4. Verwerfen.
|
||||||
|
lvremove -y "$VG/$SNAPSHOT" >/dev/null 2>&1 || fehler "Snapshot liess sich nicht entfernen"
|
||||||
|
lvs --noheadings -o lv_name "$VG" 2>/dev/null | grep -qw "$SNAPSHOT" \
|
||||||
|
&& fehler "Snapshot ist nach lvremove immer noch da"
|
||||||
|
|
||||||
|
# 5. Ergebnis zeigen: freie Extents sind die Voraussetzung fuer das naechste Update.
|
||||||
|
echo "--- Danach"
|
||||||
|
echo "Snapshot '$SNAPSHOT' verworfen."
|
||||||
|
vgs --units g -o vg_name,vg_size,vg_free "$VG" 2>/dev/null | sed 's/^/ /'
|
||||||
|
echo "ESPO05_ERGEBNIS: OK"
|
||||||
Loading…
x
Reference in New Issue
Block a user