refactor(gateway): each backend's transport in its own gateway_transport.py

Give every backend a `gateway_transport.py` holding just its `GatewayTransport`
impl, named consistently with the backend: `DockerGatewayTransport`,
`MacosGatewayTransport` (was `AppleGatewayTransport`), and
`FirecrackerGatewayTransport` (was `SshGatewayTransport`).

- docker: split `DockerGatewayTransport` out of `gateway_provision.py`, which
  keeps only the backend-neutral provisioning logic (provision_git_gate /
  deprovision_git_gate) the other backends share.
- macOS: `gateway_provision.py` held only the transport, so it's replaced by
  `gateway_transport.py`.
- firecracker: move the transport out of `gateway.py`.

Behaviour-preserving; importers + tests updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 13:52:31 -04:00
parent 6e90522664
commit e1fd8ef1b4
13 changed files with 128 additions and 95 deletions
@@ -47,7 +47,7 @@ from ..consolidated_util import (
from . import util as container_mod
from .enumerate import CONTAINER_NAME_PREFIX, EnumerationError, enumerate_active
from .gateway import GATEWAY_NETWORK
from .gateway_provision import AppleGatewayTransport
from .gateway_transport import MacosGatewayTransport
from .infra import MacosInfraService, OrchestratorStartError
@@ -172,7 +172,7 @@ def register_agent(
except (OrchestratorClientError, EnumerationError) as e:
info(f"registry reconciliation skipped: {e}")
reg = provision_bottle(
client, source_ip, egress_plan, git_gate_plan, AppleGatewayTransport(),
client, source_ip, egress_plan, git_gate_plan, MacosGatewayTransport(),
image_ref=image_ref, tokens=tokens,
env_var_secret=env_var_secret,
)
@@ -193,7 +193,7 @@ def teardown_consolidated(
"""Deregister the bottle and remove its git-gate state from the gateway.
Both steps are idempotent so this is safe from a cleanup trap. Does NOT
stop the gateway — it's a persistent per-host singleton."""
_teardown_util(bottle_id, AppleGatewayTransport(),
_teardown_util(bottle_id, MacosGatewayTransport(),
orchestrator_url=orchestrator_url, timeout=timeout)
@@ -184,10 +184,10 @@ class MacosGateway(Gateway):
def provisioning_transport(self) -> GatewayTransport:
"""The exec/cp transport git-gate provisioning stages per-bottle repos +
deploy keys through (over the `container` CLI)."""
# Local import: gateway_provision imports GATEWAY_NAME from this module,
# so importing AppleGatewayTransport at module scope would cycle.
from .gateway_provision import AppleGatewayTransport
return AppleGatewayTransport(self.name)
# Local import: gateway_transport imports GATEWAY_NAME from this module,
# so importing MacosGatewayTransport at module scope would cycle.
from .gateway_transport import MacosGatewayTransport
return MacosGatewayTransport(self.name)
__all__ = [
@@ -1,10 +1,9 @@
"""`GatewayTransport` for the Apple infra container (PRD 0070).
"""The `GatewayTransport` for the Apple gateway container (PRD 0070).
The provisioning *logic* (per-bottle creds dirs, namespaced repo init) is
backend-neutral and lives in `backend.docker.gateway_provision`; this is only
the transport how files and commands reach the running gateway. Docker uses
`docker exec`/`docker cp` and Firecracker uses SSH; Apple uses the `container`
CLI's equivalents against the infra container that hosts the gateway daemons.
How the launcher stages files + runs commands in the running gateway container:
the `container` CLI's exec/cp equivalents. The backend-neutral provisioning
logic that drives it lives in `backend.docker.gateway_provision`; Docker uses
`docker exec`/`docker cp` and Firecracker uses SSH.
"""
from __future__ import annotations
@@ -14,8 +13,8 @@ from . import util as container_mod
from .gateway import GATEWAY_NAME
class AppleGatewayTransport:
"""`GatewayTransport` for the gateway daemons in the Apple infra container."""
class MacosGatewayTransport:
"""`GatewayTransport` for the gateway daemons in the Apple gateway container."""
def __init__(self, gateway: str = GATEWAY_NAME) -> None:
self.gateway = gateway
@@ -41,4 +40,4 @@ class AppleGatewayTransport:
)
__all__ = ["AppleGatewayTransport", "GatewayProvisionError"]
__all__ = ["MacosGatewayTransport"]