Add PersistentKeepalive, consolidate resource rendering, fix docs (#4, #1) - #39
Merged
Merged
Conversation
This was referenced Aug 28, 2026
Peer configs carried no PersistentKeepalive, so an idle client would not retry a handshake until it had traffic of its own, and its NAT/conntrack entry would expire leaving the server unable to initiate toward it. This matters most after the server pod is rescheduled, which is the operator's primary recovery path. Adds spec.persistentKeepalive as a pointer with a CRD default of 25, so an explicit 0 can disable it — WireGuard reads zero as "off", which a non-pointer field could not distinguish from unset. The Go constant is only the nil fallback for objects stored before the field existed. The line is rendered once and interpolated into all three config flavors (tunnel, dual-mode direct, and plain). When disabled the interpolated string is empty, leaving output byte-identical to before. release.yaml is regenerated for the new CRD property. It is the documented install path and a generated artifact, so hack/release-file-drift.sh fails if it falls behind config/. Regenerated at the committed image pins; bumping those is release-time work, not gate work. Closes #4 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XEBcAdEeo5Kp8L6ns3yzRs Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XcHdnmhuAbyBYG2VfwuPDD
…ders The internal/resources package was entirely dead: all four builders were constructed in SetupWithManager but no method was ever called, because every resource was rendered by an inline function on the reconciler instead. The two copies had already drifted, and every planned feature touches this rendering — so changes made in the wrong copy would have had no runtime effect. Repoints all twelve call sites at the builders, adding error handling since the builders return (T, error) where the inline functions returned bare pointers, and deletes the six inline functions. The duplicated port and image constants in the controller are removed in favour of the ones in internal/resources, as is labelsForWireguard, which only the deleted functions called. Three differences in rendered output, all deliberate: - Deployment: the metrics container port the builder declared is now emitted. The agent serves metrics on it and a metrics Service already targets it. - Deployment: the http container port was declared as the WireGuard port while both probes target the health port. Wrong in both copies, so not drift; corrected here since containerPort is purely declarative. - ConfigMap: the builder sets an empty Data map where the inline version left it nil. Data is omitempty and a zero-length map is omitted, so the serialized object is unchanged. None of these reach existing deployments. The reconciler only re-renders on four triggers — agent image, userspace flag, wstunnel sidecar presence, and scheduling settings — and none of them compares container ports, so a running Deployment keeps its current spec until an unrelated trigger fires. Declarative reconciliation is #2. The Service, Secret and ConfigMap builders were verified equivalent to the inline versions before switching, and are otherwise unchanged. Closes #1 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XEBcAdEeo5Kp8L6ns3yzRs Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XcHdnmhuAbyBYG2VfwuPDD
README: - Support link pointed at the upstream issue tracker; this fork has its own. - Features list omitted IPv6 support and per-peer egress network policies, both of which are implemented. - Install instructions silently install the upstream operator, which is now diverging from this fork. The URLs are left working — this fork has no release to point at yet — but the divergence is now called out, with a pointer to #36. CONTRIBUTING was a single placeholder line. It now covers the build and codegen entry points, the files that must be regenerated rather than hand-edited, and the engineering practices the roadmap work is held to. These previously existed only as a GitHub issue comment, so nobody reading the repository could find them. ROADMAP 0.1 still described consolidating only the two Deployment builders. That scope was widened to all four resource types, so the section now matches the issue and what was implemented. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XEBcAdEeo5Kp8L6ns3yzRs Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XcHdnmhuAbyBYG2VfwuPDD
jacaudi
force-pushed
the
claude/init-container-support-review-b953sx
branch
from
August 29, 2026 17:29
d60e365 to
9320283
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #4 and #1, the two Phase 0 foundations, plus a documentation pass. Three independent commits, reviewable separately.
Rebased onto
a4c7b78and no longer touches CI. This PR originally carried a fourth commit adopting an orchestrator CI pipeline; #43 landed that work instead, so it has been dropped wholesale. The diff now contains no file under.github/, no release-please config, and no.releaserc.json. Commit subjects were rewritten to conventional-commit form so release-please — live onmainsince #43 — reads them; authors, dates and bodies are unchanged.feat:— Add PersistentKeepalive to generated peer configs (#4)Peer configs carried no
PersistentKeepalive, so an idle client would not retry a handshake until it had traffic of its own, and its NAT/conntrack entry would expire leaving the server unable to initiate toward it. That matters most right after the server pod is rescheduled, which is this operator's primary recovery path.Adds
spec.persistentKeepaliveas*int32with a CRD default of 25. The pointer is load-bearing: WireGuard reads0as disabled, and a plainint32withomitemptycould not distinguish "user asked for 0" from "user said nothing". The Go constant is only the nil fallback for objects stored before the field existed.The line is rendered once and interpolated into all three config flavors — tunnel, dual-mode direct, and plain. When disabled the interpolated string is empty, leaving output byte-identical to before.
release.yamlis regenerated in this commit. It is the documented install path and a generated artifact, so the new CRD property would otherwise failhack/release-file-drift.sh. Regenerated at the committed image pins — bumping those is release-time work.refactor:— Consolidate resource rendering onto internal/resources builders (#1)internal/resourceswas entirely dead code: all four builders were constructed inSetupWithManagerbut no method was ever called, because each resource was rendered by an inline function on the reconciler instead. The two copies had already drifted.Repoints all twelve call sites, deletes the six inline functions, and removes the duplicated constants (plus
labelsForWireguard, which only the deleted functions called).Three deliberate differences in rendered output:
metricscontainer port now emittedhttpcontainer port was 51820 while both probes target 8080Datamap vs nilomitemptyomits a zero-length map — serialized object unchangedNone of these reach existing deployments: the reconciler only re-renders on four triggers (agent image, userspace flag, wstunnel sidecar, scheduling settings) and none compares container ports. Declarative reconciliation is #2.
docs:— Correct and extend project documentationVerification
The original version of this PR shipped unverified — nothing had been compiled or tested, because the Go toolchain and module proxy were unreachable in that environment. That is no longer true. Everything below was run locally against this branch:
task cigo mod tidy -diffclean, fmt cleango test ./... -racetask go:integration(envtest,-race,-tags=integration)internal/controller78.8smake manifests generateconfig/apish hack/release-file-drift.shrelease.yaml matches config/Four things worth calling out, since they are exactly what the earlier version could not check:
make manifests generateproduces no diff, so the by-handpersistentKeepaliveCRD schema and thezz_generated.deepcopy.gopointer copy match what controller-gen v0.16.5 emits.internal/controlleris behind//go:build integrationas of ci: adopt the fleet taskfile and lint baseline, and clear the debt it surfaces #42; the new specs carry the tag and were proven to execute rather than to be silently skipped — a focused run reportsWill run 4 of 23 Specs … 4 Passed, and the suite takes ~78s rather than seconds.new-from-merge-base: origin/mainresolved its merge base; had it failed open it would have reported the 113 pre-existing findings instead of 0.release.yamldrift is a new gate this PR predates. Adding a CRD property changes the rendered manifest, so it is regenerated in thefeat:commit.Closes #4
Closes #1
🤖 Generated with Claude Code
https://claude.ai/code/session_01XcHdnmhuAbyBYG2VfwuPDD