539234f29e
Compose-up has owned per-container lifecycle since PRD 0018 ch3;
the .start() / .stop() methods on DockerPipelockProxy /
DockerEgress / DockerGitGate / DockerSupervise (and their
abstractmethod declarations in the four base ABCs) were already
documented as vestigial. With the bundle path in flight
(PRD 0024 ch2), they are truly dead — collapse to nothing.
Changes:
- Removed start/stop methods from the four DockerSidecar
classes. Plan dataclasses, image/path constants,
container-name helpers, and the .prepare() methods all stay
(the renderer + apply path still need them).
- Removed the matching @abstractmethod declarations in the
base ABCs so concrete subclasses don't have to stub them.
- launch.launch() and prepare.resolve_plan() no longer take
proxy/git_gate/egress/supervise instance parameters. backend.py
loses the four instance attributes it threaded through.
prepare.resolve_plan() instantiates the four classes itself
to call their .prepare() methods.
- Deleted four integration tests that only exercised the
removed lifecycle: test_pipelock_sidecar_smoke,
test_supervise_sidecar, test_git_gate_sidecar,
test_git_gate_mirror.
- Dropped the .stop-idempotency case in test_orphan_cleanup;
the network-cleanup cases stay (those test real production
code).
- Marked test_pipelock_apply @skip pending chunk 4 — its
bringup helper used .start; chunk 4 rewrites it with direct
`docker run`.
Dockerfile deletion deferred to chunk 5 (when the bundle flag
default flips) — the legacy compose path still needs
Dockerfile.{egress,git-gate,supervise} until then.
Net: 708 lines removed, 80 added.
533 unit tests + 27 integration tests passing (5 skipped: the
chunk-4-pending case + existing GITEA_ACTIONS guards).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
"""DockerGitGate — the Docker-specific lifecycle for the per-agent
|
|
git-gate sidecar (PRD 0008). Inherits the platform-agnostic prepare
|
|
step (upstream lift + entrypoint/hook render) from `GitGate`."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
from ...git_gate import GitGate
|
|
from . import util as docker_mod
|
|
|
|
|
|
GIT_GATE_IMAGE = os.environ.get(
|
|
"CLAUDE_BOTTLE_GIT_GATE_IMAGE",
|
|
"claude-bottle-git-gate:latest",
|
|
)
|
|
|
|
GIT_GATE_DOCKERFILE = "Dockerfile.git-gate"
|
|
|
|
GIT_GATE_ENTRYPOINT_IN_CONTAINER = "/git-gate-entrypoint.sh"
|
|
GIT_GATE_HOOK_IN_CONTAINER = "/etc/git-gate/pre-receive"
|
|
GIT_GATE_ACCESS_HOOK_IN_CONTAINER = "/etc/git-gate/access-hook"
|
|
GIT_GATE_CREDS_DIR_IN_CONTAINER = "/git-gate/creds"
|
|
|
|
# git daemon's default listening port. Surfaced as a constant because
|
|
# integration tests probe the gate on it.
|
|
GIT_GATE_PORT = 9418
|
|
|
|
# Repo root, for `docker build` context. Resolved from this file's
|
|
# location: claude_bottle/backend/docker/git_gate.py → repo root.
|
|
_REPO_DIR = str(Path(__file__).resolve().parent.parent.parent.parent)
|
|
|
|
|
|
def git_gate_container_name(slug: str) -> str:
|
|
return f"claude-bottle-git-gate-{slug}"
|
|
|
|
|
|
def git_gate_host(slug: str) -> str:
|
|
"""The hostname the agent's git client should connect to (same as
|
|
the container name — Docker's embedded DNS resolves it on the
|
|
`--internal` network)."""
|
|
return git_gate_container_name(slug)
|
|
|
|
|
|
def build_git_gate_image() -> None:
|
|
"""Build the git-gate image from `Dockerfile.git-gate`. Called by
|
|
`DockerGitGate.start`; exposed at module level so integration
|
|
tests can build it without running the full launch pipeline."""
|
|
docker_mod.build_image(GIT_GATE_IMAGE, _REPO_DIR, dockerfile=GIT_GATE_DOCKERFILE)
|
|
|
|
|
|
class DockerGitGate(GitGate):
|
|
"""Docker-flavored GitGate: inherits `.prepare()` from the base.
|
|
Container lifecycle is owned by compose; per-container
|
|
`.start()` / `.stop()` were removed in PRD 0024 chunk 3."""
|