From 9d7f7d2f5550f9628222455107341502845d3c8e Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Tue, 6 Oct 2026 09:05:45 -0400 Subject: [PATCH] chore: Stop stamping the router image into the gateway bundle The publish workflow stamped the galactic-router tag into config/galactic-gateway/base, under a comment saying the gateway DaemonSet runs two containers. It has run one since galactic-router moved to its own DaemonSet, so the stamp matched nothing and did nothing. Remove the stamp and its comment, and drop the gateway and router architecture docs' descriptions of it, including the Known Constraints entry that flagged it. Fixes #701 Co-Authored-By: Claude Opus 5.5 --- .github/workflows/publish.yaml | 6 ------ docs/agents/ARCHITECTURE-GATEWAY.md | 7 +------ docs/agents/ARCHITECTURE-ROUTER.md | 2 +- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 895b08ec..c4dfc195 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -126,12 +126,6 @@ jobs: images: | - { path: config/galactic-cni, name: ghcr.io/datum-cloud/galactic-cni, tag: "${{ needs.publish-galactic-cni-image.outputs.tag }}" } - { path: config/galactic-router/base, name: ghcr.io/datum-cloud/galactic-router, tag: "${{ needs.publish-galactic-router-image.outputs.tag }}" } - # config/galactic-gateway/base's DaemonSet has two containers (galactic-router - # + galactic-gateway) -- the config/galactic-router/base entry above only - # stamps images within that path's own tree, not - # config/galactic-gateway/base's, so galactic-router's image needs its own - # entry here too, in addition to galactic-gateway's. - - { path: config/galactic-gateway/base, name: ghcr.io/datum-cloud/galactic-router, tag: "${{ needs.publish-galactic-router-image.outputs.tag }}" } - { path: config/galactic-gateway/base, name: ghcr.io/datum-cloud/galactic-gateway, tag: "${{ needs.publish-galactic-gateway-image.outputs.tag }}" } - { path: config/fabric-router, name: ghcr.io/datum-cloud/fabric-router, tag: "${{ needs.publish-fabric-router-image.outputs.tag }}" } # config/galactic-nat/base is not in config/kustomization.yaml's own diff --git a/docs/agents/ARCHITECTURE-GATEWAY.md b/docs/agents/ARCHITECTURE-GATEWAY.md index 2625ba44..36b8e61d 100644 --- a/docs/agents/ARCHITECTURE-GATEWAY.md +++ b/docs/agents/ARCHITECTURE-GATEWAY.md @@ -735,11 +735,7 @@ tier structure. **Publish pipeline:** `.github/workflows/publish.yaml`'s `publish-galactic-gateway-image` job builds and pushes `ghcr.io/datum-cloud/galactic-gateway`; `publish-kustomize-bundles` stamps -that tag into `config/galactic-gateway/base`. That same step also stamps -the `galactic-router` tag into the same path — a carryover from when this -DaemonSet ran both images in one pod, now stale (`daemonset.yaml` is -single-container and references no `galactic-router` image at all — see -[Known Constraints](#known-constraints)). +that tag into `config/galactic-gateway/base`. **Container image:** - `containers/galactic-gateway/Dockerfile` — golang builder → @@ -769,7 +765,6 @@ single-container and references no `galactic-router` image at all — see - **The return path is opt-in per node and fails closed at startup, not silently.** `edge_return` attaches only where `GALACTIC_GATEWAY_INTERNAL_INTERFACES` names an interface; a node that needs it and does not set it drops every reply in `KUBE-FORWARD` with nothing to say why, exactly as before this program existed. Where it *is* set, an attach failure is fatal to `setupGatewayDatapath` and the pod crash-loops rather than running with the forward half working and replies dying — the same all-or-nothing choice `edgeattach.Attach` already makes across a bond's slaves. - **A backend in another site replies through that site's edge node.** The gateway can pick a backend anywhere its `NetworkRule` reaches, and the reply then leaves through the edge node in front of *that* backend, whose own `vip_addr_table` must hold the same anycast VIP or the reply meets the unmodified kernel path and dies. Within one cluster the reconciler guarantees this; across clusters it depends on the same `NetworkRule` existing on both sides, which nothing in this repo enforces. - **`vip_table` has no active GC beyond crash-recovery reconcile.** By design (see Key Design Decisions above) — DSR keeps no flow state to leak in the first place, unlike the removed Full-NAT predecessor's `conn_table`, which relied on `BPF_MAP_TYPE_LRU_HASH` self-eviction for the same purpose. -- **`publish.yaml` still stamps a `galactic-router` tag into `config/galactic-gateway/base`.** A leftover from when this DaemonSet ran both images in one pod (see [CI/CD](#cicd)) — harmless today only because the string it replaces no longer appears in this single-container manifest, not because the step was updated to reflect the split. Worth removing in `.github/workflows/publish.yaml` rather than relying on that. - **Egress is out of this binary's scope, not unimplemented.** An earlier plan (`docs/plans/865-edge-gateway-nat66-egress.md`) proposed adding a second, egress-masquerading XDP personality to this same program and process; that approach was superseded by a separate, sharded stateful egress translation tier (`galactic-nat`, its own binary — see `cmd/galactic-nat` and `internal/controller/egressshard_controller.go`) rather than built here. `NetworkRule`/this datapath remain ingress-only: external client → VIP → tenant backend. --- diff --git a/docs/agents/ARCHITECTURE-ROUTER.md b/docs/agents/ARCHITECTURE-ROUTER.md index f3bd9bfd..07421595 100644 --- a/docs/agents/ARCHITECTURE-ROUTER.md +++ b/docs/agents/ARCHITECTURE-ROUTER.md @@ -300,7 +300,7 @@ gateway) — it is not duplicated per architecture doc; see [ARCHITECTURE-GATEWAY.md](ARCHITECTURE-GATEWAY.md#cicd) for each binary's own publish/image details. -**Publish pipeline:** `.github/workflows/publish.yaml`, modeled on the `compute` repo's. Runs on every push and on published releases, via reusable `datum-cloud/actions` workflows: `publish-galactic-cni-image`, `publish-galactic-router-image`, and `publish-galactic-gateway-image` each build and push their own image (`ghcr.io/datum-cloud/galactic-cni`, `ghcr.io/datum-cloud/galactic-router`, `ghcr.io/datum-cloud/galactic-gateway`), and `publish-kustomize-bundles` (which `needs` all three image jobs) pushes `config/` as an OCI Kustomize bundle (`ghcr.io/datum-cloud/galactic-kustomize`), using the `images` input (`datum-cloud/actions` v1.20.0+) to stamp each job's real published tag into `config/galactic-cni`, `config/galactic-router/base`, and `config/galactic-gateway/base` respectively (the last of these getting both the router and gateway tags, since that base runs both images in one pod) — the bundle ships with matching versioned image references, not `:latest`. This replaced the old single-image `.github/workflows/release.yaml` (removed — see history below) with per-binary images, matching the split `deploy/containerlab/` already used for local dev. +**Publish pipeline:** `.github/workflows/publish.yaml`, modeled on the `compute` repo's. Runs on every push and on published releases, via reusable `datum-cloud/actions` workflows: `publish-galactic-cni-image`, `publish-galactic-router-image`, and `publish-galactic-gateway-image` each build and push their own image (`ghcr.io/datum-cloud/galactic-cni`, `ghcr.io/datum-cloud/galactic-router`, `ghcr.io/datum-cloud/galactic-gateway`), and `publish-kustomize-bundles` (which `needs` all three image jobs) pushes `config/` as an OCI Kustomize bundle (`ghcr.io/datum-cloud/galactic-kustomize`), using the `images` input (`datum-cloud/actions` v1.20.0+) to stamp each job's real published tag into `config/galactic-cni`, `config/galactic-router/base`, and `config/galactic-gateway/base` respectively — the bundle ships with matching versioned image references, not `:latest`. This replaced the old single-image `.github/workflows/release.yaml` (removed — see history below) with per-binary images, matching the split `deploy/containerlab/` already used for local dev. **Container image:** - `containers/galactic-router/Dockerfile` — golang builder → `gcr.io/distroless/static:nonroot`, `ENTRYPOINT ["/galactic-router"]`. No shell or CLI tools: `galactic-router` drives VRF/SRv6/route/BGP state entirely through the netlink and GoBGP Go libraries, never shells out. Pushed by `publish.yaml` as `ghcr.io/datum-cloud/galactic-router`.