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:
@@ -63,6 +63,15 @@ _GUEST_GATEWAY_JWT_PATH = "/var/lib/bot-bottle/gateway-jwt"
|
||||
# survives a gateway-VM rebuild; without it every rebuild mints a fresh CA that
|
||||
# already-running bottles distrust, breaking the TLS handshake (issue #450).
|
||||
_GATEWAY_CA_MOUNT = "/home/mitmproxy/.mitmproxy"
|
||||
# The gateway VM's persistent git-gate volume staging mount (/dev/vdc). The
|
||||
# gateway boots with this volume (see `FirecrackerGateway._ensure_git_volume`)
|
||||
# and the init bind-mounts its `git/` + `creds/` subdirs onto the load-bearing
|
||||
# `/git` and `/git-gate/creds` paths, so per-bottle bare repos + deploy creds
|
||||
# survive a gateway-VM rebuild; without it a restart drops every already-running
|
||||
# bottle's git-gate state and its agent 404s on fetch/push (issue #512).
|
||||
_GATEWAY_GIT_MOUNT = "/var/lib/bot-bottle-gitgate"
|
||||
_GATEWAY_GIT_REPO_ROOT = "/git"
|
||||
_GATEWAY_GIT_CREDS_DIR = "/git-gate/creds"
|
||||
|
||||
# The two per-plane rootfs source images. The orchestrator VM boots a control
|
||||
# plane + buildah rootfs (Dockerfile.orchestrator.fc, FROM orchestrator); the
|
||||
@@ -198,11 +207,12 @@ def boot_vm(
|
||||
run_dir: Path,
|
||||
role: str,
|
||||
mem_mib: int,
|
||||
data_drive: Path | None = None,
|
||||
data_drives: tuple[Path, ...] = (),
|
||||
extra_boot_args: str = "",
|
||||
) -> InfraVm:
|
||||
"""Boot the `role` infra VM from its per-plane rootfs on `slot`'s link.
|
||||
Records the PID."""
|
||||
Records the PID. `data_drives` are attached as /dev/vdb, /dev/vdc, ... in
|
||||
order, so callers must keep the order stable (see `firecracker_vm._config`)."""
|
||||
if not netpool.tap_present(slot.iface):
|
||||
die(f"infra link {slot.iface} not present.\n"
|
||||
f" ./cli.py backend setup --backend=firecracker")
|
||||
@@ -224,7 +234,7 @@ def boot_vm(
|
||||
name=name, rootfs=rootfs, tap=slot.iface,
|
||||
guest_ip=slot.guest_ip, host_ip=slot.host_ip, pubkey=pubkey,
|
||||
run_dir=run_dir, mem_mib=mem_mib, detached=True,
|
||||
data_drive=data_drive, extra_boot_args=boot_args,
|
||||
data_drives=data_drives, extra_boot_args=boot_args,
|
||||
)
|
||||
_pid_file(run_dir).write_text(str(vm.process.pid))
|
||||
return InfraVm(guest_ip=slot.guest_ip, private_key=private_key, vm=vm)
|
||||
@@ -461,6 +471,17 @@ def _gateway_init() -> str:
|
||||
# mitmproxy) starts.
|
||||
mkdir -p {_GATEWAY_CA_MOUNT}
|
||||
mount -t ext4 /dev/vdb {_GATEWAY_CA_MOUNT} 2>/dev/null || true
|
||||
# Persistent git-gate volume (/dev/vdc): its git/ + creds/ subdirs are
|
||||
# bind-mounted onto the load-bearing /git and /git-gate/creds so per-bottle bare
|
||||
# repos + deploy creds survive a gateway-VM rebuild (issue #512). On first boot
|
||||
# the volume is empty; the subdirs are created here. Must mount BEFORE the data
|
||||
# plane (hence git-http) starts, and before any per-bottle provisioning writes.
|
||||
mkdir -p {_GATEWAY_GIT_MOUNT}
|
||||
mount -t ext4 /dev/vdc {_GATEWAY_GIT_MOUNT} 2>/dev/null || true
|
||||
mkdir -p {_GATEWAY_GIT_MOUNT}/git {_GATEWAY_GIT_MOUNT}/creds
|
||||
mkdir -p {_GATEWAY_GIT_REPO_ROOT} {_GATEWAY_GIT_CREDS_DIR}
|
||||
mount --bind {_GATEWAY_GIT_MOUNT}/git {_GATEWAY_GIT_REPO_ROOT} 2>/dev/null || true
|
||||
mount --bind {_GATEWAY_GIT_MOUNT}/creds {_GATEWAY_GIT_CREDS_DIR} 2>/dev/null || true
|
||||
ORCH=$(sed -n 's/.*bb_orch=\\([^ ]*\\).*/\\1/p' /proc/cmdline)
|
||||
GW_JWT=""
|
||||
i=0
|
||||
|
||||
Reference in New Issue
Block a user