Files
patrickandClaude Sonnet 5.5 15676a3600
test / pytest (3.11) (push) Waiting to run
test / pytest (3.13) (push) Waiting to run
feat: Preflight-Checks und VM-Tauglichkeit des Setups
deploy/lib/preflight.sh prüft Python, venv, Platz, Betriebssystem, Umgebung
(VM/Container), pypi und optional Checkmk/Ollama per TCP. first-run.sh und
setup-lxc.sh rufen ihn auf (--skip-preflight, --preflight-only). LXC-Teile
nur bei erkanntem Container; Texte neutral; README um VM-Abschnitt ergänzt.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 15:09:53 +01:00

146 lines
5.1 KiB
Bash
Executable File

#!/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 <<EOF
Aufruf: deploy/first-run.sh [--venv <verzeichnis>] [--out <verzeichnis>] [--skip-preflight | --preflight-only]
--venv <dir> Dev-venv (Standard: \$HOME/checkbot-test-venv)
--out <dir> 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)."