@samitouri / QOSAMI-WSL / commits / e6db5668

CLI: Route wslc warnings through Reporter (#41111)

David Bennett committed Jul 17, 2026 at 21:32 UTC e6db5668edaa949df11ab4d8e66243b53c92c73d
15 files changed +80 -58
src/windows/wslc/services/ContainerService.cpp
+12 -12
@@ -41,9 +41,10 @@ static void SetContainerArguments(WSLCProcessOptions& options, std::vector<const
41 options.CommandLine = {.Values = argsStorage.data(), .Count = static_cast<ULONG>(argsStorage.size())};
42 }
43
44 -static wsl::windows::common::RunningWSLCContainer CreateInternal(
45 - Reporter& reporter, Session& session, const std::string& image, const ContainerOptions& options, IWarningCallback* warningCallback = nullptr)
44 +static wsl::windows::common::RunningWSLCContainer CreateInternal(Reporter& reporter, Session& session, const std::string& image, const ContainerOptions& options)
45 {
46 + WarningCallback warningCallback(reporter);
47 +
48 auto processFlags = WSLCProcessFlagsNone;
49 WI_SetFlagIf(processFlags, WSLCProcessFlagsStdin, options.Interactive);
50 WI_SetFlagIf(processFlags, WSLCProcessFlagsTty, options.TTY);
@@ -243,7 +244,7 @@ static wsl::windows::common::RunningWSLCContainer CreateInternal(
244 containerLauncher.AddLabel(key, value);
245 }
246
246 - auto [result, runningContainer] = containerLauncher.CreateNoThrow(*session.Get(), warningCallback);
247 + auto [result, runningContainer] = containerLauncher.CreateNoThrow(*session.Get(), &warningCallback);
248 if (result == WSLC_E_IMAGE_NOT_FOUND)
249 {
250 {
@@ -252,9 +253,9 @@ static wsl::windows::common::RunningWSLCContainer CreateInternal(
253 ImageProgressCallback callback(reporter, Reporter::Level::Info);
254 reporter.Info(L"{}\n", Localization::WSLCCLI_ImageNotFoundPulling(wsl::shared::string::MultiByteToWide(image)));
255 ImageService imageService;
255 - imageService.Pull(session, image, &callback);
256 + imageService.Pull(reporter, session, image, &callback);
257 }
257 - return containerLauncher.Create(*session.Get(), warningCallback);
258 + return containerLauncher.Create(*session.Get(), &warningCallback);
259 }
260
261 THROW_IF_FAILED(result);
@@ -431,10 +432,9 @@ int ContainerService::Run(Reporter& reporter, Session& session, const std::strin
432 // container isn't created when the caller-requested path can't be written. The file is
433 // removed automatically if we don't reach Commit() below.
434 CidFile cidFile(runOptions.CidFile);
434 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
435
436 // Create the container
437 - auto runningContainer = CreateInternal(reporter, session, image, runOptions, warningCallback.Get());
437 + auto runningContainer = CreateInternal(reporter, session, image, runOptions);
438 auto& container = runningContainer.Get();
439
440 WSLCContainerId containerId{};
@@ -456,7 +456,8 @@ int ContainerService::Run(Reporter& reporter, Session& session, const std::strin
456 startOptions.TtyColumns = size.X;
457 }
458
459 - THROW_IF_FAILED(container.Start(startFlags, &startOptions, warningCallback.Get())); // TODO: detach keys
459 + WarningCallback warningCallback(reporter);
460 + THROW_IF_FAILED(container.Start(startFlags, &startOptions, &warningCallback)); // TODO: detach keys
461
462 // Disable auto-delete only after successful start
463 runningContainer.SetDeleteOnClose(false);
@@ -475,8 +476,7 @@ int ContainerService::Run(Reporter& reporter, Session& session, const std::strin
476 CreateContainerResult ContainerService::Create(Reporter& reporter, Session& session, const std::string& image, ContainerOptions runOptions)
477 {
478 CidFile cidFile(runOptions.CidFile);
478 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
479 - auto runningContainer = CreateInternal(reporter, session, image, runOptions, warningCallback.Get());
479 + auto runningContainer = CreateInternal(reporter, session, image, runOptions);
480 runningContainer.SetDeleteOnClose(false);
481 auto& container = runningContainer.Get();
482 WSLCContainerId id{};
@@ -490,7 +490,6 @@ int ContainerService::Start(Reporter& reporter, Session& session, const std::str
490 wil::com_ptr<IWSLCContainer> container;
491 THROW_IF_FAILED(session.Get()->OpenContainer(id.c_str(), &container));
492 WSLCContainerStartFlags flags = attach ? WSLCContainerStartFlagsAttach : WSLCContainerStartFlagsNone;
493 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
493
494 wsl::windows::common::ConsoleState console;
495 WSLCProcessStartOptions startOptions{};
@@ -498,7 +497,8 @@ int ContainerService::Start(Reporter& reporter, Session& session, const std::str
497 startOptions.TtyRows = size.Y;
498 startOptions.TtyColumns = size.X;
499
501 - THROW_IF_FAILED_EXCEPT(container->Start(flags, &startOptions, warningCallback.Get()), WSLC_E_CONTAINER_IS_RUNNING);
500 + WarningCallback warningCallback(reporter);
501 + THROW_IF_FAILED_EXCEPT(container->Start(flags, &startOptions, &warningCallback), WSLC_E_CONTAINER_IS_RUNNING);
502
503 if (!attach)
504 {
src/windows/wslc/services/ContainerService.h
+1
@@ -16,6 +16,7 @@ Abstract:
16 #include "ContainerModel.h"
17 #include "Reporter.h"
18 #include <docker_schema.h>
19 +#include <wslc.h>
20 #include <wslc_schema.h>
21
22 namespace wsl::windows::wslc::services {
src/windows/wslc/services/ImageService.cpp
+12 -16
@@ -231,24 +231,20 @@ std::vector<ImageInformation> ImageService::List(
231 return result;
232 }
233
234 -void ImageService::Load(wsl::windows::wslc::models::Session& session, const std::wstring& input, IImageLoadCallback* callback)
234 +void ImageService::Load(Reporter& reporter, wsl::windows::wslc::models::Session& session, const std::wstring& input, IImageLoadCallback* callback)
235 {
236 + WarningCallback warningCallback(reporter);
237 auto source = OpenImageInput(input);
237 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
238 - THROW_IF_FAILED(session.Get()->LoadImage(ToCOMInputHandle(source.Handle.Get()), source.ContentLength, warningCallback.Get(), callback));
238 + THROW_IF_FAILED(session.Get()->LoadImage(ToCOMInputHandle(source.Handle.Get()), source.ContentLength, &warningCallback, callback));
239 }
240
241 -std::string ImageService::Import(wsl::windows::wslc::models::Session& session, const std::wstring& input, const std::string& imageName)
241 +std::string ImageService::Import(Reporter& reporter, wsl::windows::wslc::models::Session& session, const std::wstring& input, const std::string& imageName)
242 {
243 + WarningCallback warningCallback(reporter);
244 auto source = OpenImageInput(input);
244 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
245 wil::unique_cotaskmem_ansistring imageId;
246 THROW_IF_FAILED(session.Get()->ImportImage(
247 - ToCOMInputHandle(source.Handle.Get()),
248 - imageName.empty() ? nullptr : imageName.c_str(),
249 - source.ContentLength,
250 - warningCallback.Get(),
251 - &imageId));
247 + ToCOMInputHandle(source.Handle.Get()), imageName.empty() ? nullptr : imageName.c_str(), source.ContentLength, &warningCallback, &imageId));
248 return imageId.get() ? std::string(imageId.get()) : std::string();
249 }
250
@@ -271,12 +267,12 @@ void ImageService::Delete(wsl::windows::wslc::models::Session& session, const st
267 THROW_IF_FAILED(session.Get()->DeleteImage(&options, &deletedImages, deletedImages.size_address<ULONG>()));
268 }
269
274 -void ImageService::Pull(wsl::windows::wslc::models::Session& session, const std::string& image, IProgressCallback* callback)
270 +void ImageService::Pull(Reporter& reporter, wsl::windows::wslc::models::Session& session, const std::string& image, IProgressCallback* callback)
271 {
272 + WarningCallback warningCallback(reporter);
273 auto server = GetServerFromImage(image);
274 auto auth = RegistryService::Get(server);
278 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
279 - THROW_IF_FAILED(session.Get()->PullImage(image.c_str(), auth.c_str(), callback, warningCallback.Get()));
275 + THROW_IF_FAILED(session.Get()->PullImage(image.c_str(), auth.c_str(), callback, &warningCallback));
276 }
277
278 void ImageService::Tag(wsl::windows::wslc::models::Session& session, const std::string& sourceImage, const std::string& targetImage)
@@ -303,12 +299,12 @@ InspectImage ImageService::Inspect(wsl::windows::wslc::models::Session& session,
299 return wsl::shared::FromJson<InspectImage>(inspectData.get());
300 }
301
306 -void ImageService::Push(wsl::windows::wslc::models::Session& session, const std::string& image, IProgressCallback* callback)
302 +void ImageService::Push(Reporter& reporter, wsl::windows::wslc::models::Session& session, const std::string& image, IProgressCallback* callback)
303 {
304 + WarningCallback warningCallback(reporter);
305 auto server = GetServerFromImage(image);
306 auto auth = RegistryService::Get(server);
310 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
311 - THROW_IF_FAILED(session.Get()->PushImage(image.c_str(), auth.c_str(), callback, warningCallback.Get()));
307 + THROW_IF_FAILED(session.Get()->PushImage(image.c_str(), auth.c_str(), callback, &warningCallback));
308 }
309
310 void ImageService::Save(wsl::windows::wslc::models::Session& session, const std::vector<std::string>& images, const std::wstring& output, HANDLE cancelEvent)
src/windows/wslc/services/ImageService.h
+5 -4
@@ -15,6 +15,7 @@ Abstract:
15
16 #include "SessionModel.h"
17 #include "ImageModel.h"
18 +#include "Reporter.h"
19 #include <wslc_schema.h>
20
21 namespace wsl::windows::wslc::services {
@@ -35,12 +36,12 @@ public:
36
37 static std::vector<wsl::windows::wslc::models::ImageInformation> List(
38 wsl::windows::wslc::models::Session& session, const std::vector<std::pair<std::string, std::string>>& filters = {});
38 - static void Load(wsl::windows::wslc::models::Session& session, const std::wstring& input, IImageLoadCallback* callback = nullptr);
39 - static std::string Import(wsl::windows::wslc::models::Session& session, const std::wstring& input, const std::string& imageName);
39 + static void Load(Reporter& reporter, wsl::windows::wslc::models::Session& session, const std::wstring& input, IImageLoadCallback* callback = nullptr);
40 + static std::string Import(Reporter& reporter, wsl::windows::wslc::models::Session& session, const std::wstring& input, const std::string& imageName);
41 static void Delete(wsl::windows::wslc::models::Session& session, const std::string& image, bool force, bool noPrune);
42 static wsl::windows::common::wslc_schema::InspectImage Inspect(wsl::windows::wslc::models::Session& session, const std::string& image);
42 - static void Pull(wsl::windows::wslc::models::Session& session, const std::string& image, IProgressCallback* callback);
43 - static void Push(wsl::windows::wslc::models::Session& session, const std::string& image, IProgressCallback* callback);
43 + static void Pull(Reporter& reporter, wsl::windows::wslc::models::Session& session, const std::string& image, IProgressCallback* callback);
44 + static void Push(Reporter& reporter, wsl::windows::wslc::models::Session& session, const std::string& image, IProgressCallback* callback);
45 static void Save(wsl::windows::wslc::models::Session& session, const std::vector<std::string>& images, const std::wstring& output, HANDLE cancelEvent = nullptr);
46 static void Save(wsl::windows::wslc::models::Session& session, const std::vector<std::string>& images, HANDLE outputHandle, HANDLE cancelEvent = nullptr);
47 static void Tag(wsl::windows::wslc::models::Session& session, const std::string& sourceImage, const std::string& targetImage);
src/windows/wslc/services/NetworkService.cpp
+3 -3
@@ -22,8 +22,9 @@ using namespace wsl::windows::common::wslutil;
22
23 namespace wsl::windows::wslc::services {
24
25 -void NetworkService::Create(models::Session& session, const models::CreateNetworkOptions& createOptions)
25 +void NetworkService::Create(Reporter& reporter, models::Session& session, const models::CreateNetworkOptions& createOptions)
26 {
27 + WarningCallback warningCallback(reporter);
28 WSLCNetworkOptions options{};
29 options.Name = createOptions.Name.c_str();
30 if (createOptions.Driver.has_value())
@@ -61,8 +62,7 @@ void NetworkService::Create(models::Session& session, const models::CreateNetwor
62 options.Gateway = createOptions.Gateway->c_str();
63 }
64
64 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
65 - THROW_IF_FAILED(session.Get()->CreateNetwork(&options, warningCallback.Get()));
65 + THROW_IF_FAILED(session.Get()->CreateNetwork(&options, &warningCallback));
66 }
67
68 void NetworkService::Delete(models::Session& session, const std::string& name)
src/windows/wslc/services/NetworkService.h
+3 -1
@@ -15,12 +15,14 @@ Abstract:
15
16 #include "SessionModel.h"
17 #include "NetworkModel.h"
18 +#include "Reporter.h"
19 +#include <wslc.h>
20 #include <wslc_schema.h>
21
22 namespace wsl::windows::wslc::services {
23 struct NetworkService
24 {
23 - static void Create(models::Session& session, const models::CreateNetworkOptions& createOptions);
25 + static void Create(Reporter& reporter, models::Session& session, const models::CreateNetworkOptions& createOptions);
26 static void Delete(models::Session& session, const std::string& name);
27 static std::vector<WSLCNetworkInformation> List(models::Session& session);
28 static wsl::windows::common::wslc_schema::Network Inspect(models::Session& session, const std::string& name);
src/windows/wslc/services/SessionService.cpp
+5 -5
@@ -52,14 +52,14 @@ Session SessionService::OpenDefaultSession()
52 return OpenSessionByName(CreateSessionManager(), nullptr);
53 }
54
55 -Session SessionService::OpenOrCreateDefaultSession()
55 +Session SessionService::OpenOrCreateDefaultSession(Reporter& reporter)
56 {
57 + WarningCallback warningCallback(reporter);
58 auto manager = CreateSessionManager();
59
60 // Null Settings = default session with server-determined name and settings.
61 wil::com_ptr<IWSLCSession> session;
61 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
62 - THROW_IF_FAILED(manager->CreateSession(nullptr, WSLCSessionFlagsNone, warningCallback.Get(), &session));
62 + THROW_IF_FAILED(manager->CreateSession(nullptr, WSLCSessionFlagsNone, &warningCallback, &session));
63 wsl::windows::common::security::ConfigureForCOMImpersonation(session.get());
64 return Session(std::move(session));
65 }
@@ -123,11 +123,11 @@ int SessionService::Enter(Reporter& reporter, const std::wstring& storagePath, c
123 THROW_HR_IF(E_INVALIDARG, storagePath.empty());
124 THROW_HR_IF(E_INVALIDARG, displayName.empty());
125
126 + WarningCallback warningCallback(reporter);
127 auto sessionManager = CreateSessionManager();
128
129 wil::com_ptr<IWSLCSession> session;
129 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
130 - THROW_IF_FAILED(sessionManager->EnterSession(displayName.c_str(), storagePath.c_str(), warningCallback.Get(), &session));
130 + THROW_IF_FAILED(sessionManager->EnterSession(displayName.c_str(), storagePath.c_str(), &warningCallback, &session));
131 wsl::windows::common::security::ConfigureForCOMImpersonation(session.get());
132 reporter.Info(L"{}\n", Localization::MessageWslcCreatedSession(displayName));
133
src/windows/wslc/services/SessionService.h
+1 -1
@@ -35,7 +35,7 @@ struct SessionService
35 // Opens the default session. Throws WSLC_E_SESSION_NOT_FOUND if no default session exists.
36 static wsl::windows::wslc::models::Session OpenDefaultSession();
37 // Opens or creates the default session.
38 - static wsl::windows::wslc::models::Session OpenOrCreateDefaultSession();
38 + static wsl::windows::wslc::models::Session OpenOrCreateDefaultSession(Reporter& reporter);
39 // Runs the given command and arguments in a session without a TTY, resolving the executable from PATH.
40 static int Run(Reporter& reporter, const wsl::windows::wslc::models::Session& session, const std::vector<std::string>& arguments);
41 static int TerminateSession(Reporter& reporter, const wsl::windows::wslc::models::Session& session);
src/windows/wslc/services/VolumeService.cpp
+4 -3
@@ -83,8 +83,10 @@ wsl::windows::common::wslc_schema::InspectVolume VolumeService::Inspect(models::
83 return FromJson<wsl::windows::common::wslc_schema::InspectVolume>(output.get());
84 }
85
86 -models::PruneVolumesResult VolumeService::Prune(models::Session& session, bool all, const std::vector<std::pair<std::string, std::string>>& filters)
86 +models::PruneVolumesResult VolumeService::Prune(
87 + Reporter& reporter, models::Session& session, bool all, const std::vector<std::pair<std::string, std::string>>& filters)
88 {
89 + WarningCallback warningCallback(reporter);
90 const bool hasExplicitAll = std::any_of(filters.begin(), filters.end(), [](const auto& f) { return f.first == "all"; });
91
92 std::vector<WSLCFilter> filterEntries;
@@ -99,13 +101,12 @@ models::PruneVolumesResult VolumeService::Prune(models::Session& session, bool a
101 filterEntries.push_back({.Key = key.c_str(), .Value = value.c_str()});
102 }
103
102 - auto warningCallback = Microsoft::WRL::Make<WarningCallback>();
104 wil::unique_cotaskmem_array_ptr<WSLCVolumeName> volumes;
105 ULONGLONG spaceReclaimed = 0;
106 THROW_IF_FAILED(session.Get()->PruneVolumes(
107 filterEntries.empty() ? nullptr : filterEntries.data(),
108 static_cast<ULONG>(filterEntries.size()),
108 - warningCallback.Get(),
109 + &warningCallback,
110 &volumes,
111 volumes.size_address<ULONG>(),
112 &spaceReclaimed));
src/windows/wslc/services/VolumeService.h
+4 -1
@@ -15,6 +15,8 @@ Abstract:
15
16 #include "SessionModel.h"
17 #include "VolumeModel.h"
18 +#include "Reporter.h"
19 +#include <wslc.h>
20 #include <wslc_schema.h>
21
22 namespace wsl::windows::wslc::services {
@@ -24,6 +26,7 @@ struct VolumeService
26 static void Delete(models::Session& session, const std::string& name);
27 static std::vector<WSLCVolumeInformation> List(models::Session& session);
28 static wsl::windows::common::wslc_schema::InspectVolume Inspect(models::Session& session, const std::string& name);
27 - static models::PruneVolumesResult Prune(models::Session& session, bool all, const std::vector<std::pair<std::string, std::string>>& filters = {});
29 + static models::PruneVolumesResult Prune(
30 + Reporter& reporter, models::Session& session, bool all, const std::vector<std::pair<std::string, std::string>>& filters = {});
31 };
32 } // namespace wsl::windows::wslc::services
src/windows/wslc/services/WarningCallback.h
+23 -5
@@ -2,23 +2,41 @@
2
3 #pragma once
4
5 +#include "Reporter.h"
6 #include <wslc.h>
7 #include <wslutil.h>
8
9 namespace wsl::windows::wslc::services {
10
11 +// Adapts the service IWarningCallback COM sink onto the CLI Reporter so the CLI, not the
12 +// service, decides how warnings are presented (mirrors ImageProgressCallback).
13 class DECLSPEC_UUID("A7E3F8B2-4D19-4C6A-9E5B-8F2A1D3C7E90") WarningCallback
14 : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWarningCallback, IFastRundown>
15 {
16 public:
17 + explicit WarningCallback(Reporter& reporter) : m_reporter(reporter)
18 + {
19 + }
20 +
21 HRESULT OnWarning(LPCWSTR Message) override
22 {
16 - WI_ASSERT(Message);
17 - // The message already includes the "wsl: " prefix and a trailing newline (added by
18 - // EmitUserWarning), so write it directly. This matches how wsl.exe surfaces its warnings.
19 - fputws(Message, stderr);
20 - return S_OK;
23 + try
24 + {
25 + WI_ASSERT(Message);
26 + if (Message != nullptr)
27 + {
28 + // Message already carries the "wsl: " prefix and trailing newline from EmitUserWarning;
29 + // Warn writes it verbatim, adding color only on a VT console.
30 + m_reporter.Warn(L"{}", Message);
31 + }
32 +
33 + return S_OK;
34 + }
35 + CATCH_RETURN();
36 }
37 +
38 +private:
39 + Reporter& m_reporter;
40 };
41
42 } // namespace wsl::windows::wslc::services
src/windows/wslc/tasks/ImageTasks.cpp
+4 -4
@@ -226,7 +226,7 @@ void PullImage(CLIExecutionContext& context)
226 auto& imageId = context.Args.Get<ArgType::ImageId>();
227
228 ImageProgressCallback callback(context.Reporter, Reporter::Level::Output);
229 - services::ImageService::Pull(session, WideToMultiByte(imageId), &callback);
229 + services::ImageService::Pull(context.Reporter, session, WideToMultiByte(imageId), &callback);
230 }
231
232 void PushImage(CLIExecutionContext& context)
@@ -237,7 +237,7 @@ void PushImage(CLIExecutionContext& context)
237 auto& imageId = context.Args.Get<ArgType::ImageId>();
238
239 ImageProgressCallback callback(context.Reporter, Reporter::Level::Output);
240 - services::ImageService::Push(session, WideToMultiByte(imageId), &callback);
240 + services::ImageService::Push(context.Reporter, session, WideToMultiByte(imageId), &callback);
241 }
242
243 void DeleteImage(CLIExecutionContext& context)
@@ -262,7 +262,7 @@ void LoadImage(CLIExecutionContext& context)
262 {
263 auto& input = context.Args.Get<ArgType::Input>();
264 auto callback = wil::MakeOrThrow<WSLCImageLoadCallback>(context.Reporter);
265 - services::ImageService::Load(session, input, callback.Get());
265 + services::ImageService::Load(context.Reporter, session, input, callback.Get());
266 return;
267 }
268
@@ -283,7 +283,7 @@ void ImportImage(CLIExecutionContext& context)
283 }
284
285 auto& input = context.Args.Get<ArgType::ImportFile>();
286 - auto imageId = services::ImageService::Import(session, input, imageName);
286 + auto imageId = services::ImageService::Import(context.Reporter, session, input, imageName);
287 if (!imageId.empty())
288 {
289 bool trunc = !context.Args.Contains(ArgType::NoTrunc);
src/windows/wslc/tasks/NetworkTasks.cpp
+1 -1
@@ -107,7 +107,7 @@ void CreateNetwork(CLIExecutionContext& context)
107 options.Gateway = WideToMultiByte(context.Args.Get<ArgType::Gateway>());
108 }
109
110 - NetworkService::Create(context.Data.Get<Data::Session>(), options);
110 + NetworkService::Create(context.Reporter, context.Data.Get<Data::Session>(), options);
111 context.Reporter.Output(L"{}\n", MultiByteToWide(options.Name));
112 }
113
src/windows/wslc/tasks/SessionTasks.cpp
+1 -1
@@ -46,7 +46,7 @@ void OpenOrCreateDefaultSession(CLIExecutionContext& context)
46 {
47 if (!context.Data.Contains(Data::Session))
48 {
49 - context.Data.Add<Data::Session>(SessionService::OpenOrCreateDefaultSession());
49 + context.Data.Add<Data::Session>(SessionService::OpenOrCreateDefaultSession(context.Reporter));
50 }
51 }
52
src/windows/wslc/tasks/VolumeTasks.cpp
+1 -1
@@ -213,7 +213,7 @@ void PruneVolumes(CLIExecutionContext& context)
213 filters.push_back(validation::ParseFilter(value));
214 }
215
216 - auto result = VolumeService::Prune(session, all, filters);
216 + auto result = VolumeService::Prune(context.Reporter, session, all, filters);
217
218 for (const auto& volumeName : result.PrunedVolumes)
219 {