Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions localization/strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -2505,4 +2505,41 @@ On first run, creates the file with all settings commented out at their defaults
<data name="WSLCCLI_ImageLoadNoInputError" xml:space="preserve">
<value>Requested load but no input provided.</value>
</data>
<data name="WSLCCLI_VolumeCommandDesc" xml:space="preserve">
<value>Manage volumes.</value>
</data>
<data name="WSLCCLI_VolumeCommandLongDesc" xml:space="preserve">
<value>Manage the lifecycle of WSL volumes, including creating, inspecting, listing, and deleting them.</value>
<comment>{Locked="WSL"}Product names should not be translated</comment>
</data>
<data name="WSLCCLI_VolumeCreateDesc" xml:space="preserve">
<value>Create a volume.</value>
</data>
<data name="WSLCCLI_VolumeCreateLongDesc" xml:space="preserve">
<value>Creates a named volume that can be attached to containers.</value>
</data>
<data name="WSLCCLI_VolumeDeleteDesc" xml:space="preserve">
<value>Remove one or more volumes.</value>
</data>
<data name="WSLCCLI_VolumeDeleteLongDesc" xml:space="preserve">
<value>Removes one or more volumes. A volume cannot be removed if it is in use by a container.</value>
</data>
<data name="WSLCCLI_VolumeInspectDesc" xml:space="preserve">
<value>Display detailed information on one or more volumes.</value>
</data>
<data name="WSLCCLI_VolumeInspectLongDesc" xml:space="preserve">
<value>Display detailed information on one or more volumes.</value>
</data>
<data name="WSLCCLI_VolumeListDesc" xml:space="preserve">
<value>List volumes.</value>
</data>
<data name="WSLCCLI_VolumeListLongDesc" xml:space="preserve">
<value>Lists all volumes in the session.</value>
</data>
<data name="WSLCCLI_VolumeNameArgDescription" xml:space="preserve">
<value>Volume name</value>
</data>
<data name="WSLCCLI_VolumeDriverArgDescription" xml:space="preserve">
<value>Specify volume driver name</value>
</data>
</root>
2 changes: 2 additions & 0 deletions src/windows/wslc/arguments/ArgumentDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,7 @@ _(Verbose, "verbose", NO_ALIAS, Kind::Flag, L
_(Version, "version", L"v", Kind::Flag, Localization::WSLCCLI_VersionArgDescription()) \
/*_(Virtual, "virtualization", NO_ALIAS, Kind::Value, Localization::WSLCCLI_VirtualArgDescription())*/ \
_(Volume, "volume", L"v", Kind::Value, Localization::WSLCCLI_VolumeArgDescription()) \
_(VolumeDriver, "driver", L"d", Kind::Value, Localization::WSLCCLI_VolumeDriverArgDescription()) \
_(VolumeName, "volume-name", NO_ALIAS, Kind::Positional, Localization::WSLCCLI_VolumeNameArgDescription()) \
_(WorkDir, "workdir", L"w", Kind::Value, Localization::WSLCCLI_WorkingDirArgDescription()) \
// clang-format on
27 changes: 27 additions & 0 deletions src/windows/wslc/arguments/ArgumentValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ void Argument::Validate(const ArgMap& execArgs) const
validation::ValidateVolumeMount(execArgs.GetAll<ArgType::Volume>());
break;

case ArgType::VolumeDriver:
validation::ValidateVolumeDriver(execArgs.GetAll<ArgType::VolumeDriver>(), m_name);
break;

case ArgType::WorkDir:
{
const auto& value = execArgs.Get<ArgType::WorkDir>();
Expand Down Expand Up @@ -97,6 +101,29 @@ void ValidateVolumeMount(const std::vector<std::wstring>& values)
}
}

void ValidateVolumeDriver(const std::vector<std::wstring>& values, const std::wstring& argName)
{
static const std::vector<std::wstring> supportedDrivers = {L"vhd"};
for (const auto& value : values)
{
bool found = false;
for (const auto& driver : supportedDrivers)
{
if (IsEqual(value, driver))
{
found = true;
break;
}
}

if (!found)
{
throw ArgumentException(std::format(
L"Invalid {} value: {} is not a recognized volume driver. Supported drivers are: vhd.", argName, value));
}
}
}

// Convert string to WSLCSignal enum - accepts either signal name (e.g., "SIGKILL") or number (e.g., "9")
WSLCSignal GetWSLCSignalFromString(const std::wstring& input, const std::wstring& argName)
{
Expand Down
1 change: 1 addition & 0 deletions src/windows/wslc/arguments/ArgumentValidation.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,6 @@ void ValidateFormatTypeFromString(const std::vector<std::wstring>& values, const
FormatType GetFormatTypeFromString(const std::wstring& input, const std::wstring& argName = {});

void ValidateVolumeMount(const std::vector<std::wstring>& values);
void ValidateVolumeDriver(const std::vector<std::wstring>& values, const std::wstring& argName);

} // namespace wsl::windows::wslc::validation
2 changes: 2 additions & 0 deletions src/windows/wslc/commands/RootCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Module Name:
#include "SessionCommand.h"
#include "SettingsCommand.h"
#include "VersionCommand.h"
#include "VolumeCommand.h"

using namespace wsl::windows::wslc::execution;
using namespace wsl::shared;
Expand All @@ -31,6 +32,7 @@ std::vector<std::unique_ptr<Command>> RootCommand::GetCommands() const
commands.push_back(std::make_unique<ImageCommand>(FullName()));
commands.push_back(std::make_unique<SessionCommand>(FullName()));
commands.push_back(std::make_unique<SettingsCommand>(FullName()));
commands.push_back(std::make_unique<VolumeCommand>(FullName()));
commands.push_back(std::make_unique<ContainerAttachCommand>(FullName()));
commands.push_back(std::make_unique<ImageBuildCommand>(FullName()));
commands.push_back(std::make_unique<ContainerCreateCommand>(FullName()));
Expand Down
51 changes: 51 additions & 0 deletions src/windows/wslc/commands/VolumeCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

VolumeCommand.cpp

Abstract:

Implementation of command execution logic.

--*/
#include "CLIExecutionContext.h"
#include "VolumeCommand.h"

using namespace wsl::windows::wslc::execution;
using namespace wsl::shared;

namespace wsl::windows::wslc {
// Volume Root Command
std::vector<std::unique_ptr<Command>> VolumeCommand::GetCommands() const
{
std::vector<std::unique_ptr<Command>> commands;
commands.push_back(std::make_unique<VolumeCreateCommand>(FullName()));
commands.push_back(std::make_unique<VolumeDeleteCommand>(FullName()));
commands.push_back(std::make_unique<VolumeInspectCommand>(FullName()));
commands.push_back(std::make_unique<VolumeListCommand>(FullName()));
return commands;
}

std::vector<Argument> VolumeCommand::GetArguments() const
{
return {};
}

std::wstring VolumeCommand::ShortDescription() const
{
return Localization::WSLCCLI_VolumeCommandDesc();
}

std::wstring VolumeCommand::LongDescription() const
{
return Localization::WSLCCLI_VolumeCommandLongDesc();
}

void VolumeCommand::ExecuteInternal(CLIExecutionContext& context) const
{
OutputHelp();
}
} // namespace wsl::windows::wslc
95 changes: 95 additions & 0 deletions src/windows/wslc/commands/VolumeCommand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

VolumeCommand.h

Abstract:

Declaration of command classes and interfaces.

--*/
#pragma once
#include "Command.h"

namespace wsl::windows::wslc {
// Root Volume Command
struct VolumeCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"volume";
VolumeCommand(const std::wstring& parent) : Command(CommandName, parent)
{
}
std::vector<Argument> GetArguments() const override;
std::wstring ShortDescription() const override;
std::wstring LongDescription() const override;

std::vector<std::unique_ptr<Command>> GetCommands() const override;

protected:
void ExecuteInternal(CLIExecutionContext& context) const override;
};

// Create Command
struct VolumeCreateCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"create";
VolumeCreateCommand(const std::wstring& parent) : Command(CommandName, parent)
{
}
std::vector<Argument> GetArguments() const override;
std::wstring ShortDescription() const override;
std::wstring LongDescription() const override;

protected:
void ExecuteInternal(CLIExecutionContext& context) const override;
};

// Delete Command
struct VolumeDeleteCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"remove";
VolumeDeleteCommand(const std::wstring& parent) : Command(CommandName, {L"delete", L"rm"}, parent)
{
}
std::vector<Argument> GetArguments() const override;
std::wstring ShortDescription() const override;
std::wstring LongDescription() const override;

protected:
void ExecuteInternal(CLIExecutionContext& context) const override;
};

// Inspect Command
struct VolumeInspectCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"inspect";
VolumeInspectCommand(const std::wstring& parent) : Command(CommandName, parent)
{
}
std::vector<Argument> GetArguments() const override;
std::wstring ShortDescription() const override;
std::wstring LongDescription() const override;

protected:
void ExecuteInternal(CLIExecutionContext& context) const override;
};

// List Command
struct VolumeListCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"list";
VolumeListCommand(const std::wstring& parent) : Command(CommandName, {L"ls"}, parent)
{
}
std::vector<Argument> GetArguments() const override;
std::wstring ShortDescription() const override;
std::wstring LongDescription() const override;

protected:
void ValidateArgumentsInternal(const ArgMap& execArgs) const override;
void ExecuteInternal(CLIExecutionContext& context) const override;
};
} // namespace wsl::windows::wslc
54 changes: 54 additions & 0 deletions src/windows/wslc/commands/VolumeCreateCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

VolumeCreateCommand.cpp

Abstract:

Implementation of command execution logic.

--*/

#include "VolumeCommand.h"
#include "CLIExecutionContext.h"
#include "SessionTasks.h"
#include "VolumeTasks.h"
#include "Task.h"

using namespace wsl::windows::wslc::execution;
using namespace wsl::windows::wslc::task;
using namespace wsl::shared;

namespace wsl::windows::wslc {
// Volume Create Command
std::vector<Argument> VolumeCreateCommand::GetArguments() const
{
return {
Argument::Create(ArgType::VolumeName, true),
Argument::Create(ArgType::VolumeDriver),
Argument::Create(ArgType::Session),
};
}

std::wstring VolumeCreateCommand::ShortDescription() const
{
return Localization::WSLCCLI_VolumeCreateDesc();
}

std::wstring VolumeCreateCommand::LongDescription() const
{
return Localization::WSLCCLI_VolumeCreateLongDesc();
}

// clang-format off
void VolumeCreateCommand::ExecuteInternal(CLIExecutionContext& context) const
{
context
<< CreateSession
<< CreateVolume;
}
// clang-format on
} // namespace wsl::windows::wslc
53 changes: 53 additions & 0 deletions src/windows/wslc/commands/VolumeDeleteCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

VolumeDeleteCommand.cpp

Abstract:

Implementation of command execution logic.

--*/

#include "VolumeCommand.h"
#include "CLIExecutionContext.h"
#include "SessionTasks.h"
#include "VolumeTasks.h"
#include "Task.h"

using namespace wsl::windows::wslc::execution;
using namespace wsl::windows::wslc::task;
using namespace wsl::shared;

namespace wsl::windows::wslc {
// Volume Delete Command
std::vector<Argument> VolumeDeleteCommand::GetArguments() const
{
return {
Argument::Create(ArgType::VolumeName, true, NO_LIMIT),
Argument::Create(ArgType::Session),
};
}

std::wstring VolumeDeleteCommand::ShortDescription() const
{
return Localization::WSLCCLI_VolumeDeleteDesc();
}

std::wstring VolumeDeleteCommand::LongDescription() const
{
return Localization::WSLCCLI_VolumeDeleteLongDesc();
}

// clang-format off
void VolumeDeleteCommand::ExecuteInternal(CLIExecutionContext& context) const
{
context
<< CreateSession
<< DeleteVolumes;
}
// clang-format on
} // namespace wsl::windows::wslc
Loading