Vollstaendiger Neubau der Anwendung. Der vorherige Stand bleibt unveraendert im Zweig SONNET5 erhalten. Aufbau: apps/tesm (Anwendung), packages/tesm-core (gemeinsamer Kern), packages/tesm-licensing (Lizenzprotokoll), deploy (Installation, systemd, privilegierter Helfer), docs, tests. Der Lizenzserver liegt in seinem eigenen Repository; beide Repositorien bringen die gemeinsamen Pakete mit, damit sich jedes allein installieren laesst. Die wichtigsten Unterschiede zum Vorgaenger, jeweils an der Stelle im Code kommentiert, an der der Fehler entstanden ist: * Der Webprozess laeuft unprivilegiert. Alles, was Root braucht, geht ueber einen einzigen Helfer mit Positivlisten fuer jedes Argument. * CSRF-Schutz ueberhaupt -- der Vorgaenger hatte keinen. * Rechte werden serverseitig geprueft, nicht nur im Template ausgeblendet. * Die nginx-Site wird bei jedem Lauf inhaltlich verglichen und erneuert. * Jede erzeugte Konfiguration wird vor dem Uebernehmen geprueft (nginx, Kea). * Kein Hostname im Lizenz-Fingerabdruck. * Zwei Installationen auf einem Host stoeren sich nicht (eigener SITE_KEY). * Verschachtelte Datenbankverbindungen sind ein Fehler, kein Deadlock. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
57 lines
2.2 KiB
Bash
57 lines
2.2 KiB
Bash
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# Bootstrapper: laedt ein Release herunter und ruft dessen install.sh auf.
|
|
# Enthaelt selbst keinerlei Installationslogik.
|
|
#
|
|
# Zwei Fallen des Vorgaengers sind hier bewusst vermieden:
|
|
# * Der Tag "latest" wird ueber die API aufgeloest, nie direkt in die
|
|
# Download-URL geschrieben. Gitea liefert sonst mit HTTP 200 ein
|
|
# automatisch erzeugtes Quell-Snapshot statt des echten Release-Assets.
|
|
# * Nach dem Entpacken wird geprueft, dass ein install.sh existiert -- faengt
|
|
# denselben Fehler ein zweites Mal ab.
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
APP="${1:-}"
|
|
TAG="${2:-latest}"
|
|
BASE="${TESM_RELEASE_BASE:-https://gitea.example.invalid}"
|
|
OWNER="${TESM_RELEASE_OWNER:-wis}"
|
|
REPO="${TESM_RELEASE_REPO:-tesm}"
|
|
|
|
[[ "$APP" == "tesm" || "$APP" == "tesm-license" ]] || {
|
|
echo "Verwendung: update.sh <tesm|tesm-license> [tag]" >&2
|
|
exit 2
|
|
}
|
|
|
|
WORK="$(mktemp -d /tmp/tesm-update-XXXXXX)"
|
|
trap 'rm -rf "$WORK"' EXIT # anders als im Vorgaenger wird aufgeraeumt
|
|
|
|
if [[ "$TAG" == "latest" ]]; then
|
|
echo "==> Ermittle aktuellen Release-Tag ..."
|
|
TAG="$(curl -fsS "$BASE/api/v1/repos/$OWNER/$REPO/releases/latest" \
|
|
| python3 -c 'import json,sys; print(json.load(sys.stdin)["tag_name"])')"
|
|
echo " $TAG"
|
|
fi
|
|
|
|
ASSET="$REPO-$TAG.tar.gz"
|
|
echo "==> Lade $ASSET ..."
|
|
curl -fsSL -o "$WORK/$ASSET" "$BASE/$OWNER/$REPO/releases/download/$TAG/$ASSET"
|
|
|
|
echo "==> Entpacke ..."
|
|
tar -xzf "$WORK/$ASSET" -C "$WORK"
|
|
SRC="$(find "$WORK" -maxdepth 2 -name install.sh -path '*/deploy/*' -printf '%h/..\n' | head -1)"
|
|
[[ -n "$SRC" ]] || { echo "Im Paket fehlt deploy/install.sh -- Download unbrauchbar." >&2; exit 1; }
|
|
SRC="$(cd "$SRC" && pwd)"
|
|
|
|
echo "==> Pruefe auf CRLF (Windows-Buildmaschinen) ..."
|
|
if file "$SRC/deploy/install.sh" | grep -q CRLF; then
|
|
echo "Das Paket enthaelt CRLF-Zeilenenden. Beim Paketieren fehlte" >&2
|
|
echo "'git -c core.autocrlf=false archive'." >&2
|
|
exit 1
|
|
fi
|
|
|
|
read -r -p "Version $TAG fuer $APP installieren? [j/N] " answer
|
|
[[ "$answer" =~ ^[jJyY]$ ]] || exit 0
|
|
|
|
exec sudo bash "$SRC/deploy/install.sh" --app "$APP" --yes
|