Skip to content

Update volume APIs to match docker arguments#40181

Open
kvega005 wants to merge 8 commits intomicrosoft:feature/wsl-for-appsfrom
kvega005:volumeManagement
Open

Update volume APIs to match docker arguments#40181
kvega005 wants to merge 8 commits intomicrosoft:feature/wsl-for-appsfrom
kvega005:volumeManagement

Conversation

@kvega005
Copy link
Copy Markdown

Summary of the Pull Request

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

Validation Steps Performed

Copilot AI review requested due to automatic review settings April 14, 2026 22:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@kvega005 kvega005 requested a review from Copilot April 15, 2026 01:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.

@kvega005 kvega005 marked this pull request as ready for review April 15, 2026 01:46
@kvega005 kvega005 requested a review from a team as a code owner April 15, 2026 01:46
Copy link
Copy Markdown
Collaborator

@OneBlue OneBlue left a comment

Choose a reason for hiding this comment

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

Change looks great! Couple minor comments

Copilot AI review requested due to automatic review settings April 15, 2026 06:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.

Comment on lines +31 to +34
const std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned short> random;

WSLCVhdVolumeMetadata vhdMetadata{};
vhdMetadata.V1 = WSLCVhdVolumeMetadataV1{HostPath.wstring(), SizeBytes};
metadata.VhdVolumeMetadata = std::move(vhdMetadata);
std::array<unsigned short, 32> randomBytes;
std::generate(randomBytes.begin(), randomBytes.end(), random);
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

GenerateName() has a build-breaking issue and also produces weak/possibly-colliding names: (1) the RNG is declared const but operator() on standard engines is non-const, so std::generate(..., random) will not compile; (2) default_random_engine default construction is deterministic, so anonymous names can repeat across process runs, potentially tripping WI_VERIFY(inserted) or Docker “already exists”; (3) generating unsigned short then casting to BYTE discards half the generated bits. Make the engine non-const, seed it with real entropy (e.g., std::random_device or platform RNG), and generate bytes directly (e.g., uint8_t array / engine result type) before hex encoding.

Copilot uses AI. Check for mistakes.
name.reserve(randomBytes.size() * 2);
for (auto b : randomBytes)
{
std::format_to(std::back_inserter(name), "{:02x}", static_cast<BYTE>(b));
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

GenerateName() has a build-breaking issue and also produces weak/possibly-colliding names: (1) the RNG is declared const but operator() on standard engines is non-const, so std::generate(..., random) will not compile; (2) default_random_engine default construction is deterministic, so anonymous names can repeat across process runs, potentially tripping WI_VERIFY(inserted) or Docker “already exists”; (3) generating unsigned short then casting to BYTE discards half the generated bits. Make the engine non-const, seed it with real entropy (e.g., std::random_device or platform RNG), and generate bytes directly (e.g., uint8_t array / engine result type) before hex encoding.

Copilot uses AI. Check for mistakes.
THROW_HR_WITH_USER_ERROR_IF(E_INVALIDARG, Localization::MessageWslcMissingVolumeOption("SizeBytes"), it == DriverOpts.end());

auto& value = it->second;
THROW_HR_WITH_USER_ERROR_IF(E_INVALIDARG, Localization::MessageInvalidSize(value), value[0] == '-');
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

ParseSizeBytes() indexes value[0] without guarding against an empty string, which is undefined behavior and can crash if the caller passes SizeBytes= (empty value). Handle value.empty() as invalid size before checking value[0].

Suggested change
THROW_HR_WITH_USER_ERROR_IF(E_INVALIDARG, Localization::MessageInvalidSize(value), value[0] == '-');
THROW_HR_WITH_USER_ERROR_IF(E_INVALIDARG, Localization::MessageInvalidSize(value), value.empty() || value[0] == '-');

Copilot uses AI. Check for mistakes.
Comment on lines +124 to +126
metadata.Properties = {
{"HostPath", hostPath.string()},
};
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

Persisting HostPath via hostPath.string() can be lossy/non-portable on Windows when paths contain non-ASCII characters because it uses the active narrow encoding. Since this value is serialized into JSON stored in a Docker label (effectively UTF-8), prefer an explicit UTF-8 representation (or store wide + convert consistently) to avoid recovery failures in Open() for internationalized paths.

Copilot uses AI. Check for mistakes.
};

// Missing SizeBytes.
validateInvalidOptionsFailure(nullptr, 0, E_INVALIDARG, L"Missing required option: 'SizeBytes'");
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

These two cases pass identical inputs (nullptr, 0) but assert different expectations (one validates a specific error message, the other does not). This makes the intent ambiguous and can mask regressions in the message behavior. Either remove the redundant “No driver opts at all” case, or make “Missing SizeBytes” pass a non-empty set of other driver opts (e.g., an unrelated key) so it specifically tests “missing required option” when options are otherwise present.

Suggested change
validateInvalidOptionsFailure(nullptr, 0, E_INVALIDARG, L"Missing required option: 'SizeBytes'");
WSLCDriverOption missingSizeBytes[] = {{"UnrelatedOption", "value"}};
validateInvalidOptionsFailure(
missingSizeBytes, ARRAYSIZE(missingSizeBytes), E_INVALIDARG, L"Missing required option: 'SizeBytes'");

Copilot uses AI. Check for mistakes.
Comment on lines +3395 to +3397

// No driver opts at all.
validateInvalidOptionsFailure(nullptr, 0, E_INVALIDARG);
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

These two cases pass identical inputs (nullptr, 0) but assert different expectations (one validates a specific error message, the other does not). This makes the intent ambiguous and can mask regressions in the message behavior. Either remove the redundant “No driver opts at all” case, or make “Missing SizeBytes” pass a non-empty set of other driver opts (e.g., an unrelated key) so it specifically tests “missing required option” when options are otherwise present.

Suggested change
// No driver opts at all.
validateInvalidOptionsFailure(nullptr, 0, E_INVALIDARG);

Copilot uses AI. Check for mistakes.

if (reservedKey != nullptr)
{
THROW_HR_IF_MSG(E_INVALIDARG, strcmp(pairs[i].Key, reservedKey) == 0, "Key '%hs' is reserved", reservedKey);
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

The reserved-key failure message prints reservedKey rather than the offending provided key, which makes debugging harder (especially if multiple reserved keys exist in the future). Consider including pairs[i].Key in the message (and/or mentioning both the provided and reserved keys).

Suggested change
THROW_HR_IF_MSG(E_INVALIDARG, strcmp(pairs[i].Key, reservedKey) == 0, "Key '%hs' is reserved", reservedKey);
THROW_HR_IF_MSG(E_INVALIDARG, strcmp(pairs[i].Key, reservedKey) == 0, "Key '%hs' is reserved (matches reserved key '%hs')", pairs[i].Key, reservedKey);

Copilot uses AI. Check for mistakes.
Comment on lines +1922 to +1927
HRESULT WSLCSession::PruneVolumes(const WSLCPruneVolumesOptions* /*Options*/, WSLCPruneVolumesResults* /*Results*/)
{
// TODO: Implement volume pruning. Docker's volume prune API skips bind-mount volumes,
// so WSLC VHD volumes require custom handling.
return E_NOTIMPL;
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

PruneVolumes is now exposed in the public COM interface but always returns E_NOTIMPL. If clients start calling it (especially via the SDK), this becomes a persistent API surface that appears supported but isn’t. Consider either implementing a minimal, well-defined subset (even if limited to anonymous volumes) or omitting the method from the IDL until it’s ready to ship.

Suggested change
HRESULT WSLCSession::PruneVolumes(const WSLCPruneVolumesOptions* /*Options*/, WSLCPruneVolumesResults* /*Results*/)
{
// TODO: Implement volume pruning. Docker's volume prune API skips bind-mount volumes,
// so WSLC VHD volumes require custom handling.
return E_NOTIMPL;
}
HRESULT WSLCSession::PruneVolumes(const WSLCPruneVolumesOptions* /*Options*/, WSLCPruneVolumesResults* Results)
try
{
COMServiceExecutionContext context;
RETURN_HR_IF_NULL(E_POINTER, Results);
// Minimal supported behavior: report a successful prune operation that
// removed nothing. This avoids exposing a public COM method that always
// fails with E_NOTIMPL while preserving current volume behavior until
// selective pruning semantics are implemented.
*Results = {};
auto lock = m_lock.lock_shared();
std::lock_guard volumesLock(m_volumesLock);
return S_OK;
}
CATCH_RETURN();

Copilot uses AI. Check for mistakes.
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