diff --git a/README.md b/README.md index 28924d1..ef483d9 100644 --- a/README.md +++ b/README.md @@ -135,3 +135,19 @@ Entwicklungsrepository, ebenso die Tests. * **CSRF-Schutz überhaupt.** Der Vorgänger hatte keinen. * **Rechte werden serverseitig geprüft**, nicht nur im Template ausgeblendet. * **Verschachtelte Datenbankverbindungen sind ein Fehler**, kein Deadlock. + +--- + +## Von einer Installation der Fassung 1.x + +Eine einzelne Datei genügt -- sie lädt das Release selbst: + +```bash +curl -fsSLO https://gitea.int.eertmoed.net/alientim/tesm-license/raw/branch/main/deploy/upgrade.sh +sudo bash upgrade.sh --app tesm-license +``` + +Sichert die alte Installation, schaltet sie ab, installiert diese Fassung und +übernimmt die Daten. Einzelheiten und was **nicht** mitkommt: +[docs/BETRIEB.md](docs/BETRIEB.md). + diff --git a/apps/tesm-license/pyproject.toml b/apps/tesm-license/pyproject.toml index a6cd590..d9c2088 100644 --- a/apps/tesm-license/pyproject.toml +++ b/apps/tesm-license/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm-license" -version = "2.0.8" +version = "2.0.9" description = "TESM-Lizenzserver -- Kunden, Tickets, Lizenzen, Aktivierung" requires-python = ">=3.11" dependencies = [ diff --git a/deploy/rename.sh b/deploy/rename.sh index 35ba529..d5ce500 100644 --- a/deploy/rename.sh +++ b/deploy/rename.sh @@ -3,8 +3,8 @@ # Benennt eine Installation um -- aus einer Instanz wird die Hauptinstallation # (oder umgekehrt). # -# sudo bash deploy/rename.sh --app tesm --from tesm-opus --to tesm -# sudo bash deploy/rename.sh --app tesm-license --from tesm-license-opus \ +# sudo bash deploy/rename.sh --app tesm --from tesm-test --to tesm +# sudo bash deploy/rename.sh --app tesm-license --from tesm-license-test \ # --to tesm-license # # Der Name steckt an mehr Stellen, als man beim Verschieben eines Verzeichnisses @@ -51,7 +51,7 @@ usage() { Verwendung: rename.sh --app --from --to [Optionen] --app Welche Anwendung (Pflicht) - --from Bisheriger Installationsname, z.B. tesm-opus (Pflicht) + --from Bisheriger Installationsname, z.B. tesm-test (Pflicht) --to Neuer Installationsname, z.B. tesm (Pflicht) --suffix Namenszusatz fuer eine beiseite geschobene Installation der Fassung 1.x (Vorgabe: sonnet5) diff --git a/deploy/tesm-helper b/deploy/tesm-helper index 70aee1d..4764687 100644 --- a/deploy/tesm-helper +++ b/deploy/tesm-helper @@ -47,7 +47,7 @@ check_in_list() { } # Name einer Installation auf diesem Host: entweder die Hauptinstallation -# ("tesm") oder eine benannte Instanz daneben ("tesm-opus"). Mehr als diese +# ("tesm") oder eine benannte Instanz daneben ("tesm-test"). Mehr als diese # beiden Formen gibt es nicht -- so kann keine erfundene Zeichenkette einen # Pfad ausserhalb des vorgesehenen Namensraums erzeugen. check_app_key() { diff --git a/deploy/update.sh b/deploy/update.sh index 08683cd..406a6e2 100644 --- a/deploy/update.sh +++ b/deploy/update.sh @@ -1,89 +1,127 @@ #!/usr/bin/env bash # ============================================================================= -# Bootstrapper: laedt ein Release herunter und ruft dessen install.sh auf. +# Aktualisierung: laedt das aktuelle Release 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. +# Eine einzelne Datei genuegt -- sie holt sich alles Weitere: +# +# curl -fsSLO https://gitea.int.eertmoed.net/alientim/tesm/raw/branch/main/deploy/update.sh +# sudo bash update.sh tesm +# +# Auf einer bestehenden Installation liegt sie schon bereit: +# +# sudo bash /srv/tesm/deploy/update.sh tesm # ============================================================================= set -euo pipefail -# Ein Wagenruecklauf im Paket macht jedes Shell-Skript auf dem Ziel -# unbrauchbar ("bad interpreter"). Die Pruefung darf dabei nicht selbst -# von einem Zusatzpaket abhaengen: mit "file" -- das auf einem schlanken -# Server fehlt -- endete sie in "command not found", grep bekam nichts zu -# sehen, und das Skript machte weiter, als waere alles in Ordnung. -hat_crlf() { - local cr - cr="$(printf '\r')" - # -U (binaer lesen) ist unter Linux ohne Wirkung, auf einer Windows-Buildmaschine - # aber entscheidend: dort entfernt grep den Wagenruecklauf beim Lesen und - # findet deshalb nie einen. - LC_ALL=C grep -qU "$cr" "$1" -} - APP="${1:-}" TAG="${2:-latest}" # Alles nach dem Tag geht unveraendert an install.sh weiter. Ohne das liesse # sich eine benannte Instanz nicht aktualisieren: install.sh leitet den Namen -# aus "--instance" ab, und ohne den Schalter entstuende neben "tesm-opus" eine +# aus "--instance" ab, und ohne den Schalter entstuende neben "tesm-test" eine # zweite Installation namens "tesm" -- mit eigener Datenbank, eigener # nginx-Site und demselben Port. shift $(( $# > 2 ? 2 : $# )) EXTRA=("$@") -# Bezugsquelle. Die Vorgaben zeigen dorthin, wo die Releases tatsaechlich -# liegen -- ein Platzhalter wie "gitea.example.invalid" macht das Skript auf -# jedem Host unbrauchbar, und genau das war hier der Fall. -# -# Das Repository heisst wie die Anwendung; getrennte Repositorien, getrennte -# Releases. Der Anhang heisst "-.tar.gz", siehe unten. -BASE="${TESM_RELEASE_BASE:-https://gitea.int.eertmoed.net}" -OWNER="${TESM_RELEASE_OWNER:-alientim}" [[ "$APP" == "tesm" || "$APP" == "tesm-license" ]] || { echo "Verwendung: update.sh [tag] [install.sh-Argumente ...]" >&2 - echo "Beispiel : update.sh tesm latest --instance opus" >&2 + echo "Beispiel : update.sh tesm latest --instance test" >&2 exit 2 } -REPO="${TESM_RELEASE_REPO:-$APP}" +# --8<-- Bootstrap: Release holen -------------------------------------------- +# Wortgleich in update.sh und upgrade.sh; ein Hygienetest vergleicht die beiden +# Bloecke. Zwei eigenstaendige Skripte koennen sich keine Datei teilen, und +# beide sollen als **einzelne Datei** genuegen: auf das Zielsystem legen, +# ausfuehren, fertig -- auf einer 1.2.8 liegt nichts von diesem Projekt. +# +# Erwartet: $APP und $TAG. Setzt: $TAG (aufgeloest) und $SRC (entpacktes +# Release). Raeumt sein Arbeitsverzeichnis beim Beenden auf. +# +# Zwei Fallen des Vorgaengers sind hier 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-Anhangs. +# * Nach dem Entpacken wird geprueft, dass ein install.sh existiert. +BASE="${TESM_RELEASE_BASE:-https://gitea.int.eertmoed.net}" +OWNER="${TESM_RELEASE_OWNER:-alientim}" -WORK="$(mktemp -d /tmp/tesm-update-XXXXXX)" -trap 'rm -rf "$WORK"' EXIT # anders als im Vorgaenger wird aufgeraeumt +# Ein Wagenruecklauf im Paket macht jedes Shell-Skript auf dem Ziel unbrauchbar +# ("bad interpreter"). Die Pruefung darf dabei nicht selbst von einem +# Zusatzpaket abhaengen: mit "file" -- das auf einem schlanken Server fehlt -- +# endete sie in "command not found", grep bekam nichts zu sehen, und das Skript +# machte weiter, als waere alles in Ordnung. +hat_crlf() { + local cr + cr="$(printf '\r')" + # -U (binaer lesen) ist unter Linux ohne Wirkung, auf einer + # Windows-Buildmaschine aber entscheidend: dort entfernt grep den + # Wagenruecklauf beim Lesen und findet deshalb nie einen. + LC_ALL=C grep -qU "$cr" "$1" +} -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 +BOOTSTRAP_WORK="" +bootstrap_aufraeumen() { [[ -n "$BOOTSTRAP_WORK" ]] && rm -rf "$BOOTSTRAP_WORK"; } +trap bootstrap_aufraeumen EXIT -ASSET="$REPO-$TAG.tar.gz" -echo "==> Lade $ASSET ..." -curl -fsSL -o "$WORK/$ASSET" "$BASE/$OWNER/$REPO/releases/download/$TAG/$ASSET" +release_holen() { + local repo="${TESM_RELEASE_REPO:-$APP}" asset + for werkzeug in curl tar python3 find; do + command -v "$werkzeug" >/dev/null 2>&1 || { + echo "Auf diesem System fehlt $werkzeug -- ohne das geht es nicht." >&2 + return 1 + } + done + BOOTSTRAP_WORK="$(mktemp -d /tmp/tesm-release-XXXXXX)" -echo "==> Entpacke ..." -tar -xzf "$WORK/$ASSET" -C "$WORK" -# Drei Ebenen, nicht zwei: release.sh packt mit dem Praefix "/", also -# liegt das Skript unter /deploy/install.sh. Mit "-maxdepth 2" fand die -# Suche nie etwas -- und die Fehlermeldung schob es auf den Download. -SRC="$(find "$WORK" -maxdepth 3 -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)" + 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 "Kein Release gefunden unter $BASE/$OWNER/$repo." >&2 + echo "Andere Quelle: TESM_RELEASE_BASE, TESM_RELEASE_OWNER, TESM_RELEASE_REPO." >&2 + return 1 + } + echo " $TAG" + fi -echo "==> Pruefe auf CRLF (Windows-Buildmaschinen) ..." -if hat_crlf "$SRC/deploy/install.sh"; then - echo "Das Paket enthaelt CRLF-Zeilenenden. Beim Paketieren fehlte" >&2 - echo "'git -c core.autocrlf=false archive'." >&2 - exit 1 -fi + asset="$repo-$TAG.tar.gz" + echo "==> Lade $asset ..." + curl -fsSL -o "$BOOTSTRAP_WORK/$asset" \ + "$BASE/$OWNER/$repo/releases/download/$TAG/$asset" || { + echo "Download fehlgeschlagen: $BASE/$OWNER/$repo/releases/download/$TAG/$asset" >&2 + return 1 + } + + echo "==> Entpacke ..." + tar -xzf "$BOOTSTRAP_WORK/$asset" -C "$BOOTSTRAP_WORK" + # Drei Ebenen, nicht zwei: release.sh packt mit dem Praefix "/", also + # liegt das Skript unter /deploy/install.sh. Mit "-maxdepth 2" fand die + # Suche nie etwas -- und die Fehlermeldung schob es auf den Download. + SRC="$(find "$BOOTSTRAP_WORK" -maxdepth 3 -name install.sh -path '*/deploy/*' \ + -printf '%h/..\n' | head -1)" + [[ -n "$SRC" ]] || { + echo "Im Paket fehlt deploy/install.sh -- Download unbrauchbar." >&2 + return 1 + } + SRC="$(cd "$SRC" && pwd)" + + echo "==> Pruefe auf CRLF (Windows-Buildmaschinen) ..." + if hat_crlf "$SRC/deploy/install.sh"; then + echo "Das Paket enthaelt CRLF-Zeilenenden. Beim Paketieren fehlte" >&2 + echo "'git -c core.autocrlf=false archive'." >&2 + return 1 + fi +} +# --8<-- Ende Bootstrap ------------------------------------------------------ + +release_holen read -r -p "Version $TAG fuer $APP${EXTRA[0]+ (${EXTRA[*]})} installieren? [j/N] " answer [[ "$answer" =~ ^[jJyY]$ ]] || exit 0 -exec sudo bash "$SRC/deploy/install.sh" --app "$APP" --yes ${EXTRA[0]+"${EXTRA[@]}"} +# Kein exec: sonst laeuft die Aufraeumfalle nie, und jedes Update liesse ein +# entpacktes Release unter /tmp liegen. +bash "$SRC/deploy/install.sh" --app "$APP" --yes ${EXTRA[0]+"${EXTRA[@]}"} diff --git a/deploy/upgrade.sh b/deploy/upgrade.sh index 531eed3..552f96b 100644 --- a/deploy/upgrade.sh +++ b/deploy/upgrade.sh @@ -2,10 +2,17 @@ # ============================================================================= # Upgrade vom Stand SONNET5 (Version 1.x) auf diese Fassung -- mit Datenuebernahme. # -# Aufruf (aus dem entpackten Release-Verzeichnis): +# Eine einzelne Datei genuegt -- sie holt sich das Release selbst: +# +# curl -fsSLO https://gitea.int.eertmoed.net/alientim/tesm/raw/branch/main/deploy/upgrade.sh +# sudo bash upgrade.sh --app tesm +# +# Auf einer 1.2.8 liegt nichts von diesem Projekt; alles andere waere die +# falsche Voraussetzung. Liegt das Skript in einem entpackten Release, wird +# dessen install.sh benutzt statt eines Downloads: +# # sudo bash deploy/upgrade.sh --app tesm -# sudo bash deploy/upgrade.sh --app tesm-license -# sudo bash deploy/upgrade.sh --app tesm --instance opus --source /srv/tesm +# sudo bash deploy/upgrade.sh --app tesm --instance test --source /srv/tesm # # Der Ablauf ist die Vorgabe und braucht keine Schalter: # @@ -44,9 +51,15 @@ DRY_RUN=0 WITH_DATA=1 STOP_OLD=1 ADOPT_KEY=1 +TAG="latest" #: Namenszusatz, unter dem ``rename.sh`` eine verdraengte Installation der #: Fassung 1.x ablegt. Beide Skripte muessen denselben Wert benutzen; ein #: Hygienetest vergleicht sie. +#: +#: Auf einer echten 1.2.8 gibt es das **nicht** -- dort liegt die Installation +#: unter ihrem Hauptnamen. Der Zusatz entsteht erst, wenn ``rename.sh`` den +#: Hauptnamen fuer die neue Fassung braucht. Deshalb ist er der zweite Ort, an +#: dem gesucht wird, nicht der erste. ARCHIV_SUFFIX="sonnet5" #: Nur fuer die Ausgabe: wurde die Quelle selbst gefunden oder angegeben? @@ -80,6 +93,8 @@ Verwendung: upgrade.sh --app [Optionen] erzeugen, statt den alten zu uebernehmen. Dann muessen alle Kunden den Ausstellerwechsel bestaetigen -- die Vorgabe ist deshalb die Uebernahme. + --tag Bestimmte Version installieren (Vorgabe: latest). + Wird nur beachtet, wenn das Release geladen wird. --dry-run Nur zeigen, was geschehen wuerde --yes Keine Rueckfrage -h, --help Diese Hilfe @@ -92,7 +107,7 @@ Beispiele: sudo bash deploy/upgrade.sh --app tesm # Daneben, zum Vergleich, alte Installation bleibt unangetastet: - sudo bash deploy/upgrade.sh --app tesm --instance opus --keep-old-running + sudo bash deploy/upgrade.sh --app tesm --instance test --keep-old-running USAGE } @@ -106,6 +121,7 @@ while [[ $# -gt 0 ]]; do --keep-old-running) STOP_OLD=0; shift ;; --new-key) ADOPT_KEY=0; shift ;; --adopt-key) ADOPT_KEY=1; shift ;; # Vorgabe, hier nur zur Deutlichkeit + --tag) TAG="${2:?}"; shift 2 ;; --dry-run) DRY_RUN=1; shift ;; --yes|-y) ASSUME_YES=1; shift ;; -h|--help) usage; exit 0 ;; @@ -115,7 +131,103 @@ done [[ "$APP" == "tesm" || "$APP" == "tesm-license" ]] || { usage; fail "--app fehlt oder ist unbekannt"; } [[ "$(id -u)" -eq 0 ]] || fail "bitte mit sudo ausfuehren" -[[ -f "$SCRIPT_DIR/install.sh" ]] || fail "install.sh fehlt neben diesem Skript" + +# --8<-- Bootstrap: Release holen -------------------------------------------- +# Wortgleich in update.sh und upgrade.sh; ein Hygienetest vergleicht die beiden +# Bloecke. Zwei eigenstaendige Skripte koennen sich keine Datei teilen, und +# beide sollen als **einzelne Datei** genuegen: auf das Zielsystem legen, +# ausfuehren, fertig -- auf einer 1.2.8 liegt nichts von diesem Projekt. +# +# Erwartet: $APP und $TAG. Setzt: $TAG (aufgeloest) und $SRC (entpacktes +# Release). Raeumt sein Arbeitsverzeichnis beim Beenden auf. +# +# Zwei Fallen des Vorgaengers sind hier 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-Anhangs. +# * Nach dem Entpacken wird geprueft, dass ein install.sh existiert. +BASE="${TESM_RELEASE_BASE:-https://gitea.int.eertmoed.net}" +OWNER="${TESM_RELEASE_OWNER:-alientim}" + +# Ein Wagenruecklauf im Paket macht jedes Shell-Skript auf dem Ziel unbrauchbar +# ("bad interpreter"). Die Pruefung darf dabei nicht selbst von einem +# Zusatzpaket abhaengen: mit "file" -- das auf einem schlanken Server fehlt -- +# endete sie in "command not found", grep bekam nichts zu sehen, und das Skript +# machte weiter, als waere alles in Ordnung. +hat_crlf() { + local cr + cr="$(printf '\r')" + # -U (binaer lesen) ist unter Linux ohne Wirkung, auf einer + # Windows-Buildmaschine aber entscheidend: dort entfernt grep den + # Wagenruecklauf beim Lesen und findet deshalb nie einen. + LC_ALL=C grep -qU "$cr" "$1" +} + +BOOTSTRAP_WORK="" +bootstrap_aufraeumen() { [[ -n "$BOOTSTRAP_WORK" ]] && rm -rf "$BOOTSTRAP_WORK"; } +trap bootstrap_aufraeumen EXIT + +release_holen() { + local repo="${TESM_RELEASE_REPO:-$APP}" asset + for werkzeug in curl tar python3 find; do + command -v "$werkzeug" >/dev/null 2>&1 || { + echo "Auf diesem System fehlt $werkzeug -- ohne das geht es nicht." >&2 + return 1 + } + done + BOOTSTRAP_WORK="$(mktemp -d /tmp/tesm-release-XXXXXX)" + + 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 "Kein Release gefunden unter $BASE/$OWNER/$repo." >&2 + echo "Andere Quelle: TESM_RELEASE_BASE, TESM_RELEASE_OWNER, TESM_RELEASE_REPO." >&2 + return 1 + } + echo " $TAG" + fi + + asset="$repo-$TAG.tar.gz" + echo "==> Lade $asset ..." + curl -fsSL -o "$BOOTSTRAP_WORK/$asset" \ + "$BASE/$OWNER/$repo/releases/download/$TAG/$asset" || { + echo "Download fehlgeschlagen: $BASE/$OWNER/$repo/releases/download/$TAG/$asset" >&2 + return 1 + } + + echo "==> Entpacke ..." + tar -xzf "$BOOTSTRAP_WORK/$asset" -C "$BOOTSTRAP_WORK" + # Drei Ebenen, nicht zwei: release.sh packt mit dem Praefix "/", also + # liegt das Skript unter /deploy/install.sh. Mit "-maxdepth 2" fand die + # Suche nie etwas -- und die Fehlermeldung schob es auf den Download. + SRC="$(find "$BOOTSTRAP_WORK" -maxdepth 3 -name install.sh -path '*/deploy/*' \ + -printf '%h/..\n' | head -1)" + [[ -n "$SRC" ]] || { + echo "Im Paket fehlt deploy/install.sh -- Download unbrauchbar." >&2 + return 1 + } + SRC="$(cd "$SRC" && pwd)" + + echo "==> Pruefe auf CRLF (Windows-Buildmaschinen) ..." + if hat_crlf "$SRC/deploy/install.sh"; then + echo "Das Paket enthaelt CRLF-Zeilenenden. Beim Paketieren fehlte" >&2 + echo "'git -c core.autocrlf=false archive'." >&2 + return 1 + fi +} +# --8<-- Ende Bootstrap ------------------------------------------------------ + +# Woher kommt install.sh? Liegt dieses Skript in einem entpackten Release, +# nimm dessen Verzeichnis -- wer ein Paket ausgepackt hat, will nicht, dass +# ungefragt ein anderes geladen wird. Sonst hol das Release. +if [[ -f "$SCRIPT_DIR/install.sh" ]]; then + SRC="$REPO_DIR" + RELEASE_HERKUNFT="$SRC (entpacktes Release neben diesem Skript)" +else + release_holen || fail "Das Release liess sich nicht holen." + RELEASE_HERKUNFT="$TAG von $BASE/$OWNER" +fi # -- Wo liegt die alte Fassung? ---------------------------------------------- # # Zwei Orte kommen in Frage, und der zweite ist der Grund fuer diesen Block: @@ -132,8 +244,9 @@ if [[ -z "$SOURCE" ]]; then done if [[ -z "$SOURCE" ]]; then warn "Keine Installation der Fassung 1.x gefunden. Gesucht wurde in:" - warn " /srv/$APP" - warn " /srv/$APP-$ARCHIV_SUFFIX (dorthin verschiebt rename.sh sie)" + warn " /srv/$APP (dort liegt sie normalerweise)" + warn " /srv/$APP-$ARCHIV_SUFFIX (dorthin verschiebt rename.sh sie, falls" + warn " der Hauptname schon vergeben war)" [[ -f "/srv/$APP/data/app.db" ]] && warn "Unter /srv/$APP liegt die laufende Installation dieser Fassung." fail "Bitte --source setzen." fi @@ -166,6 +279,7 @@ fi step "Vorhaben" info "Anwendung : $APP${INSTANCE:+ (Instanz $INSTANCE)}" +info "Neue Fassung : $RELEASE_HERKUNFT" info "Alt : $SOURCE${info_quelle:+ (automatisch gefunden)}" info "Neu : $NEW_ROOT$([[ $IN_PLACE -eq 1 ]] && echo ' << dasselbe Verzeichnis')" info "Sicherung : $ALT_KOPIE" @@ -214,7 +328,7 @@ fi step "Neu installieren" INSTALL_ARGS=(--app "$APP" --yes) [[ -n "$INSTANCE" ]] && INSTALL_ARGS+=(--instance "$INSTANCE") -bash "$SCRIPT_DIR/install.sh" "${INSTALL_ARGS[@]}" ${EXTRA[0]+"${EXTRA[@]}"} +bash "$SRC/deploy/install.sh" "${INSTALL_ARGS[@]}" ${EXTRA[0]+"${EXTRA[@]}"} if [[ $WITH_DATA -eq 0 ]]; then step "Fertig -- ohne Datenuebernahme" diff --git a/docs/BETRIEB.md b/docs/BETRIEB.md index 5af5553..d6c8991 100644 --- a/docs/BETRIEB.md +++ b/docs/BETRIEB.md @@ -105,19 +105,26 @@ Eine bereits eingerichtete HTTPS-Konfiguration bleibt erhalten, auch ohne ### Ohne Quellbaum: `update.sh` -Liegt kein entpacktes Release vor, holt `update.sh` es selbst -- es lädt das -Release-Asset, entpackt es und ruft dessen `install.sh` auf: +`update.sh` genügt als **einzelne Datei**. Auf einem System, auf dem noch nichts +von diesem Projekt liegt: ```bash -sudo bash /opt/tesm/deploy/update.sh tesm -sudo bash /opt/tesm-license/deploy/update.sh tesm-license +curl -fsSLO https://gitea.int.eertmoed.net/alientim/tesm/raw/branch/main/deploy/update.sh +sudo bash update.sh tesm +``` + +Auf einer bestehenden Installation liegt sie schon bereit: + +```bash +sudo bash /srv/tesm/deploy/update.sh tesm +sudo bash /srv/tesm-license/deploy/update.sh tesm-license ``` Alles nach dem Tag geht unverändert an `install.sh` weiter -- das ist der Weg, eine **benannte Instanz** zu aktualisieren: ```bash -sudo bash /opt/tesm-opus/deploy/update.sh tesm latest --instance opus +sudo bash /srv/tesm/deploy/update.sh tesm ``` Ohne `--instance` entstünde daneben eine zweite Installation namens `tesm`, mit @@ -147,11 +154,26 @@ Ein eigenes Skript, weil dabei mehr passiert als ein Dateiabgleich: die alte Fassung hat ein anderes Schema, andere Rechteschlüssel und ein anderes Exportformat. +Auch `upgrade.sh` genügt als **einzelne Datei** -- und das ist hier der +Regelfall: auf einer 1.2.8 liegt nichts von dieser Fassung. + +```bash +curl -fsSLO https://gitea.int.eertmoed.net/alientim/tesm/raw/branch/main/deploy/upgrade.sh +sudo bash upgrade.sh --app tesm +``` + +Sie lädt das aktuelle Release, entpackt es und benutzt dessen `install.sh`. +Liegt das Skript in einem entpackten Release, wird dieses benutzt statt eines +Downloads -- wer ein Paket ausgepackt hat, will nicht, dass ungefragt ein +anderes geladen wird: + ```bash sudo bash deploy/upgrade.sh --app tesm sudo bash deploy/upgrade.sh --app tesm-license ``` +Eine bestimmte Version statt `latest`: `--tag v2.0.8`. + Ohne `--source` wird die alte Fassung an zwei Stellen gesucht: unter `/srv/` und unter `/srv/-sonnet5`. Der zweite Ort ist der, an den `rename.sh` sie verschiebt, sobald der Hauptname für die neue Installation @@ -184,7 +206,7 @@ Export des Vorgängers und taugt deshalb auch als Rückweg. und die alte bleibt vollständig liegen: ```bash -sudo bash deploy/upgrade.sh --app tesm --instance opus --keep-old-running --port 5100 --http-port 8080 +sudo bash deploy/upgrade.sh --app tesm --instance test --keep-old-running --port 5100 --http-port 8080 ``` **Was nicht mitkommt** -- und warum: @@ -280,7 +302,7 @@ die niemand mehr füllte. Von Hand prüfen: ```bash -sudo /usr/local/lib/tesm/tesm-motd --app tesm --root /srv/tesm-opus +sudo /usr/local/lib/tesm/tesm-motd --app tesm --root /srv/tesm-test ``` Der Aufruf im Banner ist mit `timeout 3` und `|| true` abgesichert: ein @@ -295,8 +317,8 @@ entfernt -- nur dieses, nichts anderes in dem Verzeichnis. Aus einer Instanz die Hauptinstallation machen (oder umgekehrt): ```bash -sudo bash deploy/rename.sh --app tesm --from tesm-opus --to tesm -sudo bash deploy/rename.sh --app tesm-license --from tesm-license-opus --to tesm-license +sudo bash deploy/rename.sh --app tesm --from tesm-test --to tesm +sudo bash deploy/rename.sh --app tesm-license --from tesm-license-test --to tesm-license ``` Der Name steckt an mehr Stellen als im Verzeichnisnamen, und drei davon sind diff --git a/packages/tesm-core/pyproject.toml b/packages/tesm-core/pyproject.toml index 2fc263f..730dc51 100644 --- a/packages/tesm-core/pyproject.toml +++ b/packages/tesm-core/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm-core" -version = "2.0.8" +version = "2.0.9" description = "Gemeinsames Anwendungsgeruest (Auth, RBAC, Navigation, Design-System, Migrationen) fuer TESM und TESM-Lizenzserver" requires-python = ">=3.11" dependencies = [ diff --git a/packages/tesm-core/src/tesm_core/app_factory.py b/packages/tesm-core/src/tesm_core/app_factory.py index a240aae..94d1840 100644 --- a/packages/tesm-core/src/tesm_core/app_factory.py +++ b/packages/tesm-core/src/tesm_core/app_factory.py @@ -134,7 +134,7 @@ def create_base_app( #: Wortmarke, ohne Zeile darunter; die Marke selbst zeigen beide #: Anwendungen. auth_tagline: str = "", - app_version: str = "2.0.8", + app_version: str = "2.0.9", built_in_trusted_keys: tuple[str, ...] = (), enable_license: bool = True, template_folder: str | None = None, diff --git a/packages/tesm-core/src/tesm_core/config.py b/packages/tesm-core/src/tesm_core/config.py index 9f7856a..1962bcb 100644 --- a/packages/tesm-core/src/tesm_core/config.py +++ b/packages/tesm-core/src/tesm_core/config.py @@ -76,7 +76,7 @@ class CoreConfig: """Technischer Kurzname, z. B. ``tesm`` -- Namensraum fuer Pfade und Units.""" site_key: str - """Name *dieser Installation* auf dem Host, z. B. ``tesm-opus``. + """Name *dieser Installation* auf dem Host, z. B. ``tesm-test``. Weicht vom ``app_key`` ab, sobald neben der Hauptinstallation eine zweite Instanz laeuft. Alles, was ausserhalb von ``/srv/`` liegt und damit diff --git a/packages/tesm-licensing-server/pyproject.toml b/packages/tesm-licensing-server/pyproject.toml index 864ab87..b278b98 100644 --- a/packages/tesm-licensing-server/pyproject.toml +++ b/packages/tesm-licensing-server/pyproject.toml @@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta" [project] name = "tesm-licensing-server" -version = "2.0.8" +version = "2.0.9" description = "Serverhaelfte des TESM-Lizenzprotokolls: ausstellen, erneuern, antworten" requires-python = ">=3.11" -dependencies = ["tesm-licensing==2.0.8", "cryptography>=41"] +dependencies = ["tesm-licensing==2.0.9", "cryptography>=41"] [tool.setuptools.packages.find] where = ["src"] diff --git a/packages/tesm-licensing/pyproject.toml b/packages/tesm-licensing/pyproject.toml index 1f70433..b2fe289 100644 --- a/packages/tesm-licensing/pyproject.toml +++ b/packages/tesm-licensing/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm-licensing" -version = "2.0.8" +version = "2.0.9" description = "Ed25519-basiertes Lizenz- und Aktivierungsprotokoll fuer TESM und TESM-Lizenzserver" requires-python = ">=3.11" dependencies = ["cryptography>=42"]