Skip to content

docs: Revise 854 EndpointSlice plan after review - #376

Open
privateip wants to merge 4 commits into
mainfrom
docs/854-endpointslice-plan-revisions
Open

docs: Revise 854 EndpointSlice plan after review#376
privateip wants to merge 4 commits into
mainfrom
docs/854-endpointslice-plan-revisions

Conversation

@privateip

Copy link
Copy Markdown
Contributor

Summary

A review pass against the current repo found the plan's file paths and CNI chain topology were stale after a refactor, and surfaced two real design gaps: wiring EndpointSlice publish as a step after publishBGPState can trigger the existing rollback path to delete a still-live, shared BGPAdvertisement, and the proposed GC extension assumed a per-pod liveness signal that doesn't exist in the current annotation scheme.

Revise the plan to fix the stale references, flag the rollback risk with three candidate fixes, and replace the GC extension with a recommendation to use a Kubernetes ownerReference to the owning Pod as the primary cleanup mechanism, keeping the explicit DEL as the fast path. Add two new open decisions for VM/tap-workload scope and the GC mechanism choice.

Test plan

  • Reviewer confirms the revised paths/topology match the current repo state
  • Reviewer agrees the Phase 4 rollback-risk fix and Phase 8 ownerReference approach are sound before implementation starts

Related to datum-cloud/enhancements#854

🤖 Generated with Claude Code

0xmc
0xmc previously approved these changes Aug 17, 2026

@0xmc 0xmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation matches reality, and reality seems sound.

privateip and others added 4 commits August 18, 2026 15:39
A review pass against the current repo found the plan's file paths and CNI chain topology were stale after a refactor, and surfaced two real design gaps: wiring EndpointSlice publish as a step after publishBGPState can trigger the existing rollback path to delete a still-live, shared BGPAdvertisement, and the proposed GC extension assumed a per-pod liveness signal that doesn't exist in the current annotation scheme.

Revise the plan to fix the stale references, flag the rollback risk with three candidate fixes, and replace the GC extension with a recommendation to use a Kubernetes ownerReference to the owning Pod as the primary cleanup mechanism, keeping the explicit DEL as the fast path. Add two new open decisions for VM/tap-workload scope and the GC mechanism choice.

Related to datum-cloud/enhancements#854

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Open Decision 5 asked whether VM/tap-attached workloads were in
scope for EndpointSlice publication, or implicitly excluded. They
are in scope, and are this issue's primary use case.

Confirmed against internal/cnitap and internal/cnibgp/prevresult.go
that Phase 4's nil-ipamResult skip was never a VM-exclusion
mechanism to begin with: ipamResult is nil only when no "ipam"
block is configured on the master plugin's stanza, which happens
for galactic-veth and galactic-tap alike. A tap stanza configured
with IPAM produces the same pool-allocated address publishBGPState
already advertises via BGP for that attachment today, so it flows
through Phase 4's existing publish path with no VM-specific branch
needed.

Practical implication for operators: tap-backed VMs need an "ipam"
block configured for an EndpointSlice (or a BGP advertisement) to
exist at all. Also flagged as a caveat, not a blocker: the
pool-allocated address is never confirmed as actually bound inside
the guest (no DHCP push, no ARP/NDP snooping in the current chain)
- a pre-existing property of tap addressing, not something this
issue introduces.

Also fixed two pre-existing misnumbered cross-references to "Open
Decision 5" that meant the GC/ownerReference decision (Decision 6).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Open Decision 4 (Phase 4's rollback-risk callout) offered three
candidate fixes for the BGPAdvertisement wrongful-deletion hole
and left the pick open. Resolved: fix #1, narrowing
advertisementCreated's assignment (bgp.go:412) to gate on
op == controllerutil.OperationResultCreated, mirroring
vrfInstanceCreated's existing pattern (bgp.go:353-362) exactly.

Verified by reading the actual code, not just the two candidates
in isolation:

- advertisementCreated has exactly one setter (bgp.go:412) and one
  reader (resourceTracker.cleanup, resource.go:92) across the
  whole repo. No DEL/CHECK/GC path depends on its current
  over-broad "true on any successful write" semantics, so
  narrowing it is a ~2-line diff with zero other blast radius.

- Fix #3 ("cleanup never deletes an only-updated advertisement")
  needs the identical op-result signal captured at the same
  CreateOrUpdate call site to know create-vs-update after the
  fact - any real implementation of it collapses into fix #1
  byte-for-byte. The only way to make it a distinct change is a
  second, redundant field nothing else would consume.

- Fix #2 (fold EndpointSlice publish into publishBGPState's retry
  closure) doesn't close the gap by itself: cmdAdd's deferred
  rollback fires on any non-nil error regardless of which step
  produced it, so a failure there still hits the same
  wrongful-deletion path unless advertisementCreated's semantics
  are also fixed. Reasonable as a complementary retry-robustness
  improvement, but not a substitute, and not adopted here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Open Decision 6 flagged a choice between the ownerReference and
netns-heuristic-sweep approaches for Phase 8's cleanup backstop,
with a recommendation but no adopted decision. Adopted the
recommended ownerReference-to-Pod approach as-is:

- Phase 8: during ADD, set metadata.ownerReferences on the
  EndpointSlice to the owning Pod; the API server's own garbage
  collector deletes it when the Pod is deleted. Phase 5's explicit
  delete-on-DEL remains the fast path. The netns-heuristic fallback
  is not adopted - more moving parts for no concrete gap identified.
- Phase 7: needs a pods get grant on galactic-cni's ServiceAccount
  (to look up the owning Pod's UID) - the only RBAC this decision
  requires.
- Phase 9: does NOT touch ARCHITECTURE-ROUTER.md's GC section -
  internal/gc/gc.go and config/router/rbac.yaml are untouched by
  this issue, since the ownerReference approach needs no
  galactic-router-side changes at all.
- Phase 10: gc_test.go/gc_ebpf_test.go need no changes; the e2e
  case should additionally assert the EndpointSlice disappears on
  Pod force-delete via the ownerReference.

Threaded the resolution through every cross-reference that
depended on this decision (Phase 7's revision note, Phase 9's
revision note, Phase 10's test note, PR sequencing item 5, and
Open Decision 6 itself).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Galactic CNI: publish per-pod SRv6 SID + tenant identifier via EndpointSlice for VPC HTTP ingress backends

2 participants