diff --git a/rmm-tasks/ESPO-04-Update.sh b/rmm-tasks/ESPO-04-Update.sh new file mode 100755 index 0000000..97d0edc --- /dev/null +++ b/rmm-tasks/ESPO-04-Update.sh @@ -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 +# 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" diff --git a/rmm-tasks/ESPO-05-Snapshot-verwerfen.sh b/rmm-tasks/ESPO-05-Snapshot-verwerfen.sh new file mode 100755 index 0000000..0dc8da7 --- /dev/null +++ b/rmm-tasks/ESPO-05-Snapshot-verwerfen.sh @@ -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"