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 @@ -2690,6 +2690,43 @@ 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_NetworkCommandDesc" xml:space="preserve">
<value>Manage networks.</value>
</data>
<data name="WSLCCLI_NetworkCommandLongDesc" xml:space="preserve">
<value>Manage the lifecycle of WSL networks, including creating, inspecting, listing, and deleting them.</value>
<comment>{Locked="WSL"}Product names should not be translated</comment>
</data>
<data name="WSLCCLI_NetworkCreateDesc" xml:space="preserve">
<value>Create a network.</value>
</data>
<data name="WSLCCLI_NetworkCreateLongDesc" xml:space="preserve">
<value>Creates a new network.</value>
</data>
<data name="WSLCCLI_NetworkRemoveDesc" xml:space="preserve">
<value>Remove one or more networks.</value>
</data>
<data name="WSLCCLI_NetworkRemoveLongDesc" xml:space="preserve">
<value>Removes one or more networks. A network cannot be removed if it has active endpoints.</value>
</data>
<data name="WSLCCLI_NetworkInspectDesc" xml:space="preserve">
<value>Display detailed information on one or more networks.</value>
</data>
<data name="WSLCCLI_NetworkInspectLongDesc" xml:space="preserve">
<value>Display detailed information on one or more networks.</value>
</data>
<data name="WSLCCLI_NetworkListDesc" xml:space="preserve">
<value>List networks.</value>
</data>
<data name="WSLCCLI_NetworkListLongDesc" xml:space="preserve">
<value>Lists all networks in the session.</value>
</data>
<data name="WSLCCLI_NetworkNameArgDescription" xml:space="preserve">
<value>Network name</value>
</data>
<data name="WSLCCLI_NetworkListQuietArgDesc" xml:space="preserve">
<value>Outputs the network names only</value>
</data>
<data name="WSLCCLI_VolumeCommandDesc" xml:space="preserve">
<value>Manage volumes.</value>
</data>
Expand Down
20 changes: 20 additions & 0 deletions src/shared/inc/JsonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,26 @@ struct adl_serializer<WSLCVolumeInformation>
strncpy_s(volume.Driver, sizeof(volume.Driver), driver.c_str(), _TRUNCATE);
}
};

template <>
struct adl_serializer<WSLCNetworkInformation>
{
static void to_json(json& j, const WSLCNetworkInformation& network)
{
j = json{{"Name", std::string(network.Name)}, {"Id", std::string(network.Id)}, {"Driver", std::string(network.Driver)}};
}

static void from_json(const json& j, WSLCNetworkInformation& network)
{
std::string name = j.at("Name").get<std::string>();
std::string id = j.at("Id").get<std::string>();
std::string driver = j.at("Driver").get<std::string>();

strncpy_s(network.Name, sizeof(network.Name), name.c_str(), _TRUNCATE);
strncpy_s(network.Id, sizeof(network.Id), id.c_str(), _TRUNCATE);
strncpy_s(network.Driver, sizeof(network.Driver), driver.c_str(), _TRUNCATE);
}
};
#endif

} // namespace nlohmann
1 change: 1 addition & 0 deletions src/windows/wslc/arguments/ArgumentDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ _(Input, "input", L"i", Kind::Value, L
_(Interactive, "interactive", L"i", Kind::Flag, Localization::WSLCCLI_InteractiveArgDescription()) \
_(Label, "label", NO_ALIAS, Kind::Value, L"Volume metadata setting") \
_(Name, "name", NO_ALIAS, Kind::Value, Localization::WSLCCLI_NameArgDescription()) \
_(NetworkName, "network-name", NO_ALIAS, Kind::Positional, Localization::WSLCCLI_NetworkNameArgDescription()) \
/*_(NoDNS, "no-dns", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoDNSArgDescription())*/ \
_(NoCache, "no-cache", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoCacheArgDescription()) \
_(NoPrune, "no-prune", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoPruneArgDescription()) \
Expand Down
6 changes: 5 additions & 1 deletion src/windows/wslc/arguments/ArgumentValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,17 @@ InspectType GetInspectTypeFromString(const std::wstring& input, const std::wstri
{
return InspectType::Container;
}
else if (IsEqual(input, L"network"))
{
return InspectType::Network;
}
else if (IsEqual(input, L"volume"))
{
return InspectType::Volume;
}
else
{
constexpr std::wstring_view supportedValues = L"image, container, volume";
constexpr std::wstring_view supportedValues = L"image, container, network, volume";
throw ArgumentException(Localization::WSLCCLI_InvalidInspectError(argName, input, supportedValues));
}
}
Expand Down
51 changes: 51 additions & 0 deletions src/windows/wslc/commands/NetworkCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

NetworkCommand.cpp

Abstract:

Implementation of command execution logic.

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

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

namespace wsl::windows::wslc {
// Network Root Command
std::vector<std::unique_ptr<Command>> NetworkCommand::GetCommands() const
{
std::vector<std::unique_ptr<Command>> commands;
commands.push_back(std::make_unique<NetworkCreateCommand>(FullName()));
commands.push_back(std::make_unique<NetworkRemoveCommand>(FullName()));
commands.push_back(std::make_unique<NetworkInspectCommand>(FullName()));
commands.push_back(std::make_unique<NetworkListCommand>(FullName()));
return commands;
}

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

std::wstring NetworkCommand::ShortDescription() const
{
return Localization::WSLCCLI_NetworkCommandDesc();
}

std::wstring NetworkCommand::LongDescription() const
{
return Localization::WSLCCLI_NetworkCommandLongDesc();
}

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

Copyright (c) Microsoft. All rights reserved.

Module Name:

NetworkCommand.h

Abstract:

Declaration of command classes and interfaces.

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

namespace wsl::windows::wslc {
// Root Network Command
struct NetworkCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"network";
NetworkCommand(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 NetworkCreateCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"create";
NetworkCreateCommand(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;
};

// Remove Command
struct NetworkRemoveCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"remove";
NetworkRemoveCommand(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 NetworkInspectCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"inspect";
NetworkInspectCommand(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 NetworkListCommand final : public Command
{
constexpr static std::wstring_view CommandName = L"list";
NetworkListCommand(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
53 changes: 53 additions & 0 deletions src/windows/wslc/commands/NetworkCreateCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*++
Copyright (c) Microsoft. All rights reserved.
Module Name:
NetworkCreateCommand.cpp
Abstract:
Implementation of command execution logic.
--*/

#include "NetworkCommand.h"
#include "CLIExecutionContext.h"
#include "SessionTasks.h"
#include "NetworkTasks.h"
#include "Task.h"

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

namespace wsl::windows::wslc {
// Network Create Command
std::vector<Argument> NetworkCreateCommand::GetArguments() const
{
return {
Argument::Create(ArgType::NetworkName, true),
Argument::Create(ArgType::Driver),
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

network create treats --driver as optional, but the underlying COM API IWSLCSession::CreateNetwork requires WSLCNetworkOptions::Driver to be non-null. If the user omits --driver, the CLI will pass a null driver and fail with an internal pointer error instead of a user-friendly message. Please either make --driver required for this command or supply a default (likely "bridge") before calling into the service, and update help text accordingly.

Suggested change
Argument::Create(ArgType::Driver),
Argument::Create(ArgType::Driver, true),

Copilot uses AI. Check for mistakes.
Argument::Create(ArgType::Options, false, NO_LIMIT),
Argument::Create(ArgType::Label, false, NO_LIMIT),
Comment on lines +29 to +33
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

NetworkCreateCommand reuses shared --driver/--label argument definitions whose descriptions are volume-specific (e.g., DriverArgDescription("guest") and "Volume metadata setting"). This makes wslc network create --help misleading. Consider overriding these descriptions for the network command (and localizing them) so help text refers to network drivers/labels and reflects the actual default/supported driver values.

Suggested change
return {
Argument::Create(ArgType::NetworkName, true),
Argument::Create(ArgType::Driver),
Argument::Create(ArgType::Options, false, NO_LIMIT),
Argument::Create(ArgType::Label, false, NO_LIMIT),
auto driverArgument = Argument::Create(ArgType::Driver);
driverArgument.Description = Localization::WSLCCLI_NetworkCreateDriverArgDesc();
auto labelArgument = Argument::Create(ArgType::Label, false, NO_LIMIT);
labelArgument.Description = Localization::WSLCCLI_NetworkCreateLabelArgDesc();
return {
Argument::Create(ArgType::NetworkName, true),
std::move(driverArgument),
Argument::Create(ArgType::Options, false, NO_LIMIT),
std::move(labelArgument),

Copilot uses AI. Check for mistakes.
Argument::Create(ArgType::Session),
};
}

std::wstring NetworkCreateCommand::ShortDescription() const
{
return Localization::WSLCCLI_NetworkCreateDesc();
}

std::wstring NetworkCreateCommand::LongDescription() const
{
return Localization::WSLCCLI_NetworkCreateLongDesc();
}

void NetworkCreateCommand::ExecuteInternal(CLIExecutionContext& context) const
{
context << CreateSession //
<< CreateNetwork;
}
} // namespace wsl::windows::wslc
50 changes: 50 additions & 0 deletions src/windows/wslc/commands/NetworkInspectCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

NetworkInspectCommand.cpp

Abstract:

Implementation of command execution logic.

--*/

#include "NetworkCommand.h"
#include "CLIExecutionContext.h"
#include "SessionTasks.h"
#include "NetworkTasks.h"
#include "Task.h"

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

namespace wsl::windows::wslc {
// Network Inspect Command
std::vector<Argument> NetworkInspectCommand::GetArguments() const
{
return {
Argument::Create(ArgType::NetworkName, true, NO_LIMIT),
Argument::Create(ArgType::Session),
};
}

std::wstring NetworkInspectCommand::ShortDescription() const
{
return Localization::WSLCCLI_NetworkInspectDesc();
}

std::wstring NetworkInspectCommand::LongDescription() const
{
return Localization::WSLCCLI_NetworkInspectLongDesc();
}

void NetworkInspectCommand::ExecuteInternal(CLIExecutionContext& context) const
{
context << CreateSession //
<< InspectNetworks;
}
} // namespace wsl::windows::wslc
Loading
Loading