From c77f578fb446e4f9f97006450d4ef5919dfa20dc Mon Sep 17 00:00:00 2001 From: didericis Date: Mon, 13 Jul 2026 16:24:37 -0400 Subject: [PATCH] refactor(orchestrator): move run_docker to a lean top-level docker_cmd (#352) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review feedback: don't bury a parallel docker util in the orchestrator. But reusing backend.docker.util (docker_mod) isn't right either — importing it runs backend/__init__.py, which eagerly loads all three backends (docker + firecracker + macos) plus the manifest/egress/git-gate/supervise framework (~76 modules), so every orchestrator import would drag the whole backend layer in. Compromise: promote the helper to a top-level, framework-free bot_bottle/docker_cmd.py (single stdlib import), a proper shared home the orchestrator's docker components use now and backend.docker.util can adopt later. Verified `import bot_bottle.orchestrator` stays lean (12 modules, no firecracker/macos backends). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck --- bot_bottle/docker_cmd.py | 27 ++++++++++++++++++++++++ bot_bottle/orchestrator/docker_broker.py | 2 +- bot_bottle/orchestrator/dockerutil.py | 19 ----------------- bot_bottle/orchestrator/sidecar.py | 2 +- 4 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 bot_bottle/docker_cmd.py delete mode 100644 bot_bottle/orchestrator/dockerutil.py diff --git a/bot_bottle/docker_cmd.py b/bot_bottle/docker_cmd.py new file mode 100644 index 0000000..b8b4961 --- /dev/null +++ b/bot_bottle/docker_cmd.py @@ -0,0 +1,27 @@ +"""Lean, framework-free `docker` subprocess primitive. + +Deliberately a top-level module with a single stdlib import so it can be +reused from anywhere without cost. It is intentionally *not* placed in +`backend.docker.util`: importing that module runs `backend/__init__.py`, +which eagerly loads all three bottle backends (docker + firecracker + +macos) plus the manifest/egress/git-gate/supervise framework — ~76 modules +— which would drag the whole backend layer into the deliberately-lean +orchestrator. This primitive stays free of that so both the orchestrator's +docker components and (in time) `backend.docker.util` can share it.""" + +from __future__ import annotations + +import subprocess + + +def run_docker(argv: list[str]) -> subprocess.CompletedProcess[str]: + """Run a `docker` command, capturing stdout/stderr as text. Never raises + on a non-zero exit — callers inspect `returncode` / `stderr` so they can + stay fail-closed or tolerate idempotent no-ops (e.g. removing an + already-absent container).""" + return subprocess.run( + argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False, + ) + + +__all__ = ["run_docker"] diff --git a/bot_bottle/orchestrator/docker_broker.py b/bot_bottle/orchestrator/docker_broker.py index c3d2685..9caf3a6 100644 --- a/bot_bottle/orchestrator/docker_broker.py +++ b/bot_bottle/orchestrator/docker_broker.py @@ -15,8 +15,8 @@ from __future__ import annotations import subprocess +from ..docker_cmd import run_docker from .broker import LaunchBroker, LaunchRequest -from .dockerutil import run_docker CONTAINER_PREFIX = "bot-bottle-orch-" BOTTLE_ID_LABEL = "bot-bottle-bottle-id" diff --git a/bot_bottle/orchestrator/dockerutil.py b/bot_bottle/orchestrator/dockerutil.py deleted file mode 100644 index 6646f6b..0000000 --- a/bot_bottle/orchestrator/dockerutil.py +++ /dev/null @@ -1,19 +0,0 @@ -"""Shared `docker` subprocess helper for the orchestrator's docker-backed -components (the launch broker and the consolidated sidecar).""" - -from __future__ import annotations - -import subprocess - - -def run_docker(argv: list[str]) -> subprocess.CompletedProcess[str]: - """Run a `docker` command, capturing stdout/stderr as text. Never raises - on a non-zero exit — callers inspect `returncode` / `stderr` so they can - stay fail-closed or tolerate idempotent no-ops (e.g. removing an - already-absent container).""" - return subprocess.run( - argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False, - ) - - -__all__ = ["run_docker"] diff --git a/bot_bottle/orchestrator/sidecar.py b/bot_bottle/orchestrator/sidecar.py index 2d60bcb..4def186 100644 --- a/bot_bottle/orchestrator/sidecar.py +++ b/bot_bottle/orchestrator/sidecar.py @@ -19,7 +19,7 @@ from __future__ import annotations import abc -from .dockerutil import run_docker +from ..docker_cmd import run_docker SIDECAR_NAME = "bot-bottle-orch-sidecar" SIDECAR_LABEL = "bot-bottle-orch-sidecar=1"