@samitouri / QOSAMI-WSL / commits / 58ad906d

CLI: Add multiple image support to image delete (#40686)

David Bennett committed Jun 2, 2026 at 15:19 UTC 58ad906d00997e10e827f8bfaa4832a236bcc053
4 files changed +24 -7
src/windows/wslc/commands/ImageRemoveCommand.cpp
+2 -2
@@ -28,7 +28,7 @@ namespace wsl::windows::wslc {
28 std::vector<Argument> ImageRemoveCommand::GetArguments() const
29 {
30 return {
31 - Argument::Create(ArgType::ImageId, true),
31 + Argument::Create(ArgType::ImageId, true, NO_LIMIT),
32 Argument::Create(ArgType::ImageForce),
33 Argument::Create(ArgType::NoPrune),
34 Argument::Create(ArgType::Session),
@@ -51,4 +51,4 @@ void ImageRemoveCommand::ExecuteInternal(CLIExecutionContext& context) const
51 << CreateSession //
52 << DeleteImage;
53 }
54 -} // namespace wsl::windows::wslc
\ No newline at end of file
54 +} // namespace wsl::windows::wslc
src/windows/wslc/tasks/ImageTasks.cpp
+5 -4
@@ -200,13 +200,14 @@ void PushImage(CLIExecutionContext& context)
200 void DeleteImage(CLIExecutionContext& context)
201 {
202 WI_ASSERT(context.Data.Contains(Data::Session));
203 - WI_ASSERT(context.Args.Contains(ArgType::ImageId));
203 auto& session = context.Data.Get<Data::Session>();
205 - auto& imageId = context.Args.Get<ArgType::ImageId>();
206 -
204 + const auto& imageIds = context.Args.GetAll<ArgType::ImageId>();
205 bool force = context.Args.Contains(ArgType::ImageForce);
206 bool noPrune = context.Args.Contains(ArgType::NoPrune);
209 - services::ImageService::Delete(session, WideToMultiByte(imageId), force, noPrune);
207 + for (const auto& id : imageIds)
208 + {
209 + services::ImageService::Delete(session, WideToMultiByte(id), force, noPrune);
210 + }
211 }
212
213 void LoadImage(CLIExecutionContext& context)
test/windows/wslc/CommandLineTestCases.h
+2
@@ -214,6 +214,8 @@ COMMAND_LINE_TEST_CASE(L"image list --verbose", L"list", true)
214 COMMAND_LINE_TEST_CASE(L"image list -q", L"list", true)
215 COMMAND_LINE_TEST_CASE(L"image pull ubuntu", L"pull", true)
216 COMMAND_LINE_TEST_CASE(L"pull ubuntu", L"pull", true)
217 +COMMAND_LINE_TEST_CASE(L"image rm cont1 --force --no-prune", L"remove", true)
218 +COMMAND_LINE_TEST_CASE(L"image rm cont1 cont2 cont3 --force --no-prune", L"remove", true)
219
220 // Version command tests
221 COMMAND_LINE_TEST_CASE(L"version", L"version", true)
test/windows/wslc/e2e/WSLCE2EImageDeleteTests.cpp
+15 -1
@@ -27,6 +27,7 @@ class WSLCE2EImageDeleteTests
27 {
28 EnsureContainerDoesNotExist(WslcContainerName);
29 EnsureImageIsDeleted(DebianImage);
30 + EnsureImageIsDeleted(AlpineImage);
31 return true;
32 }
33
@@ -34,6 +35,7 @@ class WSLCE2EImageDeleteTests
35 {
36 EnsureContainerDoesNotExist(WslcContainerName);
37 EnsureImageIsDeleted(DebianImage);
38 + EnsureImageIsDeleted(AlpineImage);
39 return true;
40 }
41
@@ -65,6 +67,17 @@ class WSLCE2EImageDeleteTests
67 result.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
68 }
69
70 + WSLC_TEST_METHOD(WSLCE2E_Image_Delete_MultipleUnusedImages_Success)
71 + {
72 + EnsureImageIsLoaded(DebianImage);
73 + EnsureImageIsLoaded(AlpineImage);
74 + VerifyImageIsNotUsed(DebianImage);
75 + VerifyImageIsNotUsed(AlpineImage);
76 +
77 + auto result = RunWslc(std::format(L"image delete {} {}", DebianImage.Name, AlpineImage.Name));
78 + result.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
79 + }
80 +
81 WSLC_TEST_METHOD(WSLCE2E_Image_Delete_UsedImage_Failure)
82 {
83 EnsureImageIsLoaded(DebianImage);
@@ -113,6 +126,7 @@ class WSLCE2EImageDeleteTests
126 private:
127 const std::wstring WslcContainerName = L"wslc-test-container";
128 const TestImage& DebianImage = DebianTestImage();
129 + const TestImage& AlpineImage = AlpineTestImage();
130 const TestImage& InvalidImage = InvalidTestImage();
131
132 std::wstring GetHelpMessage() const
@@ -163,4 +177,4 @@ private:
177 return options.str();
178 }
179 };
166 -} // namespace WSLCE2ETests
\ No newline at end of file
180 +} // namespace WSLCE2ETests