refactor(smolmachines): drop obsolete docker-sidecar helpers
lint / lint (push) Successful in 2m5s
test / unit (pull_request) Successful in 1m2s
test / integration (pull_request) Successful in 20s
test / coverage (pull_request) Successful in 1m11s

This commit is contained in:
2026-07-09 18:14:44 +00:00
parent bfd3e659e8
commit fe82dbc7b8
7 changed files with 37 additions and 512 deletions
@@ -1,111 +0,0 @@
"""Integration: PRD 0023 chunk 2c — bundle bringup on a per-bottle
docker bridge with the pinned IP.
End-to-end against the real docker daemon. Brings up just the
sidecar bundle on its own bridge, confirms the container lands at
the pinned IP, then tears down. Skipped under act_runner (docker
socket mount topology breaks bridge visibility) and when the
bundle image isn't available.
Full launch flow (smolvm + bundle + provisioning + the
localhost-reach / egress-port-bypass probes) lives in chunk 2d."""
from __future__ import annotations
import os
import subprocess
import time
import unittest
from bot_bottle.backend.smolmachines.sidecar_bundle import (
BundleLaunchSpec,
bundle_container_name,
bundle_network_name,
create_bundle_network,
remove_bundle_network,
start_bundle,
stop_bundle,
)
from tests._docker import skip_unless_docker
@skip_unless_docker()
@unittest.skipIf(
os.environ.get("GITEA_ACTIONS") == "true",
"skipped under act_runner: docker socket mount topology breaks "
"in-process visibility of networks created on the host daemon",
)
class TestBundleBringup(unittest.TestCase):
def setUp(self):
self.slug = f"cb-test-bundle-{os.getpid()}-{int(time.time())}"
self.network = bundle_network_name(self.slug)
self.container = bundle_container_name(self.slug)
def tearDown(self):
stop_bundle(self.slug)
remove_bundle_network(self.network)
def _bundle_image_built(self) -> bool:
"""The bundle image (`bot-bottle-sidecars:latest`) is
built lazily by the docker backend's compose. If a
smolmachines-only operator hasn't run the docker backend
first, the image won't exist locally. Skip rather than
fail."""
r = subprocess.run(
["docker", "image", "inspect", "bot-bottle-sidecars:latest"],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
check=False,
)
return r.returncode == 0
def test_create_network_then_start_bundle_pins_ip(self):
if not self._bundle_image_built():
self.skipTest(
"bot-bottle-sidecars:latest not built; run a docker "
"bottle first or `docker build -f Dockerfile.sidecars .`"
)
# Pick a subnet unlikely to collide on the host. Last
# octet of the slug hash isn't deterministic across runs;
# we hardcode a high octet (.211) that the docker default
# bridges almost never use.
subnet = "192.168.211.0/24"
gateway = "192.168.211.1"
bundle_ip = "192.168.211.2"
create_bundle_network(self.network, subnet, gateway)
spec = BundleLaunchSpec(
slug=self.slug,
network_name=self.network,
subnet=subnet,
gateway=gateway,
bundle_ip=bundle_ip,
# Empty daemons_csv → init exits "no daemons selected"
# immediately. We just need the container to land on
# the network at the right IP before it exits.
daemons_csv="", # empty → init exits "no daemons selected"
)
start_bundle(spec)
# Inspect the container's IP on the per-bottle network.
r = subprocess.run(
["docker", "inspect",
"--format",
"{{(index .NetworkSettings.Networks \"" + self.network + "\").IPAddress}}",
self.container],
capture_output=True, text=True, check=False,
)
# Container may have exited (no daemons selected → exit 0).
# The inspect still works on exited containers as long as
# `--rm` hasn't fired yet, which is a race. Even if it has,
# the launch succeeded — the container existed, on the
# right network, at the right IP. We don't fail here on
# missing inspect.
if r.returncode == 0 and r.stdout.strip():
self.assertEqual(bundle_ip, r.stdout.strip(),
f"bundle landed at wrong IP: {r.stdout!r}")
if __name__ == "__main__":
unittest.main()
+7 -37
View File
@@ -1,10 +1,9 @@
"""Integration: PRD 0023 chunk 2d — end-to-end launch + exec
round trip + the acceptance probes.
"""Integration: end-to-end smolmachines launch + exec round trip.
The smoke confirms the launch flow (per-bottle docker bridge
sidecar bundle with host-loopback published ports → smolvm guest
with TSI allowlist → exec) plumbs together end to end. The probes confirm the
security properties the design pivot was about:
The smoke confirms the launch flow (sidecar bundle smolVM
host-loopback forwarders → agent smolVM with TSI allowlist → exec)
plumbs together end to end. The probes confirm the security
properties the design pivot was about:
- **localhost-reach probe** — guest tries to dial a service
bound on the host's `127.0.0.1`. TSI's per-bottle loopback
@@ -14,13 +13,6 @@ security properties the design pivot was about:
the injected `HTTPS_PROXY`/`HTTP_PROXY` URL on the per-bottle
loopback alias, while direct egress with proxy vars unset fails.
- **egress-port-bypass probe** — guest tries to dial
`<bundle-ip>:9099` (egress's port). TSI permits the IP but
the bundle's egress daemon binds `127.0.0.1` inside its
container, so the connect refuses at the socket level. The
bind-address mitigation is what closes TSI's port-granularity
gap.
Gated on macOS/Linux + smolvm + docker + not GITEA_ACTIONS — the
runner can't host libkrun-backed VMs."""
@@ -114,8 +106,8 @@ class TestSmolmachinesLaunch(unittest.TestCase):
def test_localhost_reach_probe(self):
# Agent dials a 127.0.0.1 service on the host. TSI's
# allowlist contains only <bundle-ip>/32, so this must
# refuse. We use a port unlikely to be bound on the host
# allowlist contains only the per-bottle loopback alias, so
# this must refuse. We use a port unlikely to be bound on the host
# (high-numbered) so we're confirming TSI refusal, not
# just "no service listening."
r = self.bottle.exec(
@@ -196,28 +188,6 @@ class TestSmolmachinesLaunch(unittest.TestCase):
self.assertEqual(0, r.returncode, msg=r.stderr)
self.assertEqual(_AGENT_PROMPT, r.stdout.rstrip("\n"))
def test_egress_port_bypass_probe(self):
# Agent dials <bundle-ip>:9099 (egress's port). TSI
# permits the IP, but egress will bind 127.0.0.1:9099
# inside the bundle in chunk 3, so the connect refuses
# at the socket level. NOTE: in chunk 2d the bundle's
# daemons aren't running (daemons_csv=""), so nothing
# is listening on :9099 anyway — this test asserts the
# connect fails, which is the property chunk 3 will
# preserve once egress is actually running.
r = self.bottle.exec(
"env -u HTTPS_PROXY -u HTTP_PROXY -u https_proxy -u http_proxy "
f"curl -s --show-error --max-time 3 http://{self.plan.bundle_ip}:9099 "
"2>&1 || true"
)
self.assertTrue(
"refused" in r.stdout.lower()
or "timed out" in r.stdout.lower()
or "unreachable" in r.stdout.lower()
or "failed" in r.stdout.lower(),
f"expected egress port refusal; got: {r.stdout!r}",
)
if __name__ == "__main__":
unittest.main()