refactor(docker): split provision into provision_prompt / _ssh / _git
test / run tests/run_tests.py (pull_request) Successful in 13s
test / run tests/run_tests.py (pull_request) Successful in 13s
provision now orchestrates three focused sub-methods. Each sub-method self-gates: provision_ssh is a no-op when the bottle has no SSH entries; provision_git is a no-op when --cwd was not set. The prompt copy + chown always runs (so the path always exists in-container); the return is gated on whether the agent has a non-empty prompt.
This commit is contained in:
@@ -269,6 +269,20 @@ class DockerBottleBackend(BottleBackend):
|
|||||||
f"got {type(plan).__name__}"
|
f"got {type(plan).__name__}"
|
||||||
)
|
)
|
||||||
container = target
|
container = target
|
||||||
|
|
||||||
|
prompt_path = self.provision_prompt(plan, container)
|
||||||
|
agent = plan.spec.manifest.agents[plan.spec.agent_name]
|
||||||
|
if agent.skills:
|
||||||
|
skills_mod.skills_copy_into(container, list(agent.skills))
|
||||||
|
self.provision_ssh(plan, container)
|
||||||
|
self.provision_git(plan, container)
|
||||||
|
return prompt_path
|
||||||
|
|
||||||
|
def provision_prompt(self, plan: DockerBottlePlan, container: str) -> str | None:
|
||||||
|
"""Copy the prompt file into the container, fix ownership/mode.
|
||||||
|
Returns the in-container path if the agent has a non-empty
|
||||||
|
prompt (drives --append-system-prompt-file), else None. The
|
||||||
|
file is copied either way so the path always exists."""
|
||||||
container_home = os.environ.get("CLAUDE_BOTTLE_CONTAINER_HOME", "/home/node")
|
container_home = os.environ.get("CLAUDE_BOTTLE_CONTAINER_HOME", "/home/node")
|
||||||
in_container_prompt_path = f"{container_home}/.claude-bottle-prompt.txt"
|
in_container_prompt_path = f"{container_home}/.claude-bottle-prompt.txt"
|
||||||
|
|
||||||
@@ -291,15 +305,24 @@ class DockerBottleBackend(BottleBackend):
|
|||||||
)
|
)
|
||||||
|
|
||||||
agent = plan.spec.manifest.agents[plan.spec.agent_name]
|
agent = plan.spec.manifest.agents[plan.spec.agent_name]
|
||||||
if agent.skills:
|
return in_container_prompt_path if agent.prompt else None
|
||||||
skills_mod.skills_copy_into(container, list(agent.skills))
|
|
||||||
|
|
||||||
|
def provision_ssh(self, plan: DockerBottlePlan, container: str) -> None:
|
||||||
|
"""If the bottle has SSH entries, set up the in-container
|
||||||
|
ssh-agent and config so node can authenticate without ever
|
||||||
|
seeing the key bytes. No-op when the bottle has no SSH."""
|
||||||
bottle = plan.spec.manifest.bottle_for(plan.spec.agent_name)
|
bottle = plan.spec.manifest.bottle_for(plan.spec.agent_name)
|
||||||
if bottle.ssh:
|
if not bottle.ssh:
|
||||||
|
return
|
||||||
proxy_host_port = pipelock.pipelock_proxy_host_port(plan.slug)
|
proxy_host_port = pipelock.pipelock_proxy_host_port(plan.slug)
|
||||||
ssh_mod.ssh_setup(container, plan.stage_dir, proxy_host_port, bottle.ssh)
|
ssh_mod.ssh_setup(container, plan.stage_dir, proxy_host_port, bottle.ssh)
|
||||||
|
|
||||||
if plan.spec.copy_cwd and Path(plan.spec.user_cwd, ".git").is_dir():
|
def provision_git(self, plan: DockerBottlePlan, container: str) -> None:
|
||||||
|
"""If --cwd was set and the host cwd has a .git directory, copy
|
||||||
|
it into /home/node/workspace/.git and fix ownership. No-op
|
||||||
|
otherwise."""
|
||||||
|
if not (plan.spec.copy_cwd and Path(plan.spec.user_cwd, ".git").is_dir()):
|
||||||
|
return
|
||||||
info(f"copying {plan.spec.user_cwd}/.git -> {container}:/home/node/workspace/.git")
|
info(f"copying {plan.spec.user_cwd}/.git -> {container}:/home/node/workspace/.git")
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["docker", "cp", f"{plan.spec.user_cwd}/.git", f"{container}:/home/node/workspace/.git"],
|
["docker", "cp", f"{plan.spec.user_cwd}/.git", f"{container}:/home/node/workspace/.git"],
|
||||||
@@ -315,8 +338,6 @@ class DockerBottleBackend(BottleBackend):
|
|||||||
check=True,
|
check=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
return in_container_prompt_path if agent.prompt else None
|
|
||||||
|
|
||||||
# --- Cleanup ---
|
# --- Cleanup ---
|
||||||
|
|
||||||
def prepare_cleanup(self) -> DockerBottleCleanupPlan:
|
def prepare_cleanup(self) -> DockerBottleCleanupPlan:
|
||||||
|
|||||||
Reference in New Issue
Block a user