install.sh wird update-faehig, update.sh auf Bootstrapper reduziert
install.sh erkennt jetzt selbststaendig eine bestehende Installation (an sqlite.db) und verhaelt sich entsprechend: - Keine vorhandene Installation -> normale Frischinstallation (wie bisher). - Vorhanden, SCHEMA_VERSION unveraendert -> einfaches In-Place-Update, kein Backup noetig (rsync schliesst sqlite.db ohnehin aus). - Vorhanden, SCHEMA_VERSION unbekannt/abweichend -> Update MIT Sicherheitsnetz: die KOMPLETTE bisherige Installation (Code, venv, Datenbank, Schluessel) wird vorher 1:1 nach /srv/tesm-backup-pre-migration-<timestamp> kopiert (bewusst nicht nur die Datenbank -- ein reines DB-Rollback wuerde beim naechsten Start mit dem NEUEN Code sofort denselben Migrationsfehler wiederholen). Die eigentliche Schema-Migration uebernimmt danach die App selbst beim Start (_ensure_schema() in app.py). Kommt der Dienst anschliessend per HTTP-Check auf /login nachweislich NICHT gesund hoch, wird automatisch die komplette Sicherung zurueckgespielt und bleibt zur manuellen Pruefung erhalten. Kommt er gesund hoch, gilt die Migration als erfolgreich und das Backup wird geloescht. update.sh delegiert diese gesamte /srv/tesm-spezifische Logik jetzt an install.sh und ist selbst nur noch fuer das Ablösen AELTERER, TESM vorausgehender Installationsstufen zustaendig (PoE Manager unter /srv/poe_manager, das urspruengliche reine Bash-Setup) -- bleibt aber als bequemer Ein-Skript-Bootstrapper (Download + Entpacken + Aufruf von install.sh) bestehen, wie gewuenscht. install.sh selbst ist dadurch jetzt auch OHNE update.sh direkt aus einem entpackten Release-Paket lauffaehig und erkennt ein Update trotzdem korrekt. VERSION: 1.0.3 (SCHEMA_VERSION unveraendert, 1 -- keine echte Schema- Aenderung in diesem Release, In-Place-Update-Pfad bleibt der Normalfall).
This commit is contained in:
+89
-2
@@ -1,15 +1,37 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# TESM — Installer
|
||||
# TESM — Installer/Updater
|
||||
# Richtet System-Pakete, die Flask-App (systemd) sowie den Erreichbarkeits-
|
||||
# Check-Dienst (systemd + Timer) ein. Auszuführen als root, nachdem dieses
|
||||
# Repo z.B. nach /root/tesm geklont wurde.
|
||||
# Repo/Release-Paket z.B. nach /root/tesm entpackt wurde.
|
||||
#
|
||||
# Erkennt selbstständig, ob unter /srv/tesm bereits eine Installation
|
||||
# existiert (an sqlite.db), und verhält sich entsprechend:
|
||||
#
|
||||
# - Keine vorhandene Installation -> normale Frischinstallation.
|
||||
# - Vorhanden, SCHEMA_VERSION unverändert -> einfaches In-Place-Update
|
||||
# (Code/Templates/Abhängigkeiten aktualisieren; sqlite.db bleibt
|
||||
# unangetastet -- rsync schließt sie ohnehin aus). Kein Backup nötig,
|
||||
# da sich am Datenbank-Schema nichts ändert.
|
||||
# - Vorhanden, SCHEMA_VERSION unbekannt oder abweichend -> Update MIT
|
||||
# Sicherheitsnetz: die komplette bisherige Installation (Code, venv,
|
||||
# Datenbank, Schlüssel) wird vorher 1:1 nach /srv/tesm-backup-pre-
|
||||
# migration-<timestamp> kopiert. Die eigentliche Schema-Migration
|
||||
# übernimmt danach die App selbst beim Start (siehe _ensure_schema()
|
||||
# in app.py). Kommt der Dienst anschließend nachweislich NICHT gesund
|
||||
# hoch (HTTP-Check auf /login), wird automatisch die komplette
|
||||
# Sicherung zurückgespielt (alter Code + alte Datenbank zusammen --
|
||||
# ein reines DB-Rollback allein würde denselben Migrationsfehler beim
|
||||
# nächsten Start mit dem neuen Code sofort wiederholen) und das
|
||||
# Backup bleibt zur manuellen Prüfung erhalten. Kommt er gesund hoch,
|
||||
# gilt die Migration als erfolgreich und das Backup wird gelöscht.
|
||||
# ============================================================================
|
||||
set -e
|
||||
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() { echo -e "${GREEN}✔${NC} ${1} completed."; }
|
||||
@@ -23,6 +45,41 @@ step() { echo -e "${RED}→${NC} ${1}..." | tee -a /var/log/tesm-install
|
||||
# nie fatal.
|
||||
clear 2>/dev/null || true
|
||||
|
||||
# ---- Bestehende Installation erkennen ----
|
||||
EXISTING_INSTALL=0
|
||||
[ -f /srv/tesm/sqlite.db ] && EXISTING_INSTALL=1
|
||||
|
||||
NEEDS_MIGRATION_GUARD=0
|
||||
BACKUP_DIR=""
|
||||
|
||||
if [ "$EXISTING_INSTALL" -eq 1 ]; then
|
||||
OLD_SCHEMA_VERSION=""
|
||||
[ -f /srv/tesm/SCHEMA_VERSION ] && OLD_SCHEMA_VERSION="$(tr -d '[:space:]' < /srv/tesm/SCHEMA_VERSION)"
|
||||
NEW_SCHEMA_VERSION=""
|
||||
[ -f "$REPO_DIR/srv/tesm/SCHEMA_VERSION" ] && NEW_SCHEMA_VERSION="$(tr -d '[:space:]' < "$REPO_DIR/srv/tesm/SCHEMA_VERSION")"
|
||||
|
||||
step "Stopping tesm.service for update"
|
||||
systemctl stop tesm.service tesm-check.service tesm-check-restart.timer 2>/dev/null || true
|
||||
print_status "Service stopped"
|
||||
|
||||
if [ -n "$OLD_SCHEMA_VERSION" ] && [ -n "$NEW_SCHEMA_VERSION" ] && [ "$OLD_SCHEMA_VERSION" == "$NEW_SCHEMA_VERSION" ]; then
|
||||
echo -e "${GREEN}Bestehende Installation erkannt, Datenbank-Schema unverändert (Version ${OLD_SCHEMA_VERSION}):${NC} einfaches In-Place-Update, kein Backup nötig."
|
||||
else
|
||||
if [ -n "$OLD_SCHEMA_VERSION" ] && [ -n "$NEW_SCHEMA_VERSION" ]; then
|
||||
reason="Datenbank-Schema hat sich geändert (${OLD_SCHEMA_VERSION} -> ${NEW_SCHEMA_VERSION})"
|
||||
else
|
||||
reason="Schema-Version der bestehenden Installation oder dieses Pakets unbekannt"
|
||||
fi
|
||||
echo -e "${YELLOW}Bestehende Installation erkannt, ${reason}:${NC}"
|
||||
echo "Update mit automatischer Migration und Sicherheitsnetz (Rückroll-Backup)."
|
||||
NEEDS_MIGRATION_GUARD=1
|
||||
BACKUP_DIR="/srv/tesm-backup-pre-migration-$(date +%Y%m%d-%H%M%S)"
|
||||
step "Backing up current installation to $BACKUP_DIR before migration"
|
||||
cp -a /srv/tesm "$BACKUP_DIR"
|
||||
print_status "Backup created"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---- Pakete ----
|
||||
step "Installing system packages"
|
||||
sudo apt-get update >>/var/log/tesm-install.log 2>&1 && print_status "apt update"
|
||||
@@ -107,4 +164,34 @@ sudo systemctl enable --now tesm.service
|
||||
sudo systemctl enable --now tesm-check.service tesm-check-restart.timer
|
||||
print_status "Services enabled and started"
|
||||
|
||||
# ---- Migrations-Sicherheitsnetz prüfen ----
|
||||
# Nur relevant, wenn oben tatsächlich eine riskante Migration (abweichende/
|
||||
# unbekannte SCHEMA_VERSION) erkannt wurde -- beim einfachen In-Place-Update
|
||||
# oder einer Frischinstallation ist BACKUP_DIR leer und dieser Block wird
|
||||
# komplett übersprungen.
|
||||
if [ "$NEEDS_MIGRATION_GUARD" -eq 1 ]; then
|
||||
step "Verifying migrated installation"
|
||||
HEALTHY=0
|
||||
for i in $(seq 1 15); do
|
||||
sleep 2
|
||||
if curl -fsS -o /dev/null http://127.0.0.1:5000/login 2>/dev/null; then
|
||||
HEALTHY=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$HEALTHY" -eq 1 ]; then
|
||||
print_status "Migration verified healthy"
|
||||
rm -rf "$BACKUP_DIR"
|
||||
echo -e "${GREEN}✔${NC} Migration erfolgreich -- Backup wieder entfernt."
|
||||
else
|
||||
echo -e "${RED}✖ Migration fehlgeschlagen -- Dienst antwortet nicht gesund. Rolle zurück...${NC}"
|
||||
sudo systemctl stop tesm.service 2>/dev/null || true
|
||||
sudo rm -rf /srv/tesm
|
||||
sudo mv "$BACKUP_DIR" /srv/tesm
|
||||
sudo systemctl start tesm.service
|
||||
echo -e "${YELLOW}Zurückgerollt auf den Stand vor dem Update (alter Code + alte Datenbank zusammen).${NC}"
|
||||
echo "Bitte /var/log/tesm/app.log prüfen oder Export/Import nutzen, bevor erneut aktualisiert wird."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✔${NC} Installation abgeschlossen. Web-App erreichbar auf Port 80 (nginx) bzw. 5000 (Flask direkt)."
|
||||
|
||||
Reference in New Issue
Block a user