Skip to content

Add V2 logical container network lifecycle management - #298

Merged
David Negstad (danegsta) merged 83 commits into
mainfrom
danegsta-logical-network-controller
Nov 3, 2026
Merged

David Negstad (danegsta) merged 83 commits into
mainfrom
danegsta-logical-network-controller

Conversation

@danegsta

@danegsta David Negstad (danegsta) commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Problem

The V2 foundation defines logical network resources but does not yet realize them. Logical containers therefore cannot create with requested logical network attachments, and persistent networks have no logical lifecycle-key or workload-ownership management.

Solution

Add the logical container network controller over the existing PhysicalContainerNetwork layer, following the logical-container ownership and lifecycle patterns established in #295. That foundation is now merged; this PR targets main.

The logical controller manages session, persistent, and existing-network policy. Session container networks are created and removed with their logical resource. Persistent container networks are retained, reuse matching managed or unmanaged container networks, and replace changed DCP-managed container networks using API-owned lifecycle keys. Existing mode only observes a named container network. V2 physical resources manage backing-resource creation, observation, membership changes, and cleanup.

Behavior and integration

  • Dependency handoff: new and replacement logical containers translate a nonterminating, nonfailed LogicalContainerNetwork's published PhysicalContainerNetwork reference and aliases during Pending. A published reference is sufficient even while the logical network is Pending or Unknown; PhysicalContainer handles backing-resource readiness. Existing physical connection resources track membership, so no new logical connection kind is introduced. Adopted containers retain their existing attachments.
  • Terminal startup failure: a failed logical network ends preparation before handoff. After handoff, failed dependency API resources terminate PhysicalContainer startup, allowing the logical controller to project the failure and release an unused creation lease. Replacing the dependency does not resume that failed startup.
  • Persistent ownership and leases: V1 and V2 persistent-network startups use exclusive creation leases keyed by container network name, including within one DCP process. Verified ownership for created/replaced container networks is recorded before releasing the lease; namespace workload annotations override the global workload ID. Ordinary adoption does not claim workload cleanup ownership. Leases protect creation, not the lifetime of references to an existing container network.
  • Diagnostics and cleanup: LogicalContainerNetwork and PhysicalContainerNetwork expose system-only log endpoints, with diagnostics from owned physical API resources forwarded to the logical stream. Owned physical API resources follow the foundation's cleanup-acknowledgment protocol; the logical hold retains the API object for observation without blocking backing-resource cleanup.

Includes production/test wiring, generated API updates, and real-API/running-controller coverage. Controller-state String() methods are also colocated with their enum definitions without behavioral changes.

Validation

  • Regenerated API artifacts and built native DCP/test prerequisites.
  • Passed focused race-enabled coverage for persistent reuse/replacement, workload settlement, V1/V2 lease contention, attachment realization, cleanup, and terminal dependency failures before/after handoff.
  • The full native macOS race suite passed after merging main; a later full run exposed an unrelated V1 health-check snapshot race in unchanged code. Affected regression coverage passes.
  • Passed Windows/macOS/Linux lint.
  • Real-runtime and advanced test switches were disabled; no local real-runtime or E2E suites were run.

Introduce logical container and network APIs, delegate logical container lifecycle operations to physical resources, and track persistent workload ownership. Standardize V2 deletion dispatch and terminal startup/stop outcomes with shared API-backed coverage.

Co-authored-by: Copilot App <[email protected]>
Exercise logical readiness through the shared API server and running physical controller using runtime port-mapping fault injection. Remove redundant private deletion-handler tests already covered by retained-resource integration cases.

Co-authored-by: Copilot App <[email protected]>
Delegate runtime network realization to physical resources, manage persistent lifecycle keys and shared leases, and translate logical network attachments for new containers without changing adoption behavior.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Bring the feature branch onto the base used by PR CI, including the upstream WSLC runtime changes. Update three runtime-label test callers to the map contract while preserving slice-valued API labels.

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Use stable key sorting for logical container environment, container labels, and build labels. Resolve namespace workload overrides during asynchronous persistent ownership settlement, retaining startup leases on lookup or recording errors and supporting overrides without a global default.

Co-authored-by: Copilot App <[email protected]>
Resolve workload annotation overrides during persistent network lease settlement, retaining leases on namespace lookup failures, and preserve duplicate label precedence in lifecycle keys.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Preserve all build directives selected by the daily CLI template instead of requiring an explicit SDK directive. Leave generated AppHost validation to Aspire, supporting package-based templates without importing the unrelated watcher or dependency changes from PR #292.

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Make the selected runtime ID explicitly pending and clear it together with the generated session name after physical creation or verification. Project inline image references from the physical creation spec instead of retaining an adopted runtime ID as a marker.

Co-authored-by: Copilot App <[email protected]>
Retain the runtime ID only as a pending adoption input and clear it once the physical resource owns the selected identity.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Replace per-controller ownership permutations and private environments with one persisted-ownership scenario in the shared real API/controller environment.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Preserve the parent pending-input lifetime and inline-image projection changes alongside child network realization documentation.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
… refs

Use logical network readiness and its published physical reference instead of duplicating physical lookups. Create inline image resources before waiting for networks so image preparation can proceed independently.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Use shared setup for scoped lifecycle and ownership scenarios, consolidate deletion ordering coverage, move duplicate-label sorting regression to API tests, and remove unrelated cancellation and runtime retry checks.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Add scoped resource-stream nesting that preserves context, primary bindings, filters, and independent cleanup. Bind V2 container diagnostics by resource UID and forward owned physical container diagnostics to the logical owner's stream, including asynchronous operation failures. Keep resource-file producer names per entry and verify fanout without duplicate process or resource entries. This provides capture and routing only; V2 log subresource registration remains separate.

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Share watch-driven log storage and query handling across API versions while preserving V1 contracts. Add logical and physical container stdout, stderr, and system streamers with one physical-UID runtime capture, snapshot-only logical source resolution, independent client lifetimes, namespace preservation, and explicit unsupported-source errors. Project backing physical identity into logical status and exercise actual endpoints, cancellation, and existing V1 log behavior.

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Replace per-kind cleanup handlers with one uncached list and bounded delete executor, preserving dependency ordering and pending-resource diagnostics.

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Declare logical and physical container log subresources alongside their parents, retaining only resource-neutral storage construction and contracts in shared log types.

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Capture pull and build output, serialize image acquisition with exclusive leases, and project image startup and container runtime sources directly onto logical resources. Preserve the V1 watcher handoff, fix nested resource sink failure reporting, and share CaptureFile between V1 and V2 controllers.

Co-authored-by: Copilot App <[email protected]>
Preserve image-log source projection before waiting on published logical network readiness.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Return readiness, condition reason, and lookup error from a read-only namespace check. Let all six callers choose their phases, Ready conditions, logging, and reconciliation flags while preserving existing admission behavior.

Document the reduced helper contract and cover initial lookup failure, recovery, and post-initialization stop behavior through the real API/controller environment.

Co-authored-by: Copilot App <[email protected]>
Use the reviewer's suggested message to describe listing the physical containers backing the logical resource.

Co-authored-by: Copilot App <[email protected]>
When a physical UID is recorded but the cached owner list is empty, confirm absence through an uncached namespace list filtered by controller-owner UID. Reuse existing container/image deletion loops for discovered children and retry lookup errors without releasing the logical finalizer.

Cover successful creation before cache observation, duplicate owned backings, unrelated resource preservation, and cleanup completion after actual removal. Document the UID-gated confirmation rule.

Co-authored-by: Copilot App <[email protected]>
Return a completion channel for non-follow and completed-resource log copies so client backpressure does not hold resource processing locks. Preserve first-EOF behavior without registering lifecycle followers, and let storage cancellation close the response pipe to unblock delivery.

Cover finite-copy formatting, EOF, slow readers, lifecycle progress, request cancellation, and storage disposal.

Co-authored-by: Copilot App <[email protected]>
Merge origin/danegsta-v2-resource-plan at 7549958, preserving network realization and system logs across the parent lifecycle and logging changes.

Match logical containers with one lifecycle state, direct bounded preparation and lease settlement, reconciliation-local creation inputs, indexed owner discovery, and uncached verification after uncertain Create responses. Remove the logical network work queue, separate progress state, cancellation results, and backing-release flags.

Request physical deletion first, observe durable cleanup acknowledgment, settle retained ownership, and release logical holds. Cover duplicate backing cleanup, renamed owner-discovered children, cache visibility gaps, and existing network/container regressions.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
…gates

Use a published physical network reference without requiring logical readiness, while rejecting terminal logical network failure and settling the creation lease. Remove extra image observation and failure handling from Pending; retain the parent's inline-image declaration and log projection unchanged.

Verify physical-container declaration while network startup is blocked, physical-owned image failure propagation after references resolve, terminal network rejection, and unchanged adopted attachments. Update the published API reference contract and generated OpenAPI documentation.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Rely on child observation after successful preparation, avoid follow-up retries for terminal duplicate discovery, and consume physical Ready with a true Ready condition without redundant identity or generation gates. Preserve accumulated lease-settlement changes during handoff.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Base automatically changed from danegsta-v2-resource-plan to main October 30, 2026 22:16
Move all seven existing String methods unchanged into the respective controller data files and remove the centralized state-string file. Keep shared diagnostic tests in place.

Co-authored-by: Copilot App <[email protected]>

Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Treat failed network and volume references like failed image references, preserving dependency diagnostics and releasing unused startup leases without resuming after replacement.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Resolve squash-history conflicts against the incorporated V2 foundation, preserving logical network lifecycle handling, terminal dependency failures, and colocated state diagnostics while integrating the latest base fixes.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Prevent pending prerequisites from hiding later failures or required retries. Share dependency preparation states and condition reasons across resource kinds while retaining dependency diagnostics, terminal latching, and lease settlement.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Local review of head dd6f75f: one finding, inline below (comment only, no approval).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One cleanup race needs to be addressed; see the inline comment.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed PR #298 at dd6f75f6: 3 inline comments below (comment only, no approval).

Inspect runtime networks even when startup-harvest protection is contended, and wait only before reusing a found network. Allow missing persistent networks to be created during harvesting and use ordinary short retries for reuse contention without adding retry-delay state.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Confirm every empty cached owner list through the uncached reader, including after committed Creates whose response did not provide a backing UID. Cover unrecorded network, container, and image backings, confirmation failures, cleanup, and unrelated-resource preservation through running controllers.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Keep ended startup attempts from resolving and claiming replacement targets after stop is requested. Cover existing and missing runtime targets while retaining nonterminal replacement-stop behavior.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Continue observing and projecting existing inline image acquisition logs while logical container preparation is terminal. Preserve independent dependency work and lease settlement without reordering declarations or restarting startup.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Retain selected lifecycle identity independently of a decoded physical backing UID, following the parent logical container pattern. Cover failed confirmation and later owner discovery without adding runtime recovery or changing lease settlement.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
Name backing container networks directly in comments, diagnostics, documentation, and local identifiers. Reserve physical wording for V2 API resources and retain public identifiers and genuine container-engine references.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: bbe01c56-5ae4-4f36-8134-93b3b2718fd2
@danegsta
David Negstad (danegsta) enabled stacked auto-merge (squash) November 3, 2026 00:33
@danegsta
David Negstad (danegsta) merged commit 2b7aa99 into main Nov 3, 2026
12 checks passed
@danegsta
David Negstad (danegsta) deleted the danegsta-logical-network-controller branch November 3, 2026 00:54
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.

3 participants