#!/bin/bash set -uo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" python3 - "$ROOT" <<'PY' import json import re import sys from pathlib import Path root = Path(sys.argv[1]) control = (root / "packaging/debian/control.template").read_text() postinst = (root / "packaging/debian/postinst").read_text() provision = (root / "scripts/classroom-provision").read_text() units = "\n".join(path.read_text() for path in (root / "systemd").rglob("*.service")) canary = (root / "update_canary.sh").read_text() policy = json.loads( (root / "config/chrome/policies/managed/ekklesia-classroom.json").read_text() ) passed = failed = 0 def check(label, condition): global passed, failed if condition: print(f" ok {label}") passed += 1 else: print(f" FAIL {label}") failed += 1 depends = re.search(r"^Depends: (.*)$", control, re.MULTILINE).group(1).split(", ") print("1. Trixie package contract") for package in ( "network-manager", "cups", "cups-client", "cups-filters", "foomatic-db-compressed-ppds", ): check(f"depends on {package}", package in depends) print() print("2. networking service behavior") check("NetworkManager is explicitly enabled", "systemctl enable NetworkManager.service || true" in postinst) check("NetworkManager start is best effort", "systemctl start NetworkManager.service || true" in postinst) check("online waiter is disabled", "systemctl disable NetworkManager-wait-online.service || true" in postinst) check("no classroom NetworkManager config overrides ifupdown", not (root / "config/network").exists()) print() print("3. printing service behavior") check("CUPS service and socket are enabled", "systemctl enable cups.socket cups.service || true" in postinst) check("CUPS start is best effort", "systemctl start cups.socket || true" in postinst) check("automatic remote queue browsing is disabled", "systemctl disable --now cups-browsed.service || true" in postinst) check("printer setup is never a boot service", "classroom-printer-setup" not in units) check("printer setup is never provisioning", "classroom-printer-setup" not in provision) check("Chrome uses the system print dialog", policy.get("DisablePrintPreview") is True) print() print("4. canary release gate") validation = canary.index('"$ROOT/tools/validate-trixie-release.sh"') package_copy = canary.index('cp "$package_path"') first_rsync = canary.index("rsync -av") check("Trixie validation runs before the repository copy", validation < package_copy) check("Trixie validation runs before any upload", validation < first_rsync) print() print(f"passed: {passed} failed: {failed}") raise SystemExit(1 if failed else 0) PY