Skip to content

Add --iidfile to wslc image build - #41212

Draft
ggarzia-MSFT wants to merge 14 commits into
masterfrom
user/ggarzia/build-iidfile
Draft

Add --iidfile to wslc image build#41212
ggarzia-MSFT wants to merge 14 commits into
masterfrom
user/ggarzia/build-iidfile

Conversation

@ggarzia-MSFT

@ggarzia-MSFT ggarzia-MSFT commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary of the Pull Request

Adds a --iidfile <path> option to wslc build, mirroring docker 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

  • Closes: Link to issue #xxx
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

  • CLI argument: New iidfile value argument registered in ArgumentDefinitions.h and wired into the build command. Its description string (WSLCCLI_IidFileArgDescription) is added to Resources.resw for localization.
  • RAII helper (IidFile): New ImageModel.{h,cpp} introduces a models::IidFile class that:
    • Opens the file with CREATE_ALWAYS at construction so an invalid path surfaces an error before the build starts (matching docker build), throwing a localized user error on failure.
    • Writes the image ID on Commit().
    • Deletes the file on destruction if Commit() was never called, so a failed/cancelled build leaves no file behind.
    • Is NON_COPYABLE / NON_MOVABLE.
  • Service/session plumbing: ImageService::Build now returns the image ID string. A new WSLCBuildImageFlagsReturnImageId flag is set only when --iidfile is supplied, and the server (WSLCSession) returns the image ID via a new out-parameter on BuildImage (IDL updated in wslc.idl / WSLCShared.idl). ImageTasks.cpp orchestrates: create the IidFile, run the build, then Commit() the returned ID.

Validation Steps Performed

  • Unit tests: Updated test/windows/WSLCTests.cpp for the new flag/out-parameter and image-ID return path.
  • E2E tests: Added coverage in test/windows/wslc/e2e/WSLCE2EImageBuildTests.cpp exercising wslc build --iidfile, verifying the file contains the built image ID and that a failed build does not leave the file behind.
  • Manual: Ran 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.

ggarzia-MSFT and others added 13 commits July 28, 2026 17:32
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>
Copilot AI review requested due to automatic review settings July 30, 2026 21:17

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.

🟡 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 --iidfile support by returning the built image ID from the session BuildImage COM call and committing it to a host file via an RAII helper.
  • Add docker-buildx-style --output spec 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.

Comment thread src/windows/wslc/tasks/ImageTasks.cpp Outdated
Comment thread src/windows/wslc/services/ImageModel.cpp
Comment thread src/windows/wslcsession/WSLCSession.h Outdated
Comment thread src/windows/wslcsession/WSLCSession.cpp Outdated
…ageId out-param

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 30, 2026 21:29
@ggarzia-MSFT ggarzia-MSFT changed the title User/ggarzia/build iidfile Add --iidfile to wslc image build Jul 30, 2026

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.

🟢 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.

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.

2 participants