M8-T20: document and validate WarmteLink deployment

This commit is contained in:
2026-08-23 21:28:26 +02:00
parent 5b9d60e80a
commit ebf96de4f1
10 changed files with 255 additions and 46 deletions
+32
View File
@@ -72,6 +72,38 @@ def test_compose_uses_migration_job_before_app() -> None:
assert dev["services"]["app"]["build"] == "."
def test_warmtelink_overlay_keeps_app_non_root_and_maps_minimal_serial_device_access() -> None:
"""The optional overlay grants only pyserial's minimal open permission.
Environment interpolation is deliberately left unresolved: operators supply
a host-specific stable by-id path and its numeric serial GID at deployment.
"""
base = _read_yaml("docker-compose.yml")
overlay = _read_yaml("docker-compose.warmtelink.yml")
base_app = base["services"]["app"]
base_migration = base["services"]["migration"]
app_overlay = overlay["services"]["app"]
assert base_app["user"] == "1000:1000"
assert base_migration["user"] == "1000:1000"
assert "privileged" not in base_app
assert "privileged" not in base_migration
assert "user" not in app_overlay
assert "privileged" not in app_overlay
assert app_overlay["devices"] == [
"${WARMTELINK_DEVICE_PATH:?Set a stable /dev/serial/by-id path}:/dev/warmtelink:rw"
]
device_rule = app_overlay["devices"][0]
permissions = device_rule.rsplit(":", maxsplit=1)[1]
assert permissions == "rw"
assert "m" not in permissions
assert app_overlay["group_add"] == ["${WARMTELINK_SERIAL_GID:?Set the host serial device GID}"]
assert "/dev/serial/by-id" in (PROJECT_ROOT / "docker-compose.warmtelink.yml").read_text()
assert "migration" not in overlay["services"]
assert "devices" not in base_migration
assert "privileged" not in base_migration
def test_image_defaults_to_uvicorn_only() -> None:
dockerfile = (PROJECT_ROOT / "Dockerfile").read_text()
entrypoint = (PROJECT_ROOT / "docker/entrypoint.sh").read_text()