Add Nix package, NixOS module, and tests for bambuddy

- packages.bambuddy: FastAPI backend + prebuilt React frontend assembled
  into the app-root layout upstream expects, behind a single `bambuddy`
  launcher (uvicorn --loop asyncio, ffmpeg on PATH, XDG state defaults).
  Pins upstream maziggy/bambuddy v1.2.5.7.
- nixosModules.default: services.bambuddy with host/port/dataDir,
  openFirewall, environment + environmentFile, extraPackages,
  DynamicUser + StateDirectory, systemd hardening, and
  CAP_NET_BIND_SERVICE for the virtual-printer FTPS/RTSP ports.
- checks.bambuddy-import: backend import + admin CLI smoke test.
- checks.bambuddy-service: two-node NixOS VM test covering the health
  endpoint, UI/static assets/manifest, SQLite + logs in the
  StateDirectory, journal startup check, cross-node reachability with
  openFirewall, custom host/port/env node, and loopback-only binding.
- overlay, run app, devShell, README, .gitignore.
This commit is contained in:
0m.ax 2026-11-01 19:54:55 +01:00
commit 5fb8e8d724
9 changed files with 761 additions and 0 deletions

28
pkgs/bambuddy/wrapper.sh Normal file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Bambuddy launcher.
#
# Starts the FastAPI backend via uvicorn, mirroring the upstream Docker CMD
# (`uvicorn backend.app.main:app --loop asyncio`). PYTHONPATH points at the
# app root (@out@/share/bambuddy) which contains the `backend` package and
# the prebuilt `static/` frontend — the layout backend.app.core.config expects.
set -euo pipefail
# State locations. The NixOS module always sets these explicitly; the
# defaults keep a bare `bambuddy` invocation out of the read-only store.
export DATA_DIR="${DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bambuddy}"
export LOG_DIR="${LOG_DIR:-$DATA_DIR/logs}"
export HOME="${HOME:-$DATA_DIR}"
export MPLCONFIGDIR="${MPLCONFIGDIR:-$DATA_DIR/.cache/matplotlib}"
mkdir -p "$DATA_DIR" "$LOG_DIR" "$MPLCONFIGDIR"
export PYTHONPATH="@out@/share/bambuddy${PYTHONPATH:+:$PYTHONPATH}"
# `--loop asyncio` matches the upstream Dockerfile: uvloop has a TLS bug that
# can truncate VP FTP uploads. Override with UVICORN_LOOP=uvloop if desired.
exec "@pythonEnv@/bin/uvicorn" backend.app.main:app \
--host "${HOST:-0.0.0.0}" \
--port "${PORT:-8000}" \
--loop "${UVICORN_LOOP:-asyncio}" \
--timeout-graceful-shutdown "${UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN:-5}" \
"$@"