Files
bot-bottle/bot_bottle/orchestrator/lifecycle.py
T
didericis 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
refactor(docker): rename OrchestratorService -> DockerInfraService, move to backend/docker
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>
2026-07-24 15:26:52 -04:00

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",
]