4692a92c19
Answers "where do we build the consolidated sidecar": nowhere, until now.
* sidecar.py — `Sidecar.ensure_built()` (default no-op) + `DockerSidecar`
now defaults its image to the real bundle (`bot-bottle-sidecars`) and
`ensure_built()` builds it from `Dockerfile.sidecars` when
`docker image inspect` shows it's missing (no-op when present or when no
dockerfile is configured, e.g. a pre-pulled image). `image_exists()`
added.
* service.py — `ensure_sidecar()` now builds then runs.
* __main__.py — `--sidecar` runs the consolidated bundle (build-if-missing).
Scope note: this builds + launches the bundle *container*; making the
running instance functional across bottles needs the per-bottle,
source-IP-keyed multi-tenant config + registration/reload, and routing
agent bottles to it — the next slices (added to PRD 0070's roadmap).
Tests: unit (docker mocked) — image_exists, ensure_built builds when
missing / no-op when present / no-op without a dockerfile / raises on build
failure; ensure_sidecar builds-then-runs; integration (gated, no heavy
build) — image_exists reflects real docker state. Full suite green (only
pre-existing /bin/sleep errors).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
37 lines
1.2 KiB
Python
37 lines
1.2 KiB
Python
"""Integration: DockerSidecar.image_exists reflects real docker state.
|
|
|
|
Gated on a reachable Docker daemon. Deliberately does NOT build the full
|
|
sidecar bundle (a heavy, slow image build) — it exercises the `image_exists`
|
|
primitive that `ensure_built` gates on, against a tiny pulled image and a
|
|
name that can't exist.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
import unittest
|
|
|
|
from bot_bottle.orchestrator.sidecar import DockerSidecar
|
|
from tests._docker import skip_unless_docker
|
|
|
|
IMAGE = "busybox"
|
|
|
|
|
|
@skip_unless_docker()
|
|
class TestDockerSidecarImageExists(unittest.TestCase):
|
|
def test_image_exists_true_for_present_false_for_absent(self) -> None:
|
|
# Ensure the tiny image is present (build_if_missing is disabled here
|
|
# so this never triggers a Dockerfile.sidecars build).
|
|
subprocess.run(
|
|
["docker", "pull", IMAGE],
|
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False,
|
|
)
|
|
self.assertTrue(DockerSidecar(IMAGE, dockerfile=None).image_exists())
|
|
self.assertFalse(
|
|
DockerSidecar("bot-bottle-nonexistent:doesnotexist", dockerfile=None).image_exists()
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|