feat(dev): enable isolated local workers and verified Ollama

This commit is contained in:
cesnimda
2026-10-27 11:55:31 +01:00
parent 663023a088
commit 73ea888375
9 changed files with 356 additions and 1 deletions
+74
View File
@@ -0,0 +1,74 @@
"""Guard and apply worker settings to the existing isolated local development stack."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import subprocess
ROOT = Path(__file__).resolve().parent.parent
SIDECAR = "sha256:8a29cb90fcc2817b0d784826d55a172c943f5ad7e1b6105e690a2d79ee15fe87"
def capture(arguments, environment):
return subprocess.check_output(["rtk", "proxy", *arguments], env=environment, text=True)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--checkout", type=Path, required=True)
parser.add_argument("--bart-artifact", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--apply", action="store_true")
args = parser.parse_args()
checkout = args.checkout.resolve()
artifact = args.bart_artifact.resolve()
environment = {**os.environ, "JOBTRACKER_DEV_BART_ARTIFACT": str(artifact)}
manifest = json.loads((ROOT / "docs/redesign/phase-9/p9-sec-02/full-model/ARTIFACTS.json").read_text())["weights-only"]
for row in manifest["files"]:
path = artifact / row["file"]
assert path.is_file() and path.stat().st_size == row["bytes"], "Local model file missing or wrong size"
with path.open("rb") as stream:
assert hashlib.file_digest(stream, "sha256").hexdigest() == row["sha256"], "Local model integrity mismatch"
assert json.loads((ROOT / ".artifacts/pre-phase10-ux/local-ai/verification.json").read_text())["status"] == "PASS"
compose = ["docker", "compose", "--project-directory", str(checkout), "--env-file", str(checkout / ".env.dev"),
"-f", str(checkout / "docker-compose.dev.yml"), "-f", str(ROOT / "dev/local-workers.override.yml")]
config = json.loads(capture([*compose, "config", "--format", "json"], environment))
assert config["name"] == "jobjakt-dev", "Only the local development project is permitted"
backend = config["services"]["backend"]
sidecar = config["services"]["ai-service"]
settings = backend["environment"]
assert settings["ASPNETCORE_ENVIRONMENT"] == "Development"
connection = settings["ConnectionStrings__JobTracker"].lower()
assert "server=mariadb;" in connection and "database=jobtracker_dev;" in connection
assert settings["Ai__ExternalProcessingEnabled"].lower() == "false"
assert settings["Email__SmtpHost"] == "mailpit" and settings["Email__SmtpPort"] == "1025"
assert not settings["Email__SmtpUser"] and not settings["Email__SmtpPassword"]
assert all(port.get("host_ip") == "127.0.0.1" for port in backend.get("ports", []))
assert sidecar["environment"]["HF_HUB_OFFLINE"] == "1"
assert sidecar["environment"]["TRANSFORMERS_OFFLINE"] == "1"
assert sidecar["environment"]["EXTERNAL_AI_ENABLED"].lower() == "false"
assert sidecar["environment"]["OLLAMA_BASE_URL"] == "http://jobjakt-dev-ollama:11434"
assert any(volume.get("source") == str(artifact) and volume.get("read_only") for volume in sidecar["volumes"])
assert json.loads(capture(["docker", "image", "inspect", sidecar["image"]], environment))[0]["Id"] == SIDECAR
current = json.loads(capture(["docker", "inspect", "jobjakt-dev-backend-1"], environment))[0]
assert current["Config"]["Labels"]["com.docker.compose.project"] == "jobjakt-dev"
assert json.loads(capture(["docker", "image", "inspect", backend["image"]], environment))[0]["Id"] == current["Image"], "This operation changes worker configuration, not backend code"
record = {"project": config["name"], "verifiedBartRevision": manifest["sourceRevision"], "sidecarImage": SIDECAR,
"enabledWorkers": {key: value for key, value in settings.items() if key.startswith("Workers__")},
"emailSink": "Mailpit", "externalAI": False, "applied": False}
args.output.parent.mkdir(parents=True, exist_ok=True)
if args.apply:
with args.output.with_suffix(".log").open("w", encoding="utf-8") as log:
result = subprocess.run(["rtk", "proxy", *compose, "up", "-d", "--no-deps", "--no-build", "--pull", "never",
"--wait", "--wait-timeout", "120", "backend", "ai-service"], env=environment, stdout=log, stderr=subprocess.STDOUT)
record["exitCode"] = result.returncode
record["applied"] = result.returncode == 0
args.output.write_text(json.dumps(record, indent=2) + "\n", encoding="utf-8")
print(json.dumps(record))
if args.apply:
raise SystemExit(record["exitCode"])
if __name__ == "__main__":
main()