b96a8b44e0
test / integration-docker (pull_request) Successful in 22s
lint / lint (push) Successful in 1m7s
test / unit (pull_request) Successful in 2m10s
test / integration-firecracker (pull_request) Successful in 3m35s
test / coverage (pull_request) Successful in 15s
test / publish-infra (pull_request) Has been skipped
tracker-policy-pr / check-pr (pull_request) Failing after 13m2s
OrchestratorService wasn't the orchestrator — it's the host-side lifecycle of the docker infra *container* (the one that runs the Orchestrator). It read as "the orchestrator as a service" and lived in orchestrator/lifecycle.py, while its siblings (macOS MacosInfraService, Firecracker infra_vm) live under their backend package. Rename it DockerInfraService and move it to backend/docker/infra.py alongside the docker backend, with its docker-only constants (INFRA_*/ORCHESTRATOR_* image + container names, daemon list, mount paths). orchestrator/lifecycle.py keeps only the backend-neutral pieces the other infra services share — DEFAULT_PORT, DEFAULT_STARTUP_TIMEOUT_SECONDS, OrchestratorStartError, source_hash — which macOS / firecracker / client still import from there. backend/docker/infra.py imports those (backend -> orchestrator is an allowed direction). Renamed the unit test to test_docker_infra.py. Full unit suite green (2243). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
43 lines
1.4 KiB
Python
43 lines
1.4 KiB
Python
"""Shared orchestrator-process constants + helpers (PRD 0070).
|
|
|
|
Backend-neutral pieces the per-backend infra services build on: the
|
|
control-plane port, the startup timeout, the start-error, and the source hash
|
|
used to detect a code change. The per-backend infra lifecycle lives with each
|
|
backend — docker: `backend.docker.infra.DockerInfraService`; macOS:
|
|
`backend.macos_container.infra`; firecracker: `backend.firecracker.infra_vm`.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
from pathlib import Path
|
|
|
|
DEFAULT_PORT = 8099
|
|
DEFAULT_STARTUP_TIMEOUT_SECONDS = 45.0
|
|
|
|
|
|
class OrchestratorStartError(RuntimeError):
|
|
"""The infra container/VM did not become healthy within the timeout."""
|
|
|
|
|
|
def source_hash(repo_root: Path) -> str:
|
|
"""Content hash of the orchestrator's bind-mounted Python source (the
|
|
`bot_bottle` package the control-plane process imports). Changes only
|
|
when the code that would actually run changes — a backend's `ensure_running`
|
|
recreates the container on a mismatch so a code change takes effect,
|
|
but leaves a healthy up-to-date container alone to preserve in-memory
|
|
egress tokens."""
|
|
h = hashlib.sha256()
|
|
for path in sorted((repo_root / "bot_bottle").rglob("*.py")):
|
|
h.update(str(path.relative_to(repo_root)).encode())
|
|
h.update(path.read_bytes())
|
|
return h.hexdigest()
|
|
|
|
|
|
__all__ = [
|
|
"DEFAULT_PORT",
|
|
"DEFAULT_STARTUP_TIMEOUT_SECONDS",
|
|
"OrchestratorStartError",
|
|
"source_hash",
|
|
]
|