Skip to content

Add V2 logical container lifecycle management - #295

Merged
David Negstad (danegsta) merged 37 commits into
mainfrom
danegsta-v2-resource-plan
Oct 30, 2026
Merged

David Negstad (danegsta) merged 37 commits into
mainfrom
danegsta-v2-resource-plan

Conversation

@danegsta

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

Copy link
Copy Markdown
Member

V2 physical resources provide runtime operations, but do not express the session, persistent, and existing-container lifecycle policies needed by clients. This adds that logical layer while keeping container creation, tracking, stopping, and removal in the physical controllers. Namespaced log endpoints expose runtime output, owned image preparation output, and resource-specific system diagnostics without requiring logical streamers to query child resources.

Approach

  • Add namespace-scoped LogicalContainer APIs and a controller that creates or adopts backing physical resources, selects persistent reuse or replacement using lifecycle keys, and records workload ownership before releasing startup leases. Namespace workload annotations override the global default, including when that default is empty.
  • Compute lifecycle keys in the API types using the established shared hash initialization. Logical build-content identity comes from caller-supplied digests, without reading files or ambient inputs to calculate the logical lifecycle key.
  • Create owned physical containers and inline images with both physical cleanup and logical-backing finalizers atomically. The logical hold protects the reference lifetime until operation outcomes and ownership settlement permit cleanup; unexpected backing identity, ownership, or hold loss is terminal rather than triggering recreation.
  • Keep compound deletion-request/operation-readiness guards before normal reconciliation. Dependency-pending startup can stop without waiting for unavailable prerequisites, while in-flight creation/start outcomes must settle. Normal management owns initialization and status projection; completed deletion discards controller data with finalizer removal. A common namespace guard gates initial work without a namespace state-machine stage.
  • Verify uncertain backing Create errors immediately through uncached lookup, accepting an existing child only after owner, spec, and hold checks. Namespace cleanup uses relational metadata for resource selection and dependency ordering, with uncached lists and bounded deletes.

Logging and image acquisition

  • Physical containers expose runtime stdout, stderr, and system through their namespaced /log subresource. Physical images expose pull/build stdout and stderr, plus their own system diagnostics.
  • Logical containers expose backing-container stdout/stderr, acquisition output from owned inline images as startup_stdout/startup_stderr, and their own system stream. Externally referenced images do not contribute logical startup output; it remains available through the image's own log endpoint. Logical startup requests for external image references return empty without waiting for acquisition.
  • A common LogSource contract projects capture identity, availability, and completion from the corresponding owned physical resources. Logical streamers consume watched snapshots rather than querying children or proxying their endpoints; physical containers do not relay image output.
  • Scoped nested resource sinks forward owned physical-container and physical-image diagnostics into the logical owner's system stream. Externally referenced images do not forward system diagnostics. File-creation failures are reported outside the sink mutex, avoiding nested-sink deadlocks.
  • Share watch-driven storage/query handling with V1 while preserving its existing API and source set. Request-specific watchers stop when streaming starts; ongoing lifecycle updates use the existing kind-wide callbacks. Shared CaptureFile and filename generation support V1 startup and V2 image capture without separate startup file formats. Followers finish on source completion or resource deletion, independently of logical readiness.
  • Serialize V2 pulls with exclusive state-store leases, including same-process contenders and implicit/explicit latest spellings. Reevaluate policy after acquisition; never bypasses the lease. Docker/Podman capture non-TTY progress when output is requested; WSLC retains quiet formatting. Pull identities come from structured runtime inspection, not human-readable progress parsing.
  • Controller image inspections have a bounded retry budget that resets after successful inspection. Initial identity verification retries temporary NotFound responses; an already verified image is never silently reacquired after disappearance.

Scope and known limitations

This also introduces the LogicalContainerNetwork API foundation and namespace cleanup registration. The logical network controller and networked-container realization are separate stacked work; networked creation in this layer remains explicitly Pending until that implementation is available. Process, container-exec, and Project layers are not implemented by this PR.

Existing runtime-capture limitations shared with V1 remain outside this PR: requested line numbering in #304 and asynchronous first-capture tail selection in #305. Advanced freshness policies and persisted pull-history metadata are also deferred.

Controller behavior coverage uses the real API server and running controllers with scoped API/runtime/executor fault injection. Runtime operations are simulated in these integration scenarios; they do not claim real registry pulls or runtime builds. Equivalent-tag lease serialization is tested without adding alias semantics to the test orchestrator. Failed-pull diagnostic capture and output closure are covered at the production Docker/Podman adapter boundary using the test process executor.

Validation

  • Race-enabled API/controller/logging suites and real-API simulated lifecycle scenarios, including durable backing holds, dependency-pending cleanup, uncertain Create verification, bounded inspection retries, owned startup output, diagnostic forwarding, and independent follower lifetimes.
  • Native non-E2E repository tests and Windows/macOS/Linux lint. Host PTY-allocation failures encountered in one full run were rechecked successfully with serialized terminal tests. Real-runtime/E2E suites were not run locally.

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]>

Copilot AI 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.

🟡 Changes recommended

Persistent ownership selection and lifecycle-key normalization need correction, and deletion during process launch needs replacement integration coverage.

3 open findings
What changed in this PR

Adds V2 logical container lifecycle policies above the physical controllers, covering session creation, persistent reuse, and existing-container adoption.

Changes:

  • Adds logical APIs, lifecycle hashing, controller registration, and namespace cleanup.
  • Centralizes physical-resource deletion and makes stop/image-failure outcomes terminal.
  • Updates integration coverage and removes fake-client reconciliation tests.
File Description
test/​integration/​v2_physical_process_controller_test.go Removes fake-client process tests.
test/​integration/​v2_physical_container_volume_durability_test.go Removes fake-client volume suite.
test/​integration/​v2_physical_container_network_durability_test.go Removes fake-client network suite.
test/​integration/​v2_physical_container_network_controller_test.go Updates network references.
test/​integration/​v2_physical_container_controller_test.go Tests terminating dependencies and early stop.
test/​integration/​v2_namespace_controller_test.go Relocates namespace setup helper.
test/​integration/​test_env_common.go Adds logical-controller selection.
test/​integration/​standard_test_env.go Registers logical controller.
test/​integration/​advanced_test_env.go Registers logical controller.
plan/​v2-resource-plan.md Documents lifecycle behavior and follow-ups.
internal/​resourcecleanup/​resources.go Orders logical-resource cleanup.
internal/​resourcecleanup/​resources_test.go Checks cleanup coverage and ordering.
internal/​dcpctrl/​commands/​run_controllers.go Registers production logical controller.
internal/​dcpclient/​namespace_workload_id_test.go Consolidates workload selection tests.
internal/​dcpclient/​client_test.go Removes previous workload tests.
internal/​containers/​image_build_test.go Checks relative Dockerfile path preservation.
controllers/​physical_resource_state_string.go Removes obsolete image deletion state.
controllers/​physical_resource_invalid_state_test.go Updates invalid-state tests.
controllers/​physical_process_data.go Narrows active-operation detection.
controllers/​physical_process_controller.go Centralizes deletion dispatch.
controllers/​physical_container_volume_data.go Adds active-operation detection.
controllers/​physical_container_volume_controller.go Centralizes volume deletion.
controllers/​physical_container_network_data.go Adds active-operation detection.
controllers/​physical_container_network_controller.go Centralizes network deletion.
controllers/​physical_container_image_data.go Updates image operation states.
controllers/​physical_container_image_controller.go Centralizes deletion and cancellation.
controllers/​physical_container_data.go Adds terminal projections; simplifies state.
controllers/​physical_container_controller.go Updates deletion, startup, and stop handling.
controllers/​physical_container_controller_test.go Removes fake-client dependency test.
controllers/​namespace_controller.go Cleans logical resources.
controllers/​namespace_controller_test.go Updates cleanup concurrency setup.
controllers/​logical_container_data.go Adds logical state and status projections.
controllers/​container_network_tunnel_proxy_controller.go Updates physical network references.
controllers/​container_common.go Narrows inspection interface requirement.
api/​v2/​zz_generated.model_name.go Generates logical model names.
api/​v2/​zz_generated.deepcopy.go Generates logical deep-copy methods.
api/​v2/​physical_container_types.go Documents terminal outcomes; shares validation.
api/​v2/​physical_container_types_test.go Updates network-reference validation cases.
api/​v2/​physical_container_image_types.go Exposes reusable image validation.
api/​v2/​logical_container_types.go Defines logical container API and hashing.
api/​v2/​logical_container_network_types.go Defines logical network API foundation.
api/​v2/​logical_container_network_types_test.go Tests logical network API contracts.
api/​v2/​groupversion_info.go Registers logical storage types.
api/​v2/​container_types.go Renames network references; shares validators.
api/​v1/​container_types_test.go Checks hash stability and registration compatibility.
api/​v1/​common_types.go Appends V2 hash initialization types.
Files not reviewed (2)
  • api/v2/zz_generated.deepcopy.go: Generated file
  • api/v2/zz_generated.model_name.go: Generated file

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread api/v2/logical_container_types.go Resolved
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]>
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]>
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]>
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]>
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]>
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]>
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]>
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]>

Copilot AI 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.

🟡 Changes recommended

Resource logging can deadlock, and unresolved stream ordering, completion, and formatting defects affect log consumers.

5 open findings
3 resolved since last review
Files not reviewed (3)
  • api/v1/zz_generated.model_name.go: Generated file
  • api/v2/zz_generated.deepcopy.go: Generated file
  • api/v2/zz_generated.model_name.go: Generated file

🧠 Review effort: Balanced

Comment thread pkg/logger/resource_sink.go Resolved
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]>

Copilot AI 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.

🔵 Needs a closer look

Cross-cutting API, persistence, deletion, and concurrent logging changes need human review, particularly without real-runtime validation.

5 open issues
3 resolved since last review
3 files not reviewed
  • api/v1/zz_generated.model_name.go: Generated file
  • api/v2/zz_generated.deepcopy.go: Generated file
  • api/v2/zz_generated.model_name.go: Generated file

Review effort: Balanced

Comment thread api/v2/log_types.go Resolved
Port upstream watch-setup ordering and regression tests into internal/logstream, preserving the V1 API adapter and existing streaming handoff. Adopt Tilt v0.19.2 and namespace watcher hardening.

Co-authored-by: Copilot App <[email protected]>
Preserve the original physical source identity in a completed, unavailable descriptor so logical-only followers finish through the existing lifecycle callbacks. Cover physical deletion through an isolated real API server with no physical log request.

Co-authored-by: Copilot App <[email protected]>
Use one filename contract for command and runtime captures, preserve V1 startup filenames and runtime capture suffixes, and capture physical image output with ordinary stdout/stderr source names.

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

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.

Five additional findings after de-duplicating against the existing review.

Comment thread internal/podman/cli_orchestrator.go Resolved

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.

🤖 Copilot Code Review — PR #295

Six additional findings (all warnings) after de-duplicating against the existing reviews. The anchors are against the current head (9c7aab0b). Findings 1 and 5 were reproduced with throwaway integration tests (not committed); the rest come from reading the code and comparing with the V1 controller.

Comment thread api/v2/logical_container_types.go Resolved
Comment thread api/v2/logical_container_types.go Resolved
Separate granular lifecycle states from outstanding asynchronous work. Discover logical backings by owner metadata, require expected children before handoff, and propagate deletion to every owned child.

Preserve cleanup status before releasing finalizers, keep adopted runtimes out of workload ownership records, and retry post-pull image inspection without repeating acquisition.

Co-authored-by: Copilot App <[email protected]>
Acquire and stop the existing named runtime when stop and replace are requested before physical creation. Settle logical workload registration when the physical runtime ID is reported, without waiting for a settled lifecycle phase.

Co-authored-by: Copilot App <[email protected]>
Retain both Docker test imports and align the post-pull WSLC inspection fixture with locale-independent errors.

Co-authored-by: Copilot App <[email protected]>
Use a log-source provider capability for primary capture identity and release the observed source UID on deletion, including logical-only log consumers. Preserve existing startup and completion handling.

Co-authored-by: Copilot App <[email protected]>
Exercise the real API and running controllers with an in-use volume, verifying the grace period, abandonment status, finalizer release, and completion of namespace deletion using existing test infrastructure.

Co-authored-by: Copilot App <[email protected]>
Remove the first-match setter and rely on last-value-wins conversion so duplicate caller labels cannot override system metadata. Cover physical label collisions and persistent logical-container reuse.

Co-authored-by: Copilot App <[email protected]>
Dispatch lifecycle events in per-resource FIFO order and replace request event backlogs with coalesced latest-state notifications. Share a per-resource RW lock across snapshot processing and lifecycle callbacks so deletion cannot overtake requests processing the previous state, while allowing concurrent readers.

Cover latest-state consumption, both deletion/registration orderings, concurrent requests, cross-resource progress, scheduling fairness, and disposal. Preserve existing streamer and finite-copy behavior.

Co-authored-by: Copilot App <[email protected]>
Acquire pull leases once per operation attempt instead of waiting inside the bounded worker queue. Keep direct pulls and build-base acquisition pending on contention and retry through normal reconciliation without consuming pull retries.

Allow WithResourceLease to forward existing acquisition options so single-attempt calls retain exclusivity and automatic release. Cover same-process contention, unrelated work progress, and recovery after lease release.

Co-authored-by: Copilot App <[email protected]>
Sort mounts by target, ports by protocol and host port, copied files by destination, and build secrets by ID before hashing the copied configuration. Preserve equal-key declaration order and caller-provided digest behavior.

Cover reordering equivalence, meaningful ordering, input immutability, and persistent runtime reuse after port reordering. Leave acquisition-policy inclusion unchanged.

Co-authored-by: Copilot App <[email protected]>
Match V1 by omitting network attachments and aliases from the copied configuration used for hashing. Preserve the declared spec and avoid making dynamic connection changes trigger persistent container replacement.

Cover membership, ordering, aliases, empty inputs, and immutability; update the intentional V2 golden key and resource plan.

Co-authored-by: Copilot App <[email protected]>
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]>
@danegsta
David Negstad (danegsta) enabled stacked auto-merge (squash) October 30, 2026 19:43
Preserve backing identity assertions in the retained regression and scan system logs for the expected physical failure instead of assuming it is the first line.

Co-authored-by: Copilot App <[email protected]>
@danegsta
David Negstad (danegsta) merged commit 5901d3d into main Oct 30, 2026
15 of 18 checks passed
@danegsta
David Negstad (danegsta) deleted the danegsta-v2-resource-plan branch October 30, 2026 22:16
@danegsta

Copy link
Copy Markdown
Member Author

/backport to release/0.27

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

David Negstad (@danegsta) backporting to release/0.27 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch

Applying: Add V2 logical container resource foundation
Applying: Replace synthetic V2 controller tests with behavioral coverage
Applying: Preserve lifecycle duplicate precedence and honor namespace workload IDs
Applying: Import Aspire regression scaffold compatibility fix from #292
Using index info to reconstruct a base tree...
M	test/aspire/apphost-body.cs
M	test/aspire/run-regression.sh
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.
Applying: Release logical container realization inputs after physical handoff
Applying: Capture logical and physical container system diagnostics
Applying: Expose namespaced V2 container log endpoints
Using index info to reconstruct a base tree...
M	api/v1/log_storage.go
M	internal/apiserver/apiserver.go
M	test/integration/v2_logical_container_controller_test.go
Falling back to patching base and 3-way merge...
Auto-merging api/v1/log_storage.go
CONFLICT (content): Merge conflict in api/v1/log_storage.go
Auto-merging internal/apiserver/apiserver.go
Auto-merging test/integration/v2_logical_container_controller_test.go
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0007 Expose namespaced V2 container log endpoints
Error: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

David Negstad (danegsta) added a commit that referenced this pull request Oct 30, 2026
* Add V2 logical container resource foundation

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.



* Replace synthetic V2 controller tests with behavioral coverage

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.



* Preserve lifecycle duplicate precedence and honor namespace workload IDs

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.



* Import Aspire regression scaffold compatibility fix from #292

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.



* Release logical container realization inputs after physical handoff

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.



* Capture logical and physical container system diagnostics

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.



* Expose namespaced V2 container log endpoints

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.



* Drive namespace cleanup directly from relational metadata

Replace per-kind cleanup handlers with one uncached list and bounded delete executor, preserving dependency ordering and pending-resource diagnostics.



* Keep V2 container log subresources with their parent types

Declare logical and physical container log subresources alongside their parents, retaining only resource-neutral storage construction and contracts in shared log types.



* Use container-specific filenames for V2 log streaming



* Expose V2 image acquisition logs through shared capture sources

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.



* Rename shared V2 logging package for resource consumers



* Complete logical container log sources when physical backing disappears

Preserve the original physical source identity in a completed, unavailable descriptor so logical-only followers finish through the existing lifecycle callbacks. Cover physical deletion through an isolated real API server with no physical log request.



* Unify resource log capture filename generation

Use one filename contract for command and runtime captures, preserve V1 startup filenames and runtime capture suffixes, and capture physical image output with ordinary stdout/stderr source names.



* Complete missing-runtime log sources and focus regression coverage

Finish physical and logical followers after confirmed runtime disappearance, wait for image log-writer release in its assertion, and remove unnecessary simulated image aliases. Cover failed pull diagnostics and stream closure at the production Docker/Podman adapter boundary.



* Protect logical backing lifetimes and settle image inspections

Hold owned physical containers and inline images until logical cleanup permits release. Preserve operation outcomes through status conflicts, clean up dependency-pending startup, and verify uncertain backing creates immediately.

Limit logical startup output to owned images, bound image inspection retries, and align reconciliation and integration tests with repository patterns.



* Align physical resource reconciliation and namespace guards

Move physical resource initialization, state updates, and status projection into management and deletion handlers. Discard completed container and image data alongside finalizer removal, and release resource logs during cleanup.

Replace namespace state-machine stages with a common V2 namespace guard while preserving operation settlement and logical backing holds.



* Make V2 finalizer sequencing explicit

Use an explicit ensureFinalizer call followed by management only when no finalizer change is needed, matching the network controller's control flow without changing deletion guards.



* Simplify V2 reconciliation and logical backing coordination

Separate granular lifecycle states from outstanding asynchronous work. Discover logical backings by owner metadata, require expected children before handoff, and propagate deletion to every owned child.

Preserve cleanup status before releasing finalizers, keep adopted runtimes out of workload ownership records, and retry post-pull image inspection without repeating acquisition.



* Stop existing replacement targets and settle workloads on identity

Acquire and stop the existing named runtime when stop and replace are requested before physical creation. Settle logical workload registration when the physical runtime ID is reported, without waiting for a settled lifecycle phase.



* Release runtime captures through observed log sources

Use a log-source provider capability for primary capture identity and release the observed source UID on deletion, including logical-only log consumers. Preserve existing startup and completion handling.



* Cover bounded volume removal during namespace deletion

Exercise the real API and running controllers with an in-use volume, verifying the grace period, abandonment status, finalizer release, and completion of namespace deletion using existing test infrastructure.



* Remove unused V1 resource streamer adapter



* Append authoritative DCP runtime labels after caller labels

Remove the first-match setter and rely on last-value-wins conversion so duplicate caller labels cannot override system metadata. Cover physical label collisions and persistent logical-container reuse.



* Synchronize log readiness with resource lifecycle processing

Dispatch lifecycle events in per-resource FIFO order and replace request event backlogs with coalesced latest-state notifications. Share a per-resource RW lock across snapshot processing and lifecycle callbacks so deletion cannot overtake requests processing the previous state, while allowing concurrent readers.

Cover latest-state consumption, both deletion/registration orderings, concurrent requests, cross-resource progress, scheduling fairness, and disposal. Preserve existing streamer and finite-copy behavior.



* Requeue image acquisition when exclusive pull leases are held

Acquire pull leases once per operation attempt instead of waiting inside the bounded worker queue. Keep direct pulls and build-base acquisition pending on contention and retry through normal reconciliation without consuming pull retries.

Allow WithResourceLease to forward existing acquisition options so single-attempt calls retain exclusivity and automatic release. Cover same-process contention, unrelated work progress, and recovery after lease release.



* Align V2 lifecycle-key collection ordering with V1

Sort mounts by target, ports by protocol and host port, copied files by destination, and build secrets by ID before hashing the copied configuration. Preserve equal-key declaration order and caller-provided digest behavior.

Cover reordering equivalence, meaningful ordering, input immutability, and persistent runtime reuse after port reordering. Leave acquisition-policy inclusion unchanged.



* Exclude dynamic networks from V2 container lifecycle keys

Match V1 by omitting network attachments and aliases from the copied configuration used for hashing. Preserve the declared spec and avoid making dynamic connection changes trigger persistent container replacement.

Cover membership, ordering, aliases, empty inputs, and immutability; update the intentional V2 golden key and resource plan.



* Separate namespace readiness checks from controller status policy

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.



* Clarify logical container backing lookup diagnostic

Use the reviewer's suggested message to describe listing the physical containers backing the logical resource.



* Confirm recorded logical backings are absent before deletion completes

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.



* Copy finite stdio logs asynchronously

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.



---------


(cherry picked from commit 5901d3d)

Co-authored-by: Copilot App <[email protected]>
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