Add --iidfile to wslc image build - #41212
Conversation
Adds WSLCCLIOutputParserUnitTests covering docker-style --output specs (validation::ParseOutputSpec) for wslc image build: shorthand, all exporter types (local, tar, oci, docker, image, registry, cacheonly), every documented attribute, and invalid combinations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a docker-buildx-style --output flag to wslc image build. The client parses and validates the spec (type/dest/attributes, shorthand, exporter-specific destination/name requirements), normalizes it to a canonical form, and forwards it to buildx via the existing WSLCBuildImageOptions plumbing. - ParseOutputSpec: docker-parity parser with case-insensitive keys, empty-field rejection, and validation of the supported exporter types. - FormatOutputSpec: re-serializes the parsed BuildOutput into a canonical spec. - Wire the parsed/normalized output through ImageTasks -> ImageService -> WSLCSession's docker build argv. - Add MessageWslcOutputInvalidSpec localization string. - Extend WSLCCLIOutputParserUnitTests with round-trip Format tests (39 total). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add end-to-end coverage for the --output flag on 'wslc image build': - Tier 1: unsupported --output type is rejected before reaching buildx. - Tier 2: type=docker loads the built image into the engine store; the image is tagged via -t and verified host-side through image inspect (RepoTags and Config.Cmd). The default docker builder does not honor the exporter name= attribute for tagging, so the tests tag with -t. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The tar exporter's stdout stream ('dest=-', and the bare '-' shorthand) is
not supported, so reject it during output spec parsing and require a file
path via 'dest='. Update the affected parser unit tests accordingly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nd console stdout - Parser: mirror docker for --output dest=- (stdout). Allow tar/oci/docker, reject local (dest cannot be stdout for local exporter); '-' shorthand -> type=tar,dest=-. - Client ImageService::Build: route dest=- to stdout with a console guard mirroring docker's 'refusing to write to console'. - Service streams exporter output to the client handle. - TEMP: diagnostic in BuildImage to inspect VM-side exporter output (empty tarball repro). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The empty-tarball issue was a stale deployed wslcsession.exe; streaming works end-to-end after redeploy. Remove the temporary VM-side exporter diagnostic block that was added for debugging. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add passing and failing E2E coverage for the --output exporter types (tar, local, image, cacheonly, docker, registry), plus a ListTarEntries helper. oci and docker-to-file are omitted as they require the containerd image store, which the VM's docker driver does not enable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tay under virtiofs share cap Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…se output attr keys, fix drive-root tar dest, log cleanup failures, harden temp file, resw Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Not ready to approve
The current iidfile commit path can leave an empty iidfile on successful builds that produce no image ID, and the COM BuildImage ImageId parameter contract is inconsistent (optional vs required) in a way that can trigger RPC null-pointer failures.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR extends wslc build with Docker parity features by introducing --iidfile <path> (write the resulting image ID to a host file) and wiring up docker-buildx-style --output handling, including client/server plumbing and test coverage.
Changes:
- Add
--iidfilesupport by returning the built image ID from the sessionBuildImageCOM call and committing it to a host file via an RAII helper. - Add docker-buildx-style
--outputspec parsing/normalization and streaming of exporter artifacts back to the client when needed. - Add/extend unit + E2E tests and localization strings for the new CLI surface and validation errors.
File summaries
| File | Description |
|---|---|
| test/windows/WSLCTests.cpp | Updates COM BuildImage calls to pass the new ImageId out-parameter and adjusts invalid-flag testing. |
| test/windows/wslc/WSLCCLISecretParserUnitTests.cpp | Hardens temp-file creation/writes with explicit failure checks. |
| test/windows/wslc/WSLCCLIOutputParserUnitTests.cpp | Adds unit tests defining the contract for --output spec parsing/formatting. |
| test/windows/wslc/e2e/WSLCE2EImageBuildTests.cpp | Adds E2E coverage for --output exporters and --iidfile success/failure behavior. |
| src/windows/wslcsession/WSLCSession.h | Extends IWSLCSession::BuildImage signature with an ImageId out-parameter. |
| src/windows/wslcsession/WSLCSession.cpp | Implements returning an image ID via VM --iidfile and streams exporter output back via a handle. |
| src/windows/wslc/tasks/ImageTasks.cpp | Wires --output and --iidfile into the build task; commits iidfile after build. |
| src/windows/wslc/services/ImageService.h | Adds BuildOutput model and changes Build() to return image ID; threads output routing inputs. |
| src/windows/wslc/services/ImageService.cpp | Implements output routing/streaming and extracts the image ID from the session build call. |
| src/windows/wslc/services/ImageModel.h | Introduces the models::IidFile RAII helper API. |
| src/windows/wslc/services/ImageModel.cpp | Implements IidFile create/truncate, commit, and delete-on-failure semantics. |
| src/windows/wslc/commands/ImageBuildCommand.cpp | Registers new --iidfile and --output CLI arguments for the build command. |
| src/windows/wslc/arguments/SpecParsing.h | Declares ParseOutputSpec/FormatOutputSpec for docker-style --output. |
| src/windows/wslc/arguments/SpecParsing.cpp | Implements --output spec parsing, validation, and canonical formatting. |
| src/windows/wslc/arguments/ArgumentDefinitions.h | Adds the iidfile argument definition. |
| src/windows/service/inc/WSLCShared.idl | Adds build flags for output-directory streaming and returning image ID; updates valid mask. |
| src/windows/service/inc/wslc.idl | Extends WSLCBuildImageOptions with output fields and adds ImageId out-param to BuildImage. |
| localization/strings/en-US/Resources.resw | Adds localized strings for --output validation and --iidfile/--output arg descriptions. |
Review details
- Files reviewed: 18/18 changed files
- Comments generated: 4
- Review effort level: Low
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
…ageId out-param Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Ready to approve
The implementation is coherent and well-covered by updated unit/E2E tests, with only minor documentation/comment consistency nits noted.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
Comments suppressed due to low confidence (2)
test/windows/wslc/WSLCCLIOutputParserUnitTests.cpp:35
- The top-of-file contract comment says non-structural --output attributes are “stored verbatim”, but ParseOutputSpec lowercases attribute keys (and FormatOutputSpec re-serializes the normalized keys). This doc mismatch can mislead future readers/tests about the intended behavior.
* Otherwise the spec is a comma separated list of key=value pairs. Keys are matched
case-insensitively. 'type' and 'dest' populate the struct fields; every other key is
stored verbatim in Attributes (values may themselves contain '=').
src/windows/wslc/services/ImageService.h:45
- BuildOutput’s comment states attributes are “carried verbatim”, but ParseOutputSpec normalizes attribute keys to lowercase (and FormatOutputSpec emits the normalized keys). Updating this comment to reflect the actual behavior will keep API expectations consistent.
// Parsed docker-style --output spec (buildx exporter). Type/Dest are the resolved exporter type and
// destination; any remaining key=value attributes (name, push, compression, ...) are carried verbatim.
struct BuildOutput
{
std::wstring Type; // resolved exporter type (e.g. L"local", L"tar", ...)
std::wstring Dest; // destination path; L"-" means stdout; empty when not applicable
std::map<std::wstring, std::wstring> Attributes; // remaining key=value attributes
};
- Files reviewed: 18/18 changed files
- Comments generated: 0 new
- Review effort level: Low
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
Summary of the Pull Request
Adds a
--iidfile <path>option towslc build, mirroringdocker build --iidfile. After a successful build, the resulting image ID is written to the given file. The file is created/truncated up front (so a bad path fails fast before the long build runs) and is removed if the build fails, so a failed build never leaves a stale file behind.PR Checklist
Detailed Description of the Pull Request / Additional comments
iidfilevalue argument registered inArgumentDefinitions.hand wired into the build command. Its description string (WSLCCLI_IidFileArgDescription) is added toResources.reswfor localization.IidFile): NewImageModel.{h,cpp}introduces amodels::IidFileclass that:CREATE_ALWAYSat construction so an invalid path surfaces an error before the build starts (matchingdocker build), throwing a localized user error on failure.Commit().Commit()was never called, so a failed/cancelled build leaves no file behind.NON_COPYABLE/NON_MOVABLE.ImageService::Buildnow returns the image ID string. A newWSLCBuildImageFlagsReturnImageIdflag is set only when--iidfileis supplied, and the server (WSLCSession) returns the image ID via a new out-parameter onBuildImage(IDL updated inwslc.idl/WSLCShared.idl).ImageTasks.cpporchestrates: create theIidFile, run the build, thenCommit()the returned ID.Validation Steps Performed
test/windows/WSLCTests.cppfor the new flag/out-parameter and image-ID return path.test/windows/wslc/e2e/WSLCE2EImageBuildTests.cppexercisingwslc build --iidfile, verifying the file contains the built image ID and that a failed build does not leave the file behind.wslc build --iidfile <path>and confirmed the image ID is written to the file; verified an invalid path fails before the build runs and a failed build leaves no file.