feat(reconcile): reprovision CA, git-gate, and egress tokens on gateway bring-up (PRD 0081)
prd-number-check / require-numbered-prds (pull_request) Successful in 10s
tracker-policy-pr / check-pr (pull_request) Successful in 16s
lint / lint (push) Failing after 1m1s
test / unit (pull_request) Successful in 56s
test / image-input-builds (pull_request) Successful in 1m0s
test / integration-docker (pull_request) Failing after 3m7s
test / coverage (pull_request) Has been skipped
prd-number-check / require-numbered-prds (pull_request) Successful in 10s
tracker-policy-pr / check-pr (pull_request) Successful in 16s
lint / lint (push) Failing after 1m1s
test / unit (pull_request) Successful in 56s
test / image-input-builds (pull_request) Successful in 1m0s
test / integration-docker (pull_request) Failing after 3m7s
test / coverage (pull_request) Has been skipped
On a gateway cold boot, reconcile every live agent VM against the fresh gateway: push the new CA into each agent's trust store, re-provision git-gate repos/creds from the persisted upstreams snapshot, and restore egress tokens. Per-bottle failures are logged and skipped rather than aborting the whole reconcile. New: reconcile.py — attach_bottled_agents_to_gateway, _push_ca, _reprovision_git_gate, _guest_ip_from_config. New: git_gate/provision.py writes upstreams.json after key provisioning so the bring-up reconcile can reconstruct the upstream table without the manifest. Wired into FirecrackerInfraService.ensure_running() cold-boot path; base.py BottleBackend gets a no-op default. Old _reprovision_running_bottles removed from consolidated_launch.py (superseded by reconcile.py). Tests migrated and extended.
This commit is contained in:
@@ -8,6 +8,7 @@ imported (`deploy_key_provisioner`) to keep its cost off the host path.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import dataclasses
|
||||
from pathlib import Path
|
||||
@@ -138,7 +139,32 @@ def provision_git_gate_dynamic_keys(
|
||||
if upstream.name not in updated_names:
|
||||
updated.append(upstream)
|
||||
|
||||
return dataclasses.replace(plan, upstreams=tuple(updated))
|
||||
final_plan = dataclasses.replace(plan, upstreams=tuple(updated))
|
||||
_write_upstreams_snapshot(stage_dir, final_plan.upstreams)
|
||||
return final_plan
|
||||
|
||||
|
||||
def _write_upstreams_snapshot(
|
||||
stage_dir: Path, upstreams: tuple[GitGateUpstream, ...]
|
||||
) -> None:
|
||||
"""Persist the fully-resolved upstream table to `upstreams.json` in
|
||||
`stage_dir` so the bring-up reconcile can re-provision git-gate without
|
||||
the manifest. Written after dynamic keys are provisioned so every
|
||||
identity_file is set."""
|
||||
data = [
|
||||
{
|
||||
"name": u.name,
|
||||
"upstream_url": u.upstream_url,
|
||||
"upstream_host": u.upstream_host,
|
||||
"upstream_port": u.upstream_port,
|
||||
"identity_file": u.identity_file,
|
||||
"known_host_key": u.known_host_key,
|
||||
}
|
||||
for u in upstreams
|
||||
]
|
||||
snapshot = stage_dir / "upstreams.json"
|
||||
snapshot.write_text(json.dumps(data, indent=2))
|
||||
snapshot.chmod(0o600)
|
||||
|
||||
|
||||
__all__ = [
|
||||
|
||||
Reference in New Issue
Block a user