diff --git a/rmm-tasks/ESPO-03-First-Deploy.sh b/rmm-tasks/ESPO-03-First-Deploy.sh index f2eec82..e66ce19 100755 --- a/rmm-tasks/ESPO-03-First-Deploy.sh +++ b/rmm-tasks/ESPO-03-First-Deploy.sh @@ -14,6 +14,25 @@ WARTE_MAX=900 FQDN="${1:-}" RING="${2:-}" +# 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# }" +} + fehler() { echo "FEHLER: $*"; echo "ESPO03_ERGEBNIS: FEHLER"; exit 1; } # 1. Vorbedingungen - lieber hier abbrechen als auf halbem Weg. @@ -65,11 +84,10 @@ START_AUSGABE="$(docker compose -f /srv/espo/docker-compose.yml up -d --quiet-pu # 7. Auf die Anwendung warten. Der erste Lauf installiert und baut das Schema auf, das dauert. ENDE=$(( SECONDS + WARTE_MAX )) while [ "$SECONDS" -lt "$ENDE" ]; do - [ "$(docker inspect -f '{{.State.Health.Status}}' espocrm 2>/dev/null)" = "healthy" ] && break + alle_gesund && 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" +alle_gesund || fehler "nach ${WARTE_MAX}s nicht alle Container gesund: $(nicht_gesund) - 'docker logs ' ansehen" # 8. Ergebnis zeigen. Die Datenbankabfragen laufen im Container und lesen das Passwort dort aus der Secret-Datei, # damit es weder im Skript noch in der Prozessliste der VM auftaucht. diff --git a/rmm-tasks/ESPO-10-Update.sh b/rmm-tasks/ESPO-10-Update.sh index 21ed625..867ca48 100755 --- a/rmm-tasks/ESPO-10-Update.sh +++ b/rmm-tasks/ESPO-10-Update.sh @@ -18,6 +18,25 @@ WARTE_MAX=900 FQDN="${1:-}" RING="${2:-}" +# 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# }" +} + fehler() { echo "FEHLER: $*"; echo "ESPO10_ERGEBNIS: FEHLER"; exit 1; } # 1. Vorbedingungen - lieber hier abbrechen als auf halbem Weg. @@ -37,6 +56,9 @@ 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 '$v=""; foreach (["/var/www/html/application/Espo/Resources/defaults/config.php","/var/www/html/data/config.php","/var/www/html/data/config-internal.php"] as $f) { $a=@include $f; if (is_array($a) && !empty($a["version"])) { $v=$a["version"]; } } echo $v;' 2>/dev/null)" +VORHER_ESPO_ID="$(docker inspect -f '{{.Image}}' espocrm 2>/dev/null)" +VORHER_DB_ID="$(docker inspect -f '{{.Image}}' espocrm-db 2>/dev/null)" +VORHER_DB_IMAGE="$(docker inspect -f '{{.Config.Image}}' espocrm-db 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. @@ -70,23 +92,45 @@ START_AUSGABE="$(docker compose -f /srv/espo/docker-compose.yml up -d --quiet-pu # 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 + alle_gesund && 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" +alle_gesund || fehler "nach ${WARTE_MAX}s nicht alle Container gesund: $(nicht_gesund) - 'docker logs ' ansehen" # 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_ESPO_ID="$(docker inspect -f '{{.Image}}' espocrm 2>/dev/null)" NACHHER_VERSION="$(docker exec espocrm php -r '$v=""; foreach (["/var/www/html/application/Espo/Resources/defaults/config.php","/var/www/html/data/config.php","/var/www/html/data/config-internal.php"] as $f) { $a=@include $f; if (is_array($a) && !empty($a["version"])) { $v=$a["version"]; } } echo $v;' 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 "--- Datenbank" +NACHHER_DB_IMAGE="$(docker inspect -f '{{.Config.Image}}' espocrm-db 2>/dev/null)" +NACHHER_DB_ID="$(docker inspect -f '{{.Image}}' espocrm-db 2>/dev/null)" +echo "Image: ${VORHER_DB_IMAGE:-unbekannt} -> ${NACHHER_DB_IMAGE:-unbekannt}" +echo "Version: $(docker exec espocrm-db sh -c 'mariadb -u root -p"$(cat /run/secrets/db_root_password)" -N -B -e "select version()"' 2>/dev/null | tr -d '\r')" +echo "Digest: $(docker image inspect --format '{{if .RepoDigests}}{{index .RepoDigests 0}}{{else}}{{.Id}}{{end}}' "$NACHHER_DB_IMAGE" 2>/dev/null)" + +# Alte Images wegraeumen: Es bleiben genau zwei je Anwendung - das laufende und das vorherige. +# Das vorherige muss bleiben, sonst zeigt die zurueckgerollte Compose nach ESPO-12 auf einen Tag, +# der lokal nicht mehr liegt. Alles aeltere ist nur Platzverbrauch auf dem docker-lv. +aufraeumen() { # aufraeumen + local repo="$1" a="$2" b="$3" id + docker image ls --no-trunc --format '{{.ID}} {{.Repository}}' 2>/dev/null \ + | awk -v r="$repo" '$2 == r {print $1}' | sort -u | while read -r id; do + [ "$id" = "$a" ] || [ "$id" = "$b" ] || docker rmi "$id" >/dev/null 2>&1 || true + done +} +aufraeumen espocrm "$NACHHER_ESPO_ID" "$VORHER_ESPO_ID" +aufraeumen mariadb "$NACHHER_DB_ID" "$VORHER_DB_ID" +echo "--- Images auf der VM (behalten: laufendes und vorheriges)" +docker image ls --format 'table {{.Repository}}\t{{.Tag}}\t{{.Size}}' 2>/dev/null \ + | grep -E 'REPOSITORY|^espocrm|^mariadb' | sed 's/^/ /' echo "--- Rueckweg" -lvs --noheadings -o lv_name,lv_attr,origin,data_percent "$VG/$SNAPSHOT" 2>/dev/null | sed 's/^ */ /' +lvs --noheadings -o lv_name,lv_attr,origin,lv_size,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-11 ausfuehren," echo "das den Snapshot verwirft. Solange er besteht, kostet jeder Schreibvorgang zusaetzliche Zeit," diff --git a/rmm-tasks/ESPO-12-Snapshot-wiederherstellen.sh b/rmm-tasks/ESPO-12-Snapshot-wiederherstellen.sh index f32b2ed..6097930 100755 --- a/rmm-tasks/ESPO-12-Snapshot-wiederherstellen.sh +++ b/rmm-tasks/ESPO-12-Snapshot-wiederherstellen.sh @@ -14,6 +14,25 @@ SNAPSHOT=srv-vor-update COMPOSE=/srv/espo/docker-compose.yml WARTE_MAX=900 +# 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# }" +} + fehler() { echo "FEHLER: $*"; echo "ESPO12_ERGEBNIS: FEHLER"; exit 1; } # Bringt den Dienst wieder hoch, wenn der Rueckweg abgebrochen wird - eine stehende Instanz @@ -79,11 +98,10 @@ START_AUSGABE="$(docker compose -f "$COMPOSE" up -d --quiet-pull 2>&1)" || { # 7. Auf die Anwendung warten. ENDE=$(( SECONDS + WARTE_MAX )) while [ "$SECONDS" -lt "$ENDE" ]; do - [ "$(docker inspect -f '{{.State.Health.Status}}' espocrm 2>/dev/null)" = "healthy" ] && break + alle_gesund && 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" +alle_gesund || fehler "nach ${WARTE_MAX}s nicht alle Container gesund: $(nicht_gesund) - 'docker logs ' ansehen" # 8. Ergebnis zeigen. echo "--- Container"