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>
146 lines
5.1 KiB
Bash
Executable File
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)."
|