#!/usr/bin/env bash # Erster Testlauf: Dev-venv anlegen, Import und Templates prüfen, pytest vollständig laufen lassen # und die Ergebnisse (ohne Secrets) in ein Archiv packen. Braucht kein root. set -euo pipefail VENV="${HOME}/checkbot-test-venv" OUT="$(pwd)" REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" SKIP_PREFLIGHT=0 PREFLIGHT_ONLY=0 # shellcheck source=lib/preflight.sh source "$REPO_DIR/deploy/lib/preflight.sh" usage() { cat <] [--out ] [--skip-preflight | --preflight-only] --venv Dev-venv (Standard: \$HOME/checkbot-test-venv) --out Zielverzeichnis des Archivs (Standard: aktuelles Verzeichnis) --skip-preflight Preflight-Prüfungen überspringen --preflight-only nur die Preflight-Prüfungen ausführen und beenden Optional per Umgebung: CHECKMK_URL und OLLAMA_URL (nur Host:Port wird per TCP auf Erreichbarkeit geprüft). EOF } die() { echo "FEHLER: $*" >&2 exit 1 } while [ $# -gt 0 ]; do case "$1" in --venv) [ $# -ge 2 ] || die "--venv braucht ein Verzeichnis"; VENV="$2"; shift 2 ;; --out) [ $# -ge 2 ] || die "--out braucht ein Verzeichnis"; OUT="$2"; shift 2 ;; --skip-preflight) SKIP_PREFLIGHT=1; shift ;; --preflight-only) PREFLIGHT_ONLY=1; shift ;; -h|--help) usage; exit 0 ;; *) usage >&2; die "Unbekannte Option: $1" ;; esac done [ "$SKIP_PREFLIGHT$PREFLIGHT_ONLY" != 11 ] || die "--skip-preflight und --preflight-only schließen sich aus" [ -f "$REPO_DIR/requirements-dev.txt" ] || die "requirements-dev.txt nicht gefunden in $REPO_DIR" WORK="$(mktemp -d)" PIP_LOG="$(mktemp)" trap 'rm -rf "$WORK" "$PIP_LOG"' EXIT PREFLIGHT_STATUS=übersprungen if [ "$SKIP_PREFLIGHT" -eq 0 ]; then echo "== Preflight" PF_REPORT="$WORK/preflight.txt" if preflight_run "$(dirname "$VENV")" "$OUT"; then PREFLIGHT_STATUS=ok else PREFLIGHT_STATUS=FEHLER fi if [ "$PREFLIGHT_ONLY" -eq 1 ] || [ "$PREFLIGHT_STATUS" = FEHLER ]; then [ "$PREFLIGHT_STATUS" = ok ] || die "Preflight fehlgeschlagen, siehe FEHLER-Zeilen oben (--skip-preflight übergeht die Prüfung)" exit 0 fi elif [ "$PREFLIGHT_ONLY" -eq 1 ]; then die "--preflight-only ohne Preflight ergibt nichts" fi command -v python3 >/dev/null 2>&1 || die "python3 fehlt (apt-get install python3 python3-venv python3-pip)" mkdir -p "$OUT" || die "Zielverzeichnis $OUT nicht anlegbar" OUT="$(cd "$OUT" && pwd)" echo "== 1/6 Dev-venv: $VENV" if [ ! -x "$VENV/bin/python" ]; then python3 -m venv "$VENV" || die "venv konnte nicht angelegt werden (apt-get install python3-venv)" fi echo "== 2/6 Abhängigkeiten installieren (requirements-dev.txt)" if ! "$VENV/bin/python" -m pip install --quiet -r "$REPO_DIR/requirements-dev.txt" >"$PIP_LOG" 2>&1; then tail -n 30 "$PIP_LOG" >&2 die "pip install fehlgeschlagen" fi cd "$REPO_DIR" echo "== 3/6 Import von app.main" IMPORT_STATUS=ok "$VENV/bin/python" -c "import app.main" >"$WORK/import.log" 2>&1 || IMPORT_STATUS=FEHLER echo " Ergebnis: $IMPORT_STATUS" echo "== 4/6 Jinja-Templates kompilieren" TEMPLATE_STATUS=ok "$VENV/bin/python" - >"$WORK/templates.log" 2>&1 <<'PY' || TEMPLATE_STATUS=FEHLER from app.web.deps import templates env = templates.env names = env.list_templates() failed = 0 for name in names: try: env.get_template(name) except Exception as exc: failed += 1 print(f"FEHLER {name}: {type(exc).__name__}: {exc}") print(f"{len(names)} Templates, {failed} Fehler") raise SystemExit(1 if failed else 0) PY echo " Ergebnis: $TEMPLATE_STATUS" echo "== 5/6 pytest -q (ohne -x, alle Fehler werden gesammelt)" PYTEST_STATUS=ok "$VENV/bin/python" -m pytest -q >"$WORK/pytest.log" 2>&1 || PYTEST_STATUS=FEHLER tail -n 3 "$WORK/pytest.log" | sed 's/^/ /' echo "== 6/6 Archiv packen" { echo "venv-python: $("$VENV/bin/python" --version 2>&1)" echo "system-python: $(python3 --version 2>&1)" } >"$WORK/python-version.txt" "$VENV/bin/python" -m pip freeze >"$WORK/pip-freeze.txt" 2>&1 || true uname -a >"$WORK/uname.txt" if git -C "$REPO_DIR" rev-parse --git-dir >/dev/null 2>&1; then { echo "revision: $(git -C "$REPO_DIR" rev-parse HEAD 2>/dev/null || echo unbekannt)" echo "branch: $(git -C "$REPO_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo unbekannt)" if [ -n "$(git -C "$REPO_DIR" status --porcelain 2>/dev/null)" ]; then echo "arbeitsverzeichnis: geaendert (nicht committete Aenderungen)" else echo "arbeitsverzeichnis: sauber" fi } >"$WORK/git-revision.txt" fi { echo "preflight: $PREFLIGHT_STATUS" echo "import: $IMPORT_STATUS" echo "templates: $TEMPLATE_STATUS" echo "pytest: $PYTEST_STATUS" } >"$WORK/summary.txt" ARCHIVE="$OUT/first-run-$(date +%Y%m%d-%H%M%S).tar.gz" tar -czf "$ARCHIVE" -C "$WORK" . echo echo "Import: $IMPORT_STATUS | Templates: $TEMPLATE_STATUS | pytest: $PYTEST_STATUS" echo "Archiv: $ARCHIVE" echo "Das Archiv enthält nur Logs und Versionsangaben (keine Umgebungsvariablen, Datenbanken oder Schlüssel)."