Repository navigation
[release/17.0] Add initial WSLc publish/deploy support with explicit capability limits - #22012
Closed
Mitch Denny (mitchdenny) wants to merge 1 commit into
Closed
Mitch Denny (mitchdenny) wants to merge 1 commit into
Mitch Denny (mitchdenny) wants to merge 1 commit into
Conversation
…ts (#21009) ## Description WSLc can run Aspire apps on Windows, but publishing currently has no WSLc runtime implementation. This adds an initial, deliberately limited publishing implementation so supported image operations use the selected runtime and unsupported operations fail clearly instead of falling back or working around WSLc limitations. This PR targets `main` and builds on the runtime detection and doctor support from #21004, now incorporated into `main`. Supported on Windows: local Dockerfile builds without platform selection, image tagging/removal/push, registry login, native JSON image configuration inspection, and single-platform .NET SDK publishing to WSLc's local image store. Auto-discovery retains Docker → Podman → WSLc priority; explicit case-insensitive selection and custom keyed runtimes remain supported. Native SDK local publishing uses `LocalRegistry=Wslc` and requires an SDK containing the WSLc support introduced in [dotnet/sdk#55249](dotnet/sdk#55249). It was verified with the repository-pinned SDK `11.0.100-rc.1.26425.128`; older SDKs without this support report an unsupported registry rather than falling back to another runtime. Aspire does not implement an archive/load bridge. Unsupported: Compose deployment/management, platform-selected Dockerfile builds, Dockerfile archives/OCI format selection, manifest inspection, multi-platform SDK publishing to WSLc's local image store, and container-file layering (which requires a platform-selected Dockerfile build). Multi-platform image loading is tracked by [microsoft/WSL#41123](microsoft/WSL#41123). These paths reject explicitly using existing exception/inspection-result contracts. Daemon-free single- and multi-platform SDK archives remain supported without WSLc health checks or commands; archive publishing omits `LocalRegistry=Wslc`, preserving compatibility with SDKs that do not recognize it. No alternative builder or runtime fallback is introduced. Dockerfile builds in Docker, Podman, and WSLc now use `ProcessSpec.ArgumentList` instead of a manually quoted command line. Shared eager argument helpers preserve quotes, spaces, backslashes, empty values, and inherited environment values, retaining Podman's existing secret behavior. Platform-specific process argument handling remains owned by .NET, without invoking a shell. ### User-facing usage On Windows, select WSLc with `ASPIRE_CONTAINER_RUNTIME=wslc`. Single-platform .NET SDK publishing then uses WSLc's local store through the SDK's native support. Dockerfile publishing defaults to `linux/amd64`; explicitly opt into the WSLc host platform only when appropriate: ```csharp builder.AddDockerfile("program", "./program") .WithContainerBuildOptions(options => options.TargetPlatform = null); ``` For a .NET SDK archive without container-file layering: ```csharp project.WithContainerBuildOptions(options => { options.Destination = ContainerImageDestination.Archive; options.OutputPath = "./images"; }); ``` ### Validation - `.\restore.cmd /p:SkipNativeBuild=true` — passed during initial setup. - `.\.dotnet\dotnet.exe test --project tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj --no-launch-profile /p:SkipNativeBuild=true -- --filter-class '*.WslcContainerRuntimeTests' --filter-class '*.ContainerRuntimeResolverTests' --filter-class '*.ContainerRuntimeDetectorTests' --filter-class '*.DockerContainerRuntimeTests' --filter-class '*.ContainerRuntimeBaseTests' --filter-class '*.DotnetProgramArchiveTests' --filter-class '*.DotnetProgramPublishingTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'` — passed, 151 tests after merging `main`, before the argument-list correction. - `.\.dotnet\dotnet.exe test --project tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj --no-launch-profile /p:SkipNativeBuild=true -- --filter-class '*.ContainerRuntimeBaseTests' --filter-class '*.DockerContainerRuntimeTests' --filter-class '*.PodmanSaveArgumentsTests' --filter-class '*.WslcContainerRuntimeTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'` — passed, 95 tests after the argument-list correction and eager helper changes. The runtime-constant follow-up was rebuilt with `--filter-method '*.BuildImageAsync_PreservesArgumentBoundaries'` (same project and exclusions) — passed, 3 cases. The complete 95-test selection was rerun with `--no-build` immediately before pushing — passed. - `.\.dotnet\dotnet.exe test --project tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj --no-build --no-launch-profile -- --filter-method '*.BuildSecretsFormats*' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'` — passed, 4 tests after the argument-list correction. - `.\.dotnet\dotnet.exe test --project tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj --no-build --no-launch-profile -- --filter-class '*.DotnetProgramArchiveTests' --filter-class '*.DotnetProgramPublishingTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'` — passed, 48 tests after the argument-list correction. - `.\.dotnet\dotnet.exe test --project tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj --no-build --no-launch-profile -- --filter-method '*.BuildImageAsync_Dotnet*' --filter-method '*.BuildImageAsync_ProjectBuildPassesResolvedContainerRuntimeAsLocalRegistry' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'` — passed, 20 tests after the SDK correction and before the `main` merge. - `.\.dotnet\dotnet.exe publish '<probe-directory>\probe.csproj' --configuration Release /t:PublishContainer --property:LocalRegistry=Wslc --property:ContainerRepository=aspire-wslc-sdk-probe-b35fa7a4 --property:ContainerImageTag=single --property:RuntimeIdentifier=linux-x64 --property:ContainerRuntimeIdentifier=linux-x64 --property:ContainerBaseImage=mcr.microsoft.com/dotnet/runtime:10.0 --source https://packagefeedproxy.microsoft.io/nuget/v3/index.json` — passed using a temporary minimal net10.0 console project and SDK `11.0.100-rc.1.26425.128`. SDK reported successful publication via Wslc; `wslc image inspect aspire-wslc-sdk-probe-b35fa7a4:single --format json` confirmed linux/amd64. Probe image and project cleaned up; the path above is a placeholder for that temporary directory. - Installed WSLc 3.0.3.0: verified local Dockerfile build and native `image inspect --format json`; inspected tag/remove/push/login/build help and DCP's WSLc adapter. Direct `--output type=docker` and `--output type=oci` probes both failed with the Docker-driver exporter limitation, confirming the explicit archive boundary. Probe image/files cleaned up. - Local E2E tests were not run; no E2E tests were added. Linux/macOS execution and live registry push/login were not validated locally. - Existing NU1902/NU1903 warnings for `System.Security.Cryptography.Pkcs` 10.0.12 remain; no dependency changes are included. ### Security considerations The selected WSLc executable is trusted in the same way as Docker/Podman. Image commands use the existing process runner; registry passwords remain on stdin and environment build secrets follow the existing runtime pattern. Native image inspection uses source-generated JSON deserialization and preserves the image reference as a single process argument. Dockerfile build invocations for all three runtimes now preserve argument boundaries through `ProcessSpec.ArgumentList`. No listener, elevated execution, archive extraction, or Aspire-managed archive/load bridge is added. A separate security review has not been performed. Fixes # (issue) ## Checklist - Is this feature complete? - [x] Yes. Ready to ship. - [ ] No. Follow-up changes expected. - Are you including unit tests for the changes and scenario tests if relevant? - [x] Yes - [ ] No - Did you add public API? - [ ] Yes - If yes, did you have an API Review for it? - [ ] Yes - [ ] No - Did you add `<remarks />` and `<code />` elements on your triple slash comments? - [ ] Yes - [ ] No - [x] No - Does the change make any security assumptions or guarantees? - [ ] Yes - If yes, have you done a threat model and had a security review? - [ ] Yes - [x] No - [x] No --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f85e4b06-371e-465a-8fd8-e635d14ec41f Copilot-Session: b35fa7a4-1433-4b70-9840-5f5866230ff4 (cherry picked from commit 64ba1eb)
14 tasks
This comment has been minimized.
This comment has been minimized.
Mitch Denny (mitchdenny)
marked this pull request as ready for review
November 10, 2026 04:31
Member
Author
|
Approved for inclusion in release/17.0. Do not merge yet. |
Mitch Denny (mitchdenny)
force-pushed
the
mitchdenny-backport-17-0-15-pr21009
branch
from
November 10, 2026 05:35
4a63560 to
e40acf1
Compare
Contributor
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 22012Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 22012" |
This comment has been minimized.
This comment has been minimized.
Mitch Denny (mitchdenny)
force-pushed
the
mitchdenny-backport-17-0-15-pr21009
branch
2 times, most recently
from
November 10, 2026 07:19
4a63560 to
e40acf1
Compare
Contributor
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Mitch Denny (mitchdenny)
changed the base branch from
mitchdenny-backport-17-0-14-pr21845
to
mitchdenny-backport-17-0-12-pr21565
November 10, 2026 08:18
Contributor
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Mitch Denny (mitchdenny)
force-pushed
the
mitchdenny-backport-17-0-15-pr21009
branch
from
November 10, 2026 09:10
e40acf1 to
4a63560
Compare
Mitch Denny (mitchdenny)
changed the base branch from
mitchdenny-backport-17-0-12-pr21565
to
mitchdenny-backport-17-0-14-pr21845
November 10, 2026 10:33
Contributor
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Contributor
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
David Negstad (danegsta)
approved these changes
Nov 10, 2026
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.
Description
Backport of #21009 to
release/17.0(cherry-picked from 64ba1eb with no modifications). Layer 15 of 55 in the release/17.0 backport stack; stacked on #22011.Backport recommendation: Owner call — WSLc publish is a feature, but the author requested a backport (#21991).
Backport of #21009
Checklist
<remarks />and<code />elements on your triple slash comments?