espo-deploy/rmm-tasks/ESPO-13-Secrets-setzen.sh
Gordon Zimm f75c62224f ESPO-13-Secrets-setzen, ESPO-30-Extension-Installieren, espo_extensions
ESPO-13 legt Secrets unter /srv/espo/secrets ab (vorerst
gitea_package_token). Je Secret ein Parameter; leer oder woertlicher
Platzhalter laesst den Bestand. Erst Format und Funktion aller Werte
pruefen (Probeabruf der Registry), dann atomar schreiben - ein falscher
Token ersetzt keinen funktionierenden. Getestet: gesetzt, unveraendert,
falsches Format, abgelehnter Token.

ESPO-30 holt <extension> <version> aus der Package Registry
EspoCRM_Packages: SHA-256 gegen die Registry, Name und Version gegen das
Manifest, kein Rueckschritt, Snapshot srv-vor-update vor dem Download,
Installation per command.php als www-data, Neustart und Warten auf
healthy, Nachweis ueber --list. Danach liegt keine ZIP mehr auf der VM -
auch EspoCRMs eigene Archive in data/upload/extensions werden entfernt;
Update und Deinstallation brauchen sie nicht (Quelle 10.0.8).

ESPO-20 misst espo_extensions ("Name Version; ...", "none" wenn leer) und
beschreibt den Leseweg der Version wieder richtig. Ring 0 sperrt den
Extension-Upload in der Oberflaeche. README: Nummernkreise nachgezogen,
verrutschte Zeilen der Verzeichnistabelle zurueckgeholt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 13:58:35 +02:00

87 lines
3.7 KiB
Bash

#!/bin/bash
# ESPO-13-Secrets-setzen - legt Secrets auf der VM ab oder aktualisiert sie.
# Aufruf ueber den RMM-Task, der jeden Wert per Heredoc einliest und als Umgebungsvariable uebergibt -
# nie als Argument, denn Argumente stehen in der Prozessliste.
# Ein leerer Wert oder ein nicht ersetzter Platzhalter (@Name@) laesst das bestehende Secret unveraendert.
# Geschrieben wird erst, wenn alle uebergebenen Werte geprueft sind - alles oder nichts.
set -u
# Standzeile: zeigt im Protokoll, welche Fassung tatsaechlich gelaufen ist.
echo "ESPO-13-Secrets-setzen, Skriptstand 2026-09-30"
ZIEL=/srv/espo/secrets
GITEA=https://gitea.subcura.net
GITEA_BENUTZER=system
# Bekannte Secrets in der Reihenfolge der Ausgabe: Datei|Umgebungsvariable|Format.
# Ein neues Secret ist eine Zeile hier und ein Parameter im Task.
SECRETS='
gitea_package_token|ESPO_GITEA_PACKAGE_TOKEN|^[0-9a-f]{40}$
'
fehler() { echo "FEHLER: $*"; echo "ESPO13_ERGEBNIS: FEHLER"; exit 1; }
# Das RMM setzt einen leer gelassenen Parameter wortwoertlich als @Name@ ein (gemessen 30.09.2026).
nicht_uebergeben() { [ -z "$1" ] || [[ "$1" =~ ^@[A-Za-z0-9_]+@$ ]]; }
# Probeabruf der Package Registry mit einem Token. Der Token geht als netrc ueber einen Dateideskriptor
# an curl und erscheint so weder in der Prozessliste noch in der Ausgabe. Liefert den HTTP-Code.
registry_probe() {
curl -s -o /dev/null -w '%{http_code}' --max-time 20 \
--netrc-file <(printf 'machine gitea.subcura.net login %s password %s\n' "$GITEA_BENUTZER" "$1") \
"$GITEA/api/v1/packages/EspoCRM_Packages?type=generic&limit=1"
}
# Funktionspruefung je Secret, zusaetzlich zum Format. Gibt 0 zurueck, wenn der Wert traegt.
funktioniert() { # funktioniert <name> <wert>
local code
case "$1" in
gitea_package_token)
code="$(registry_probe "$2")"
[ "$code" = "200" ] && return 0
[ "$code" = "000" ] && echo " $1: Gitea nicht erreichbar" || echo " $1: Registry lehnt den Token ab (HTTP $code)"
return 1 ;;
esac
return 0
}
[ "$(id -u)" -eq 0 ] || fehler "nicht als root gestartet"
# 1. Alle uebergebenen Werte pruefen: erst das Format, dann ob sie tatsaechlich funktionieren.
# Ein Token mit gueltigem Format, der nicht traegt, soll keinen funktionierenden ersetzen.
ZU_SCHREIBEN=" "
while IFS='|' read -r NAME VAR FORMAT; do
[ -n "$NAME" ] || continue
WERT="${!VAR-}"
nicht_uebergeben "$WERT" && continue
[[ "$WERT" =~ $FORMAT ]] || fehler "$NAME hat nicht das erwartete Format - es wurde nichts geschrieben"
funktioniert "$NAME" "$WERT" || fehler "$NAME funktioniert nicht - es wurde nichts geschrieben"
ZU_SCHREIBEN="$ZU_SCHREIBEN$NAME "
done <<< "$SECRETS"
# 2. Schreiben: atomar ueber eine temporaere Datei im selben Verzeichnis, Rechte 0600, ohne Zeilenumbruch.
install -d -m 0700 "$ZIEL" || fehler "Verzeichnis $ZIEL nicht anlegbar"
FEHLT=0
while IFS='|' read -r NAME VAR FORMAT; do
[ -n "$NAME" ] || continue
if [[ "$ZU_SCHREIBEN" == *" $NAME "* ]]; then
TMP="$(mktemp "$ZIEL/.$NAME.XXXXXX")" || fehler "temporaere Datei fuer $NAME nicht anlegbar"
if printf '%s' "${!VAR}" > "$TMP" && chmod 0600 "$TMP" && mv -f "$TMP" "$ZIEL/$NAME"; then
echo "$NAME: gesetzt"
else
rm -f "$TMP"; fehler "$NAME nicht geschrieben"
fi
elif [ -s "$ZIEL/$NAME" ]; then
# Unveraendert heisst nicht ungeprueft: ein vorhandenes Secret, das nicht mehr traegt, ist ein Fehler.
if funktioniert "$NAME" "$(cat "$ZIEL/$NAME")"; then
echo "$NAME: unveraendert, funktioniert"
else
echo "$NAME: unveraendert, funktioniert NICHT"; FEHLT=1
fi
else
echo "$NAME: fehlt - weder vorhanden noch uebergeben"; FEHLT=1
fi
done <<< "$SECRETS"
if [ "$FEHLT" -eq 0 ]; then echo "ESPO13_ERGEBNIS: OK"; exit 0; else echo "ESPO13_ERGEBNIS: FEHLER"; exit 1; fi