docs(prd): reconcile via a backend-ABC method across all backends (0081 review)
Address review: target all backends, not firecracker-only. Make the reconcile an @abc.abstractmethod `attach_bottled_agents_to_gateway()` on BottleBackend so every backend implements it (cross-backend by construction) and the host calls it on gateway bring-up. Drop the docker/macOS non-goal; add the open question of retiring docker's now-redundant CA bind-mount. Refs #516
This commit is contained in:
@@ -49,29 +49,40 @@ destroy (the original #450 failure mode).
|
|||||||
running agents by the same reconcile.
|
running agents by the same reconcile.
|
||||||
- Per-bottle failures are tolerated: one unreachable or malformed bottle does not
|
- Per-bottle failures are tolerated: one unreachable or malformed bottle does not
|
||||||
block the others or the gateway coming up.
|
block the others or the gateway coming up.
|
||||||
|
- **All backends** (Firecracker, docker, macOS) reconcile through the *same*
|
||||||
|
contract — an abstract method on the backend base class, so a new backend
|
||||||
|
cannot forget to implement it and none drifts onto a bespoke mechanism.
|
||||||
|
|
||||||
## Non-goals
|
## Non-goals
|
||||||
|
|
||||||
- Deliberate mid-session CA rotation *without* a gateway restart — `rotate_ca`
|
- Deliberate mid-session CA rotation *without* a gateway restart — `rotate_ca`
|
||||||
stays for that operator action.
|
stays for that operator action.
|
||||||
- The docker / macOS backends. This lands the reconcile for Firecracker (the
|
|
||||||
backend that boots a fresh gateway rootfs each time); docker keeps its existing
|
|
||||||
host-bind-mounted CA until the same seam is extended there (follow-up). The
|
|
||||||
unification target is *per-service*, not *per-backend*.
|
|
||||||
- Changing source-IP attribution, `/resolve`, or the plane split (#469).
|
- Changing source-IP attribution, `/resolve`, or the plane split (#469).
|
||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
**Trigger — the gateway startup flow.** `FirecrackerGateway.connect_to_orchestrator`
|
**The contract — `attach_bottled_agents_to_gateway()` on the backend ABC.**
|
||||||
is the cold-boot path: `FirecrackerInfraService.ensure_running` calls it only when
|
Reconciling running bottles against the current gateway is a backend
|
||||||
it boots a fresh pair, and skips it when it adopts a healthy, current gateway
|
responsibility (only the backend can enumerate its agents and reach them —
|
||||||
(state intact). So reconcile fires exactly when the gateway was (re)booted —
|
firecracker over SSH, docker/macOS over `exec`/`cp`), so it is an
|
||||||
including orchestrator restarts, since the pair boots together — and never on an
|
`@abc.abstractmethod` on `BottleBackend` (`backend/base.py`). Every backend
|
||||||
adopt. There is no bare-restart path that bypasses `ensure_running`.
|
implements it; the host calls it whenever the gateway is (re)brought up. This is
|
||||||
|
what makes the fix cross-backend by construction rather than a per-backend
|
||||||
|
follow-up. It reprovisions **all** registered bottles' gateway-dependent state:
|
||||||
|
CA, git-gate, and egress tokens.
|
||||||
|
|
||||||
**`reconcile_running_bottles(gateway, orchestrator_url)`** (new
|
**Trigger — the gateway bring-up path.** The host calls
|
||||||
`firecracker/reconcile.py`), called at the end of `connect_to_orchestrator` once
|
`attach_bottled_agents_to_gateway()` only when the gateway was actually
|
||||||
the gateway VM is up and its CA is available:
|
(re)brought up — the cold-boot branch of the infra bring-up (e.g.
|
||||||
|
`FirecrackerInfraService.ensure_running` after it boots a fresh pair), never on an
|
||||||
|
adopt of a healthy, current gateway (state intact). So it fires exactly when the
|
||||||
|
gateway was (re)booted — including orchestrator restarts, since the pair boots
|
||||||
|
together — and there is no bare-restart path that bypasses bring-up.
|
||||||
|
|
||||||
|
**Per-backend implementation.** Each backend's `attach_bottled_agents_to_gateway`
|
||||||
|
enumerates its live bottles and, for each, reconciles the three services against
|
||||||
|
the current gateway. The firecracker implementation, once the gateway VM is up
|
||||||
|
and its CA is available:
|
||||||
|
|
||||||
1. Map each live bottle's guest IP → `bottle_id` from the orchestrator registry
|
1. Map each live bottle's guest IP → `bottle_id` from the orchestrator registry
|
||||||
(`list_bottles`).
|
(`list_bottles`).
|
||||||
@@ -100,6 +111,7 @@ as a CA rotation with zero extra machinery.
|
|||||||
|
|
||||||
## Open questions
|
## Open questions
|
||||||
|
|
||||||
- Docker / macOS parity: extend the same reconcile seam (docker `exec` instead of
|
- Docker's existing host-bind-mounted CA (`host_gateway_ca_dir`): once docker's
|
||||||
SSH) and drop docker's CA bind-mount, or leave docker on persistence? Deferred
|
`attach_bottled_agents_to_gateway` pushes the CA to running agents on bring-up,
|
||||||
to a follow-up; not blocking the Firecracker fix.
|
the bind-mount is redundant — drop it (so docker rotates like firecracker) or
|
||||||
|
keep it as belt-and-suspenders? Leaning drop, for one behaviour across backends.
|
||||||
|
|||||||
Reference in New Issue
Block a user