Add V2 PhysicalContainerNetwork resource and controller - #226
Draft
David Negstad (danegsta) wants to merge 5 commits into
Draft
Add V2 PhysicalContainerNetwork resource and controller#226David Negstad (danegsta) wants to merge 5 commits into
David Negstad (danegsta) wants to merge 5 commits into
Conversation
David Negstad (danegsta)
marked this pull request as draft
July 31, 2026 21:39
Adds the first V2 physical network primitive, following the patterns established by PhysicalContainer and PhysicalContainerImage. PhysicalNetwork either creates a runtime container network from an explicit networkName or tracks an existing one by networkID, and reports the observed network identity, driver, IPv6 setting, and address allocations. The spec is immutable after create. Created networks are stamped with the persistent and creator-process labels so startup harvesting can reclaim them after a DCP crash. The controller performs three runtime operations: create (queued, so a blocking runtime call does not stall reconciliation), inspect, and remove. Creation is guarded by an active namespace; deletion bypasses that gate so cleanup can finish after the namespace is gone. Removal is confirmed by re-inspecting rather than by interpreting the orchestrator error, because a partial-failure result covers both an already-absent network and one that still has containers attached. A ready network re-inspects on the monitoring delay so a network removed outside of DCP is noticed, and the status projection reports no change when the inspection is unchanged, so steady state produces no writes. Registers the type with the scheme and API server, the controller with the controller runner and both integration test environments, and the kind with namespace cleanup, ordered after physical containers because a network cannot be removed while containers are attached to it. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2bcfab76-f43d-4564-a714-303ce7779074
Aligns the resource name with the existing PhysicalContainerImage naming convention. Resource path becomes physicalcontainernetworks and the short name becomes pcn. The roadmap's future PhysicalVolume is renamed to PhysicalContainerVolume in docs/v2-resource-plan.md for the same consistency. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2bcfab76-f43d-4564-a714-303ce7779074
A repeated identical runtime inspection failure produces no status change, and with no watch subscription or cache resync the resource was left with nothing scheduled to retry it, wedging it in Failed until an unrelated update arrived. Recoverable failures now request another reconciliation and pace it at LongDelay, matching how V1 handles an unhealthy runtime; terminal creation failures continue to not requeue. Existing delay jitter keeps retrying networks from polling the runtime in lockstep. Also narrows the shared network cleanup helper so it confirms absence instead of blanket-tolerating ErrIncomplete, which is also returned when removal fails. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2bcfab76-f43d-4564-a714-303ce7779074
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2bcfab76-f43d-4564-a714-303ce7779074
The Active namespace fallback reconcile landed in the base branch, so the recorded gap no longer applies. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2bcfab76-f43d-4564-a714-303ce7779074
David Negstad (danegsta)
force-pushed
the
danegsta-danegsta-v2-physical-network
branch
from
August 11, 2026 20:24
5a8a703 to
aedb6ff
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.
Stacked on #223 — this PR targets
danegsta-v2-namespace-support, notmain. Review #223 first.Implements follow-up roadmap item 1 from
docs/v2-resource-plan.md: a V2PhysicalContainerNetworkresource representing one concrete container runtime network. The name mirrors the existingPhysicalContainerImage; the resource path isphysicalcontainernetworksand the short name ispcn.What it adds
api/v2/physical_container_network_types.go—PhysicalContainerNetworkwith an immutable spec. EithernetworkName(create a new runtime network) ornetworkID(track an existing one), never both.preserveOnDeletionkeeps the runtime network in place on deletion, and applies in track-only mode too, mirroringPhysicalContainer.controllers/physical_container_network_controller.go+physical_container_network_data.go— reconciler using the establishedObjectStateMap/ deferred-op / queued-work pattern.PersistentTypes), the controller runner, both integration test environments, namespace cleanup, and resource cleanup ordering.Design notes
networkNameis required on the create path and is not generated. Uniquifying a user-facing name belongs in the logical layer, which does not exist yet. Validated against^[a-zA-Z0-9][a-zA-Z0-9_.-]*$, which is Podman'sNameRegex; Docker applies no pattern to network names. This is deliberately a separate constant fromvalidContainerName, which requires at least two characters.CreateNetwork,InspectNetworks,RemoveNetworks. No connect/disconnect (that is container-side, roadmap item 2) and noWatchNetworkssubscription.PhysicalContainerImagecancels pulls, but images are shared artifacts that are never removed on deletion, so there is nothing to orphan.)MonitoringDelayso a network removed outside of DCP is noticed, and the status projection returns no change when the inspection is unchanged, so steady state produces no writes.Faileduntil an unrelated update arrived. Recoverable failures therefore request another reconciliation and pace it atLongDelay(5s ± 2s), matching how V1 handles an unhealthy runtime; a terminal creation failure still schedules nothing. The existing delay jitter keeps many retrying networks from polling the runtime in lockstep.Testing
api/v2) and for the controller's terminal-failure guard, creation labels, status projection idempotence, and progress record (controllers).InspectNetworkCallCountandBlockCreateNetwork/CreateNetworkCallCounttoTestContainerOrchestrator, mirroring the existing container helpers.SetRuntimeHealthis global, and it was verified in both directions: it fails when the retry is reverted and passes with it restored.removeRuntimeNetworkOnCleanupno longer blanket-toleratesErrIncomplete. That error is returned both for a network that is already gone and for one that could not be removed, so the helper now re-inspects and only ignores the error once the network is confirmed absent.make generateproduces no uncommitted diff (the two newnames_matchwarnings forIPv6are the same shape as the pre-existingapi/v1ContainerNetworkSpec,IPv6warnings),make lintreports 0 issues, andmake testpasses.Docs
docs/v2-resource-plan.mdmovesPhysicalContainerNetworkinto the current foundation and renumbers the remaining physical-layer items. A new item records thatharvestAbandonedNetworksfilters onwithCreatorrather thannonPersistentWithCreator, so a network withpreserveOnDeletion: trueis still reaped after a DCP crash. That asymmetry is inherited from V1 and is deliberately left unchanged here. Another item records thatPhysicalContainerImagenever retries a repeated identical inspection failure; that gap belongs to #223's code. The status guidelines also now describe the recoverable-versus-terminal failure pattern so future physical resources follow it. The roadmap's futurePhysicalVolumeis also renamed toPhysicalContainerVolumeso the naming stays consistent.Every validation workflow in
.github/workflowsis gated tomain,release/*, andproductiononpull_request:pull_requestbranchesbuild-test.ymlmain,release/*,productionlint.ymlmain,release/*,productionvalidate-generated.ymlmain,release/*,productionaspire-regression.ymlmainBecause this PR targets
danegsta-v2-namespace-support, the only check that will ever report islicense/cla. A green checkmark on this PR does not mean it was validated. That matters here in particular: this change touches container-runtime code paths, where platform differences surface, and it regenerates deepcopy/model-name/openapi files thatvalidate-generated.ymlwould normally verify.Validation performed instead:
make generate(no uncommitted diff),make lint(0 issues), andmake test— macOS/arm64 only.workflow_dispatchruns against this head branch for the three workflows that would otherwise have covered it:c2f8fe7— Build and Test success on all three platforms, Lint success, Check Generated Files success.598c09b— Lint success, Check Generated Files success. Build and Test was dispatched three times on this SHA: once green on all three platforms, and twice red onmacos-latestonly.aedb6ff(rebased onto Add V2 namespace and physical container resources #223 commit29c3fe1) — Build and Test success on all three platforms, Lint success, Check Generated Files success. A duplicate Build and Test run failed only on Windows becauseTestPersistentContainerRecordsWorkloadIDcould not remove an open temporary SQLite file; its macOS job was cancelled, and the other run on the identical SHA passed Windows.Known flake:
TestV2NamespaceControllerCleansUpPhysicalContainersThe two red macOS runs above both failed the same test from #223, and the same SHA passed on the same platform, so this was timing-dependent rather than a deterministic break.
ubuntu-latestandwindows-latestwere green on every one of those runs. I could not reproduce it locally in eight full-suite runs, including the exact CI configuration (-race, no-parallel, and a constrainedGOMAXPROCS).In both failures the namespace remained at
phase: Activewith adeletionTimestampand its finalizer for the full 180s, which means the deletion path never made progress. The exact lost-event mechanism was not conclusively reproduced or proven. However,manageNamespacereturnednoChangefor anActivenamespace, so nothing was requeued and the controller depended entirely on watch events from that point, while DCP configures no cache resync. That left no safety net for a missed watch event or a reconciliation that observed cached state predating deletion.The defensive fix landed where the code belongs, in base PR #223 commit
29c3fe1. Active namespaces now receive a slowMonitoringDelayfallback reconciliation, while deleting namespaces retainStandardDelay. This branch was rebased onto that fix, roadmap item 9 was removed as resolved, and the subsequent Build and Test run passed all three platforms.Please do not retarget this PR to
mainto obtain CI — that would pull PR #223's diff into this one. Once #223 merges, this PR retargets tomainautomatically and picks up real CI.Out of scope
PhysicalContainerVolume(item 1 of the remaining physical-layer work) and rewiringPhysicalContainerto referencePhysicalContainerNetwork(item 2).