#!/bin/bash # ============================================================================ # TESM — Update/Reinstall (Bootstrapper) # Lädt ein gepacktes Gitea-Release per HTTP herunter (kein "git clone" # nötig) und übergibt die eigentliche Installations-/Update-Logik an # install.sh aus dem Paket -- das erkennt selbstständig, ob unter # /srv/tesm schon eine Installation existiert, und aktualisiert sie # entsprechend (In-Place bei unverändertem Datenbank-Schema, sonst mit # automatischem Backup + Migrations-Sicherheitsnetz samt Rückroll- # Möglichkeit -- siehe install.sh für Details). # # Dieses Skript ist reiner Bootstrapper: Download + Entpacken + Aufruf von # install.sh. Die frühere Sonderbehandlung zweier TESM vorausgehender # Installationsstufen (rpi-check.service aus dem ursprünglichen reinen # Bash-Setup, poe_web.service/poe_manager als Flask-Vorgänger von TESM) # wurde entfernt -- diese Stufen sind auf allen aktuellen Installationen # längst migriert, die dazugehörigen Unit-Dateien wurden dort manuell # entfernt. Ein heute noch unmigriertes System wäre ohnehin so alt, dass # ein manueller Blick vor dem Update angebracht ist statt automatischer # stillschweigender Bereinigung. # # Auszuführen als root auf dem Zielsystem: # sudo ./update.sh # Optional übersteuerbar (z.B. für eine bestimmte Version statt "latest"): # TESM_RELEASE_TAG=v1.0.0 sudo -E ./update.sh # Für ein privates Repo wird ein Zugriffstoken benötigt: # TESM_GITEA_USER=alientim TESM_GITEA_TOKEN= sudo -E ./update.sh # ============================================================================ set -e GITEA_BASE="${TESM_GITEA_BASE:-https://gitea.int.eertmoed.net}" REPO_OWNER="${TESM_REPO_OWNER:-alientim}" REPO_NAME="${TESM_REPO_NAME:-tesm}" RELEASE_TAG="${TESM_RELEASE_TAG:-latest}" GITEA_USER="${TESM_GITEA_USER:-}" GITEA_TOKEN="${TESM_GITEA_TOKEN:-}" WORK_DIR="/tmp/tesm-update-$(date +%s)" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' if [ "$(id -u)" -ne 0 ]; then echo "Bitte als root ausführen (sudo ./update.sh)." >&2 exit 1 fi CURL_AUTH=() if [ -n "$GITEA_USER" ] && [ -n "$GITEA_TOKEN" ]; then CURL_AUTH=(-u "${GITEA_USER}:${GITEA_TOKEN}") fi # ---- "latest" IMMER über die Gitea-API auflösen, nie als Literal in die # Download-URL einsetzen ---- # Live reproduziert: /releases/download/latest/tesm-latest.tar.gz liefert # HTTP 200 -- aber keinen echten Release-Asset, sondern (weil kein Asset # exakt "tesm-latest.tar.gz" heißt) Giteas automatisch generiertes # Quellcode-Archiv des AKTUELLEN Default-Branch-Stands, kommentarlos und # ohne Fehlermeldung. Ohne diesen Auflösungsschritt würde ein einfaches # "sudo ./update.sh" (ohne explizites TESM_RELEASE_TAG) also lautlos einen # unversionierten, potenziell halbfertigen Zwischenstand installieren # statt des tatsächlich neuesten Releases. if [ "$RELEASE_TAG" == "latest" ]; then echo -e "${RED}→${NC} Ermittle aktuellsten Release-Tag von ${GITEA_BASE}/${REPO_OWNER}/${REPO_NAME}..." RESOLVED_TAG="$(curl -fsSL "${CURL_AUTH[@]}" "${GITEA_BASE}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/releases/latest" \ | python3 -c "import json,sys; print(json.load(sys.stdin).get('tag_name',''))" 2>/dev/null)" if [ -z "$RESOLVED_TAG" ]; then echo "✖ Konnte den aktuellsten Release-Tag nicht über die Gitea-API ermitteln -- Abbruch." >&2 echo " (Alternative: TESM_RELEASE_TAG=vX.Y.Z explizit setzen.)" >&2 exit 1 fi RELEASE_TAG="$RESOLVED_TAG" echo -e "${GREEN}✔${NC} Aktuellster Release ist ${RELEASE_TAG}." fi PACKAGE_NAME="tesm-${RELEASE_TAG}.tar.gz" DOWNLOAD_URL="${GITEA_BASE}/${REPO_OWNER}/${REPO_NAME}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}" PACKAGE_FILE="$WORK_DIR/${PACKAGE_NAME}" echo -e "${YELLOW}============================================================================${NC}" echo -e "${YELLOW} TESM Update/Reinstall — Release \"${RELEASE_TAG}\"${NC}" echo -e "${YELLOW}============================================================================${NC}" echo echo "Lädt das Release-Paket herunter und übergibt Installation/Update an" echo "install.sh daraus -- das erkennt selbst, ob es sich um eine frische" echo "Installation oder ein Update einer bestehenden handelt, und sichert" echo "die Datenbank bei einer Schema-Änderung automatisch vorsorglich ab." echo read -r -p "Fortfahren? [y/N] " confirm if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then echo "Abgebrochen — nichts wurde verändert." exit 0 fi echo -e "${RED}→${NC} Lade Paket von ${DOWNLOAD_URL}..." mkdir -p "$WORK_DIR" curl -fsSL "${CURL_AUTH[@]}" -o "$PACKAGE_FILE" "$DOWNLOAD_URL" echo -e "${GREEN}✔${NC} Paket heruntergeladen ($(du -h "$PACKAGE_FILE" | cut -f1))." echo -e "${RED}→${NC} Entpacke Paket..." mkdir -p "$WORK_DIR/pkg" tar xzf "$PACKAGE_FILE" -C "$WORK_DIR/pkg" --strip-components=1 # Absicherung gegen genau das oben beschriebene Fallback-Verhalten: statt # eines späten, kryptischen "No such file or directory" beim Aufruf von # install.sh hier klar benennen, WENN das heruntergeladene Paket nicht das # erwartete ist (z.B. weil sich Giteas Verhalten wieder ändert). if [ ! -f "$WORK_DIR/pkg/install.sh" ]; then echo "✖ Entpacktes Paket enthält kein install.sh -- vermutlich wurde nicht das" >&2 echo " erwartete Release-Asset heruntergeladen (siehe ${DOWNLOAD_URL})." >&2 exit 1 fi echo -e "${GREEN}✔${NC} Paket entpackt." echo -e "${RED}→${NC} Starte install.sh aus dem Paket..." bash "$WORK_DIR/pkg/install.sh" echo echo -e "${GREEN}============================================================================${NC}" echo -e "${GREEN} TESM Update/Reinstall (Release \"${RELEASE_TAG}\") abgeschlossen.${NC}" echo -e "${GREEN}============================================================================${NC}" echo "Siehe Ausgabe von install.sh oben für Details (In-Place-Update, frische" echo "Installation, oder Migrationsergebnis inkl. eventuellem Rückroll-Hinweis)."