refactor(firecracker): use docker_mod instead of hand-rolled docker helpers
firecracker/launch.py reimplemented docker build/image-exists/rm/exec/cp as private functions instead of the shared docker_mod used by the docker and macos-container backends. Switching to docker_mod dedupes the logic and gets --no-cache support for free (docker_mod.build_image already reads BOT_BOTTLE_NO_CACHE); docker_mod gains docker_exec/ docker_cp general-purpose helpers to cover what the private versions did.
This commit is contained in:
@@ -89,6 +89,31 @@ def docker_exec_root(container: str, argv: list[str]) -> None:
|
||||
)
|
||||
|
||||
|
||||
def docker_exec(container: str, argv: list[str], *, user: str = "") -> None:
|
||||
"""Run `docker exec` in the named container, dying with the
|
||||
command's own stderr on failure. Pass `user=\"0\"` to run as root."""
|
||||
cmd = ["docker", "exec"]
|
||||
if user:
|
||||
cmd += ["-u", user]
|
||||
cmd += [container, *argv]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=False)
|
||||
if result.returncode != 0:
|
||||
die(
|
||||
f"docker exec in {container} failed: "
|
||||
f"{(result.stderr or '').strip() or '<no stderr>'}"
|
||||
)
|
||||
|
||||
|
||||
def docker_cp(src: str, dest: str) -> None:
|
||||
"""Run `docker cp`, dying with the command's own stderr on failure."""
|
||||
result = subprocess.run(
|
||||
["docker", "cp", src, dest], capture_output=True, text=True, check=False,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
die(f"docker cp {src} -> {dest} failed: "
|
||||
f"{(result.stderr or '').strip() or '<no stderr>'}")
|
||||
|
||||
|
||||
_SLUG_RE = re.compile(r"[^a-z0-9]+")
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ from ...git_gate import (
|
||||
from ...log import die, info, warn
|
||||
from ...supervise import DB_PATH_IN_CONTAINER, SUPERVISE_PORT
|
||||
from ...util import expand_tilde
|
||||
from ..docker import util as docker_mod
|
||||
from ..docker.egress import (
|
||||
EGRESS_CA_IN_CONTAINER,
|
||||
EGRESS_PORT,
|
||||
@@ -106,9 +107,9 @@ def launch(
|
||||
plan = _provision_git_gate_keys(plan)
|
||||
|
||||
sidecar_name = sidecar_container_name(plan.slug)
|
||||
_force_remove_container(sidecar_name)
|
||||
docker_mod.force_remove_container(sidecar_name)
|
||||
_start_sidecar_bundle(plan, sidecar_name, slot.host_ip)
|
||||
stack.callback(_force_remove_container, sidecar_name)
|
||||
stack.callback(docker_mod.force_remove_container, sidecar_name)
|
||||
_stage_git_gate(plan, sidecar_name)
|
||||
|
||||
plan = _stamp_agent_urls(plan, slot.host_ip)
|
||||
@@ -170,15 +171,15 @@ def _mint_certs(plan: FirecrackerBottlePlan) -> FirecrackerBottlePlan:
|
||||
|
||||
|
||||
def _build_agent_image(plan: FirecrackerBottlePlan) -> FirecrackerBottlePlan:
|
||||
_docker_build(SIDECAR_BUNDLE_IMAGE, _REPO_DIR, dockerfile=SIDECAR_BUNDLE_DOCKERFILE)
|
||||
docker_mod.build_image(SIDECAR_BUNDLE_IMAGE, _REPO_DIR, dockerfile=SIDECAR_BUNDLE_DOCKERFILE)
|
||||
committed = read_committed_image(plan.slug)
|
||||
if committed and _image_exists(committed):
|
||||
if committed and docker_mod.image_exists(committed):
|
||||
info(f"using committed image {committed!r}")
|
||||
return dataclasses.replace(
|
||||
plan,
|
||||
agent_provision=dataclasses.replace(plan.agent_provision, image=committed),
|
||||
)
|
||||
_docker_build(plan.image, _REPO_DIR, dockerfile=plan.dockerfile_path)
|
||||
docker_mod.build_image(plan.image, _REPO_DIR, dockerfile=plan.dockerfile_path)
|
||||
return plan
|
||||
|
||||
|
||||
@@ -291,15 +292,15 @@ def _stage_git_gate(plan: FirecrackerBottlePlan, sidecar_name: str) -> None:
|
||||
gp = plan.git_gate_plan
|
||||
if not gp.upstreams:
|
||||
return
|
||||
_docker_exec(sidecar_name, [
|
||||
docker_mod.docker_exec(sidecar_name, [
|
||||
"mkdir", "-p",
|
||||
str(Path(GIT_GATE_HOOK_IN_CONTAINER).parent),
|
||||
GIT_GATE_CREDS_DIR_IN_CONTAINER, "/git",
|
||||
str(Path(_GIT_GATE_READY_FILE).parent),
|
||||
])
|
||||
for host_path, container_path in _git_gate_files(plan):
|
||||
_docker_cp(host_path, f"{sidecar_name}:{container_path}")
|
||||
_docker_exec(sidecar_name, [
|
||||
docker_mod.docker_cp(host_path, f"{sidecar_name}:{container_path}")
|
||||
docker_mod.docker_exec(sidecar_name, [
|
||||
"sh", "-c",
|
||||
f"chmod 755 {GIT_GATE_ENTRYPOINT_IN_CONTAINER} "
|
||||
f"{GIT_GATE_HOOK_IN_CONTAINER} {GIT_GATE_ACCESS_HOOK_IN_CONTAINER} && "
|
||||
@@ -355,50 +356,3 @@ def _agent_guest_env(plan: FirecrackerBottlePlan, host_ip: str) -> dict[str, str
|
||||
if value is not None:
|
||||
env[name] = value
|
||||
return env
|
||||
|
||||
|
||||
# --- docker helpers --------------------------------------------------
|
||||
|
||||
def _docker_build(ref: str, context: str, *, dockerfile: str = "") -> None:
|
||||
info(f"docker build {ref}")
|
||||
args = ["docker", "build", "-t", ref]
|
||||
if dockerfile:
|
||||
if not os.path.isabs(dockerfile):
|
||||
dockerfile = os.path.join(context, dockerfile)
|
||||
args += ["-f", dockerfile]
|
||||
args.append(context)
|
||||
result = subprocess.run(args, check=False)
|
||||
if result.returncode != 0:
|
||||
die(f"docker build for {ref!r} failed")
|
||||
|
||||
|
||||
def _image_exists(ref: str) -> bool:
|
||||
return subprocess.run(
|
||||
["docker", "image", "inspect", ref],
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False,
|
||||
).returncode == 0
|
||||
|
||||
|
||||
def _force_remove_container(name: str) -> None:
|
||||
subprocess.run(
|
||||
["docker", "rm", "-f", name],
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False,
|
||||
)
|
||||
|
||||
|
||||
def _docker_exec(name: str, argv: list[str]) -> None:
|
||||
result = subprocess.run(
|
||||
["docker", "exec", name, *argv], capture_output=True, text=True, check=False,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
die(f"docker exec in {name} failed: "
|
||||
f"{(result.stderr or '').strip() or '<no stderr>'}")
|
||||
|
||||
|
||||
def _docker_cp(host_path: str, dest: str) -> None:
|
||||
result = subprocess.run(
|
||||
["docker", "cp", host_path, dest], capture_output=True, text=True, check=False,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
die(f"docker cp {host_path} -> {dest} failed: "
|
||||
f"{(result.stderr or '').strip() or '<no stderr>'}")
|
||||
|
||||
Reference in New Issue
Block a user