feat(git-gate): wire DockerGitGate through prepare/launch/plan
test / unit (pull_request) Successful in 12s
test / integration (pull_request) Successful in 14s

DockerBottleBackend now instantiates a DockerGitGate alongside
DockerPipelockProxy and DockerSSHGate; the prepare step lifts
bottle.git into a GitGatePlan stored on DockerBottlePlan, and
launch starts/stops the sidecar in the same ExitStack as the
other two (only when bottle.git is non-empty).

bottle_plan.print now surfaces git remotes and per-upstream gate
forwards in the y/N preflight; to_dict adds git_remotes and
git_gate keys to the dry-run JSON payload for CLI consumers.
PRD: docs/prds/0008-git-gate.md
This commit is contained in:
2026-05-12 21:06:08 -04:00
parent 509b1b61e2
commit f787edb861
5 changed files with 59 additions and 2 deletions
+17
View File
@@ -22,6 +22,7 @@ from . import network as network_mod
from . import util as docker_mod
from .bottle import DockerBottle
from .bottle_plan import DockerBottlePlan
from .git_gate import DockerGitGate
from .pipelock import DockerPipelockProxy, pipelock_proxy_url, pipelock_tls_init
from .provision.ca import AGENT_CA_BUNDLE, AGENT_CA_PATH
from .ssh_gate import DockerSSHGate
@@ -37,6 +38,7 @@ def launch(
*,
proxy: DockerPipelockProxy,
gate: DockerSSHGate,
git_gate: DockerGitGate,
provision: Callable[[DockerBottlePlan, str], str | None],
) -> Generator[DockerBottle, None, None]:
"""Build, launch, and provision a Docker bottle. Teardown on exit.
@@ -102,6 +104,21 @@ def launch(
gate_name = gate.start(plan.gate_plan)
stack.callback(gate.stop, gate_name)
# Git gate (PRD 0008). One sidecar per agent, only brought up
# when the bottle has git entries. Same internal + egress
# network attachment as the other sidecars; agent dials it as
# `git://<container-name>/<name>.git` via the pushInsteadOf
# rules provision_git writes into ~/.gitconfig.
if plan.git_gate_plan.upstreams:
git_gate_plan = dataclasses.replace(
plan.git_gate_plan,
internal_network=internal_network,
egress_network=egress_network,
)
plan = dataclasses.replace(plan, git_gate_plan=git_gate_plan)
git_gate_name = git_gate.start(plan.git_gate_plan)
stack.callback(git_gate.stop, git_gate_name)
container = _run_agent_container(plan, internal_network)
stack.callback(docker_mod.force_remove_container, container)