fix(gateway): persist git-gate state across gateway restarts
Per-bottle git-gate state (bare repos under /git/<id>, deploy creds under /git-gate/creds/<id>) was provisioned once at bottle launch and lived only in the gateway's ephemeral storage. A gateway rebuild/restart wiped it and nothing re-provisioned already-running bottles, so their agents 404'd on fetch/push. Same class of bug as the CA (#510); the orchestrator restores only egress tokens, not git-gate declarations. Persist the state on both backends, mirroring the CA-persistence approach: - firecracker: attach a second persistent data drive (/dev/vdc) to the gateway VM and bind-mount its git/ + creds/ subdirs onto /git and /git-gate/creds in the gateway guest init, before the data plane starts. Generalize the VM config to a stable-ordered data_drives tuple (CA=vdb, git=vdc; orchestrator registry stays vdb). - docker: bind-mount host dirs (host_gateway_git_dir / creds_dir, under the never-pruned app-data root) onto /git and /git-gate/creds, with BOT_BOTTLE_DOCKER_GIT_MOUNT / _CREDS_MOUNT env overrides so CI isolates them to per-run volumes it cleans up. Teardown already rm -rf's /git/<id> + creds, so the persistent store self-cleans over the normal lifecycle. Closes #512 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,8 @@ from .gateway_transport import DockerGatewayTransport
|
||||
from ...paths import (
|
||||
ORCHESTRATOR_AUTH_JWT_ENV,
|
||||
host_gateway_ca_dir,
|
||||
host_gateway_git_dir,
|
||||
host_gateway_creds_dir,
|
||||
)
|
||||
from ... import resources
|
||||
from ...gateway import (
|
||||
@@ -40,6 +42,8 @@ class DockerGateway(Gateway):
|
||||
dockerfile: str | None = GATEWAY_DOCKERFILE,
|
||||
host_port_bindings: tuple[int, ...] = (),
|
||||
ca_mount_source: str | Path | None = None,
|
||||
git_mount_source: str | Path | None = None,
|
||||
creds_mount_source: str | Path | None = None,
|
||||
subnet: str | None = None,
|
||||
) -> None:
|
||||
self.image_ref = image_ref
|
||||
@@ -74,6 +78,17 @@ class DockerGateway(Gateway):
|
||||
self._ca_mount_source = str(
|
||||
ca_mount_source or configured_ca or host_gateway_ca_dir()
|
||||
)
|
||||
# The persistent git-gate mounts (/git bare repos, /git-gate/creds deploy
|
||||
# creds) — same host-bind-mount rationale as the CA (issue #512). The env
|
||||
# overrides let CI point them at per-run named volumes it cleans up.
|
||||
configured_git = os.environ.get("BOT_BOTTLE_DOCKER_GIT_MOUNT", "").strip()
|
||||
self._git_mount_source = str(
|
||||
git_mount_source or configured_git or host_gateway_git_dir()
|
||||
)
|
||||
configured_creds = os.environ.get("BOT_BOTTLE_DOCKER_CREDS_MOUNT", "").strip()
|
||||
self._creds_mount_source = str(
|
||||
creds_mount_source or configured_creds or host_gateway_creds_dir()
|
||||
)
|
||||
|
||||
def image_exists(self) -> bool:
|
||||
return run_docker(["docker", "image", "inspect", self.image_ref]).returncode == 0
|
||||
@@ -198,6 +213,12 @@ class DockerGateway(Gateway):
|
||||
# container recreation AND docker volume pruning (agents trust it)
|
||||
# — see host_gateway_ca_dir / issue #450.
|
||||
"--volume", f"{self._ca_mount_source}:{MITMPROXY_HOME}",
|
||||
# Persist per-bottle git-gate state (bare repos + deploy creds) on
|
||||
# the host so a gateway restart doesn't drop already-running bottles'
|
||||
# repos — they would otherwise 404 on fetch/push (issue #512). Same
|
||||
# host-bind-mount rationale as the CA.
|
||||
"--volume", f"{self._git_mount_source}:/git",
|
||||
"--volume", f"{self._creds_mount_source}:/git-gate/creds",
|
||||
# No DB mount: the data plane (egress / supervise / git-gate) reaches
|
||||
# the supervise queue over the control-plane RPC and never opens
|
||||
# bot-bottle.db, so the gateway container gets no file handle on it
|
||||
|
||||
Reference in New Issue
Block a user