refactor(backend): pass Bottle to provisioners instead of target string
test / unit (pull_request) Successful in 50s
test / integration (pull_request) Successful in 59s
test / unit (push) Successful in 43s
test / integration (push) Successful in 1m3s

Closes #178.

The backend provision functions now receive a Bottle handle with
exec / cp_in methods instead of a raw target string. Provisioner
modules use bottle.exec and bottle.cp_in in place of inlined
subprocess.run(["docker", "exec"/"cp", ...]) and direct
_smolvm.machine_cp / machine_exec calls. This decouples the
provisioners from backend-specific runtime primitives so future
refactors (e.g. the supervise rework) can swap the bottle's exec
implementation without touching every provisioner.

Each launch.py constructs the Bottle handle before calling
provision so it can be passed in; provision_prompt's return value
is wired back onto the bottle's prompt path attribute after the
fact.
This commit was merged in pull request #179.
This commit is contained in:
2026-06-03 20:47:37 +00:00
parent f12b0f754e
commit 0efc07ba67
22 changed files with 662 additions and 884 deletions
@@ -2,35 +2,34 @@
from __future__ import annotations
import subprocess
import shlex
from ....log import die
from ... import Bottle
from ..bottle_plan import DockerBottlePlan
def provision_provider_auth(plan: DockerBottlePlan, target: str) -> None:
"""Apply provider-owned guest setup through Docker primitives."""
def provision_provider_auth(plan: DockerBottlePlan, bottle: Bottle) -> None:
"""Apply provider-owned guest setup through the bottle's exec / cp_in."""
provision = plan.agent_provision
for d in provision.dirs:
_exec(target, ["mkdir", "-p", d.guest_path])
_exec(target, ["chown", d.owner, d.guest_path])
_exec(target, ["chmod", d.mode, d.guest_path])
_exec(bottle, f"mkdir -p {shlex.quote(d.guest_path)}", d.guest_path)
_exec(bottle, f"chown {shlex.quote(d.owner)} {shlex.quote(d.guest_path)}", d.guest_path)
_exec(bottle, f"chmod {shlex.quote(d.mode)} {shlex.quote(d.guest_path)}", d.guest_path)
for command in provision.pre_copy:
_exec(target, list(command.argv))
_exec(bottle, shlex.join(command.argv), command.error)
for f in provision.files:
subprocess.run(
["docker", "cp", str(f.host_path), f"{target}:{f.guest_path}"],
stdout=subprocess.DEVNULL,
check=True,
)
_exec(target, ["chown", f.owner, f.guest_path])
_exec(target, ["chmod", f.mode, f.guest_path])
bottle.cp_in(str(f.host_path), f.guest_path)
_exec(bottle, f"chown {shlex.quote(f.owner)} {shlex.quote(f.guest_path)}", f.guest_path)
_exec(bottle, f"chmod {shlex.quote(f.mode)} {shlex.quote(f.guest_path)}", f.guest_path)
for command in provision.verify:
_exec(target, list(command.argv))
_exec(bottle, shlex.join(command.argv), command.error)
def _exec(target: str, argv: list[str]) -> None:
subprocess.run(
["docker", "exec", "-u", "0", target, *argv],
stdout=subprocess.DEVNULL,
check=True,
)
def _exec(bottle: Bottle, script: str, error: str) -> None:
result = bottle.exec(script, user="root")
if result.returncode != 0:
detail = (result.stderr or result.stdout).strip()
if detail:
detail = f": {detail}"
die(f"agent provider provisioning: {error}{detail}")