fix(smolmachines): build sidecar image before launch
This commit is contained in:
@@ -142,6 +142,7 @@ def launch(
|
|||||||
# daemons the agent needs to reach from the smolvm guest.
|
# daemons the agent needs to reach from the smolvm guest.
|
||||||
bundle_spec = _bundle_launch_spec(plan, network, loopback_ip)
|
bundle_spec = _bundle_launch_spec(plan, network, loopback_ip)
|
||||||
token_env = _resolve_token_env(plan, os.environ)
|
token_env = _resolve_token_env(plan, os.environ)
|
||||||
|
_bundle.ensure_bundle_image(bundle_spec.image)
|
||||||
_bundle.start_bundle(bundle_spec, env={**os.environ, **token_env})
|
_bundle.start_bundle(bundle_spec, env={**os.environ, **token_env})
|
||||||
stack.callback(_bundle.stop_bundle, plan.slug)
|
stack.callback(_bundle.stop_bundle, plan.slug)
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,14 @@ from pathlib import Path
|
|||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from ...log import die, warn
|
from ...log import die, warn
|
||||||
from ..docker.sidecar_bundle import SIDECAR_BUNDLE_IMAGE
|
from ..docker import util as docker_mod
|
||||||
|
from ..docker.sidecar_bundle import (
|
||||||
|
SIDECAR_BUNDLE_DOCKERFILE,
|
||||||
|
SIDECAR_BUNDLE_IMAGE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_REPO_DIR = str(Path(__file__).resolve().parent.parent.parent.parent)
|
||||||
|
|
||||||
|
|
||||||
def bundle_network_name(slug: str) -> str:
|
def bundle_network_name(slug: str) -> str:
|
||||||
@@ -85,6 +92,21 @@ class BundleLaunchSpec:
|
|||||||
publish_host_ip: str = "127.0.0.1"
|
publish_host_ip: str = "127.0.0.1"
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_bundle_image(image: str = SIDECAR_BUNDLE_IMAGE) -> None:
|
||||||
|
"""Build the sidecar bundle image before `docker run`.
|
||||||
|
|
||||||
|
The Docker backend gets this for free from compose's `build:`
|
||||||
|
stanza. smolmachines starts the bundle with plain `docker run`,
|
||||||
|
so without an explicit build a first launch tries to pull the
|
||||||
|
local-only `bot-bottle-sidecars:latest` tag from a registry.
|
||||||
|
"""
|
||||||
|
docker_mod.build_image(
|
||||||
|
image,
|
||||||
|
_REPO_DIR,
|
||||||
|
dockerfile=SIDECAR_BUNDLE_DOCKERFILE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_bundle_network(network_name: str, subnet: str, gateway: str) -> None:
|
def create_bundle_network(network_name: str, subnet: str, gateway: str) -> None:
|
||||||
"""`docker network create` with an explicit subnet + gateway
|
"""`docker network create` with an explicit subnet + gateway
|
||||||
so the bundle's `--ip` lands on the address the Smolfile's
|
so the bundle's `--ip` lands on the address the Smolfile's
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import unittest
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from bot_bottle.backend.smolmachines.sidecar_bundle import (
|
from bot_bottle.backend.smolmachines.sidecar_bundle import (
|
||||||
@@ -16,6 +17,7 @@ from bot_bottle.backend.smolmachines.sidecar_bundle import (
|
|||||||
bundle_container_name,
|
bundle_container_name,
|
||||||
bundle_network_name,
|
bundle_network_name,
|
||||||
create_bundle_network,
|
create_bundle_network,
|
||||||
|
ensure_bundle_image,
|
||||||
remove_bundle_network,
|
remove_bundle_network,
|
||||||
start_bundle,
|
start_bundle,
|
||||||
stop_bundle,
|
stop_bundle,
|
||||||
@@ -182,6 +184,21 @@ class TestStartBundle(unittest.TestCase):
|
|||||||
self.assertEqual({"FOO": "bar"}, m.call_args.kwargs["env"])
|
self.assertEqual({"FOO": "bar"}, m.call_args.kwargs["env"])
|
||||||
|
|
||||||
|
|
||||||
|
class TestEnsureBundleImage(unittest.TestCase):
|
||||||
|
def test_builds_sidecar_dockerfile_before_plain_docker_run(self):
|
||||||
|
with patch(
|
||||||
|
"bot_bottle.backend.smolmachines.sidecar_bundle.docker_mod.build_image",
|
||||||
|
) as build:
|
||||||
|
ensure_bundle_image()
|
||||||
|
|
||||||
|
build.assert_called_once()
|
||||||
|
args = build.call_args.args
|
||||||
|
kwargs = build.call_args.kwargs
|
||||||
|
self.assertEqual("bot-bottle-sidecars:latest", args[0])
|
||||||
|
self.assertTrue((Path(args[1]) / "Dockerfile.sidecars").is_file())
|
||||||
|
self.assertEqual("Dockerfile.sidecars", kwargs["dockerfile"])
|
||||||
|
|
||||||
|
|
||||||
class TestStopBundle(unittest.TestCase):
|
class TestStopBundle(unittest.TestCase):
|
||||||
def _patch_run(self, **kwargs):
|
def _patch_run(self, **kwargs):
|
||||||
return patch(
|
return patch(
|
||||||
|
|||||||
Reference in New Issue
Block a user