Vollstaendiger Neubau der Anwendung. Der vorherige Stand bleibt unveraendert im Zweig SONNET5 erhalten. Aufbau: apps/tesm-license (Anwendung), packages/tesm-core (gemeinsamer Kern), packages/tesm-licensing (Lizenzprotokoll), deploy (Installation, systemd, privilegierter Helfer), docs, tests. Die verwaltete Anwendung liegt in ihrem eigenen Repository; beide Repositorien bringen die gemeinsamen Pakete mit, damit sich jedes allein installieren laesst. Die wichtigsten Unterschiede zum Vorgaenger: * Keine doppelte licensing.py -- ein Paket, das beide Anwendungen installieren, statt zweier Dateien, die byte-identisch bleiben sollen. * 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. * Keine Lizenz ohne master_endpoint: eine Ausstellung ohne Endpunkt wird abgelehnt statt eine Lizenz zu erzeugen, die sich nie aktivieren kann. * Offline-Aktivierung in beide Richtungen; die Lizenz bleibt als "Aktivierung offen" markiert, bis sie zurueckkommt. * Getrennte Signaturkontexte je Nachrichtenart, Nonce gegen Wiedereinspielung, seq gegen das Zurueckrollen auf eine aeltere Lizenz. * Kein Hostname im Maschinen-Fingerabdruck. * 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
|