Skip to content
Open
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
29 changes: 29 additions & 0 deletions localization/strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -2840,6 +2840,24 @@ On first run, creates the file with all settings commented out at their defaults
<value>Invalid {} value: '{}'. Only 'all' is supported.</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="WSLCCLI_HealthCmdArgDescription" xml:space="preserve">
<value>Command to run to check container health</value>
</data>
<data name="WSLCCLI_HealthIntervalArgDescription" xml:space="preserve">
<value>Time between running the health check (e.g. 30s, 1m30s)</value>
<comment>{Locked="30s"}{Locked="1m30s"}Command line argument example values should not be translated</comment>
</data>
<data name="WSLCCLI_HealthRetriesArgDescription" xml:space="preserve">
<value>Consecutive failures needed to report the container as unhealthy</value>
</data>
<data name="WSLCCLI_HealthStartPeriodArgDescription" xml:space="preserve">
<value>Start period for the container to initialize before health-check countdown (e.g. 30s, 1m30s)</value>
<comment>{Locked="30s"}{Locked="1m30s"}Command line argument example values should not be translated</comment>
</data>
<data name="WSLCCLI_HealthTimeoutArgDescription" xml:space="preserve">
<value>Maximum time to allow one health check to run (e.g. 30s, 1m30s)</value>
<comment>{Locked="30s"}{Locked="1m30s"}Command line argument example values should not be translated</comment>
</data>
<data name="WSLCCLI_ImageForceArgDescription" xml:space="preserve">
<value>Delete images even if they are being used</value>
</data>
Expand Down Expand Up @@ -2897,6 +2915,9 @@ On first run, creates the file with all settings commented out at their defaults
<data name="WSLCCLI_NoCacheArgDescription" xml:space="preserve">
<value>Do not use cache when building the image</value>
</data>
<data name="WSLCCLI_NoHealthcheckArgDescription" xml:space="preserve">
<value>Disable any container-specified health check</value>
</data>
<data name="WSLCCLI_NoPruneArgDescription" xml:space="preserve">
<value>Do not delete untagged parents</value>
</data>
Expand Down Expand Up @@ -3077,6 +3098,14 @@ On first run, creates the file with all settings commented out at their defaults
<value>Invalid {} argument value: '{}'. Expected a memory size (e.g. 256M, 1G)</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated{Locked="256M"}{Locked="1G"}</comment>
</data>
<data name="WSLCCLI_InvalidDurationError" xml:space="preserve">
<value>Invalid {} argument value: '{}'. Expected a duration (e.g. 30s, 1m30s)</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated{Locked="30s"}{Locked="1m30s"}</comment>
</data>
<data name="WSLCCLI_NoHealthcheckConflictError" xml:space="preserve">
<value>The '--no-healthcheck' option cannot be combined with other health check options.</value>
<comment>{Locked="--no-healthcheck'"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="WSLCCLI_CIDFileAlreadyExistsError" xml:space="preserve">
<value>CID file '{}' already exists</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
Expand Down
45 changes: 45 additions & 0 deletions src/windows/common/WSLCContainerLauncher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,36 @@ void WSLCContainerLauncher::SetShmSize(int64_t ShmSize)
m_shmSize = ShmSize;
}

void WSLCContainerLauncher::SetHealthCmd(std::string&& HealthCmd)
{
m_healthCmd = std::move(HealthCmd);
}

void WSLCContainerLauncher::SetHealthInterval(int64_t Nanoseconds)
{
m_healthInterval = Nanoseconds;
}

void WSLCContainerLauncher::SetHealthTimeout(int64_t Nanoseconds)
{
m_healthTimeout = Nanoseconds;
}

void WSLCContainerLauncher::SetHealthStartPeriod(int64_t Nanoseconds)
{
m_healthStartPeriod = Nanoseconds;
}

void WSLCContainerLauncher::SetHealthRetries(LONG Retries)
{
m_healthRetries = Retries;
}

void WSLCContainerLauncher::SetNoHealthcheck()
{
WI_SetFlag(m_containerFlags, WSLCContainerFlagsNoHealthCheck);
}

void WSLCContainerLauncher::SetEntrypoint(std::vector<std::string>&& entrypoint)
{
m_entrypoint = std::move(entrypoint);
Expand Down Expand Up @@ -309,6 +339,21 @@ std::pair<HRESULT, std::optional<RunningWSLCContainer>> WSLCContainerLauncher::C

options.ShmSize = m_shmSize;

if (m_healthCmd.has_value() || m_healthInterval.has_value() || m_healthTimeout.has_value() ||
m_healthStartPeriod.has_value() || m_healthRetries.has_value())
{
if (m_healthCmd.has_value())
{
options.HealthCmd = m_healthCmd->c_str();
}

options.HealthIntervalNs = m_healthInterval.value_or(0);
options.HealthTimeoutNs = m_healthTimeout.value_or(0);
options.HealthStartPeriodNs = m_healthStartPeriod.value_or(0);
options.HealthRetries = m_healthRetries.value_or(0);
WI_SetFlag(options.Flags, WSLCContainerFlagsHealthCheck);
}

if (!entrypointStorage.empty())
{
options.Entrypoint = {entrypointStorage.data(), static_cast<ULONG>(entrypointStorage.size())};
Expand Down
11 changes: 11 additions & 0 deletions src/windows/common/WSLCContainerLauncher.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ class WSLCContainerLauncher : private WSLCProcessLauncher
void SetDefaultStopSignal(WSLCSignal Signal);
void SetStopTimeout(LONG Timeout);
void SetShmSize(int64_t ShmSize);
void SetHealthCmd(std::string&& HealthCmd);
void SetHealthInterval(int64_t Nanoseconds);
void SetHealthTimeout(int64_t Nanoseconds);
void SetHealthStartPeriod(int64_t Nanoseconds);
void SetHealthRetries(LONG Retries);
void SetNoHealthcheck();
void SetContainerFlags(WSLCContainerFlags Flags);
void SetHostname(std::string&& Hostname);
void SetDomainname(std::string&& Domainame);
Expand Down Expand Up @@ -106,6 +112,11 @@ class WSLCContainerLauncher : private WSLCProcessLauncher
WSLCSignal m_stopSignal = WSLCSignalNone;
std::optional<LONG> m_stopTimeout;
int64_t m_shmSize = 0;
std::optional<std::string> m_healthCmd;
std::optional<int64_t> m_healthInterval;
std::optional<int64_t> m_healthTimeout;
std::optional<int64_t> m_healthStartPeriod;
std::optional<LONG> m_healthRetries;
WSLCContainerFlags m_containerFlags = WSLCContainerFlagsNone;
std::string m_hostname;
std::string m_domainname;
Expand Down
39 changes: 36 additions & 3 deletions src/windows/inc/docker_schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,17 @@ struct NetworkSettings
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(NetworkSettings, Networks);
};

struct HealthConfig
{
std::optional<std::vector<std::string>> Test;
std::optional<std::int64_t> Interval;
std::optional<std::int64_t> Timeout;
std::optional<std::int64_t> StartPeriod;
std::optional<int> Retries;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HealthConfig, Test, Interval, Timeout, StartPeriod, Retries);
};

struct CreateContainer
{
using TResponse = CreatedContainer;
Expand All @@ -306,11 +317,31 @@ struct CreateContainer
std::vector<std::string> Env;
std::map<std::string, EmptyObject> ExposedPorts;
std::map<std::string, std::string> Labels;
std::optional<HealthConfig> Healthcheck;
HostConfig HostConfig;
NetworkingConfig NetworkingConfig;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(
CreateContainer, Image, Cmd, Tty, OpenStdin, StdinOnce, Entrypoint, Env, ExposedPorts, HostConfig, StopSignal, StopTimeout, WorkingDir, User, Hostname, Domainname, Labels, NetworkingConfig);
CreateContainer, Image, Cmd, Tty, OpenStdin, StdinOnce, Entrypoint, Env, ExposedPorts, HostConfig, StopSignal, StopTimeout, WorkingDir, User, Hostname, Domainname, Labels, Healthcheck, NetworkingConfig);
};

struct HealthcheckResult
{
std::string Start;
std::string End;
int ExitCode{};
std::string Output;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HealthcheckResult, Start, End, ExitCode, Output);
};

struct Health
{
std::string Status;
int FailingStreak{};
std::vector<HealthcheckResult> Log;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Health, Status, FailingStreak, Log);
};

struct ContainerInspectState
Expand All @@ -320,8 +351,9 @@ struct ContainerInspectState
int ExitCode{};
std::string StartedAt;
std::string FinishedAt;
std::optional<Health> Health;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerInspectState, Status, Running, ExitCode, StartedAt, FinishedAt);
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerInspectState, Status, Running, ExitCode, StartedAt, FinishedAt, Health);
};

struct ContainerConfig
Expand All @@ -334,8 +366,9 @@ struct ContainerConfig
std::optional<std::vector<std::string>> Entrypoint;
std::optional<std::string> StopSignal;
std::optional<int> StopTimeout;
std::optional<HealthConfig> Healthcheck;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerConfig, Image, User, WorkingDir, Env, Cmd, Entrypoint, StopSignal, StopTimeout);
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerConfig, Image, User, WorkingDir, Env, Cmd, Entrypoint, StopSignal, StopTimeout, Healthcheck);
};

struct InspectMount
Expand Down
36 changes: 34 additions & 2 deletions src/windows/inc/wslc_schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,35 @@ struct InspectMount
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(InspectMount, Type, Source, Destination, ReadWrite);
};

struct HealthcheckResult
{
std::string Start;
std::string End;
int ExitCode{};
std::string Output;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HealthcheckResult, Start, End, ExitCode, Output);
};

struct Health
{
std::string Status;
int FailingStreak{};
std::vector<HealthcheckResult> Log;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Health, Status, FailingStreak, Log);
};

struct ContainerInspectState
{
std::string Status;
bool Running{};
int ExitCode{};
std::string StartedAt;
std::string FinishedAt;
std::optional<Health> Health;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerInspectState, Status, Running, ExitCode, StartedAt, FinishedAt);
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerInspectState, Status, Running, ExitCode, StartedAt, FinishedAt, Health);
};

struct Ulimit
Expand All @@ -69,6 +89,17 @@ struct InspectHostConfig
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(InspectHostConfig, NetworkMode, Memory, NanoCpus, Ulimits);
};

struct HealthConfig
{
std::optional<std::vector<std::string>> Test;
std::optional<std::int64_t> Interval;
std::optional<std::int64_t> Timeout;
std::optional<std::int64_t> StartPeriod;
std::optional<int> Retries;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HealthConfig, Test, Interval, Timeout, StartPeriod, Retries);
};

struct ContainerConfig
{
std::optional<std::vector<std::string>> Env;
Expand All @@ -77,8 +108,9 @@ struct ContainerConfig
std::string User;
std::string WorkingDir;
std::optional<int> StopTimeout;
std::optional<HealthConfig> Healthcheck;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerConfig, Env, Cmd, Entrypoint, User, WorkingDir, StopTimeout);
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerConfig, Env, Cmd, Entrypoint, User, WorkingDir, StopTimeout, Healthcheck);
};

struct InspectEndpointSettings
Expand Down
4 changes: 3 additions & 1 deletion src/windows/service/inc/WSLCShared.idl
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,11 @@ typedef enum _WSLCContainerFlags
WSLCContainerFlagsInit = 4, // Run the container under an init process.
WSLCContainerFlagsPublishAll = 8, // Publish all exposed ports.
WSLCContainerFlagsStopTimeout = 16, // The StopTimeout field is set and should be honored (otherwise StopTimeout is ignored).
WSLCContainerFlagsHealthCheck = 32, // The Health* fields are set and should be honored (otherwise they are ignored).
WSLCContainerFlagsNoHealthCheck = 64, // Disable any container/image-specified health check.
} WSLCContainerFlags;

cpp_quote("#define WSLCContainerFlagsValid (WSLCContainerFlagsRm | WSLCContainerFlagsGpu | WSLCContainerFlagsInit | WSLCContainerFlagsPublishAll | WSLCContainerFlagsStopTimeout)")
cpp_quote("#define WSLCContainerFlagsValid (WSLCContainerFlagsRm | WSLCContainerFlagsGpu | WSLCContainerFlagsInit | WSLCContainerFlagsPublishAll | WSLCContainerFlagsStopTimeout | WSLCContainerFlagsHealthCheck | WSLCContainerFlagsNoHealthCheck)")

cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCContainerFlags);")

Expand Down
6 changes: 6 additions & 0 deletions src/windows/service/inc/wslc.idl
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,12 @@ typedef struct _WSLCContainerOptions

// Ignored unless WSLCContainerFlagsStopTimeout is set in Flags.
LONG StopTimeout;

[unique] LPCSTR HealthCmd;
LONGLONG HealthIntervalNs;
LONGLONG HealthTimeoutNs;
LONGLONG HealthStartPeriodNs;
LONG HealthRetries;
} WSLCContainerOptions;

typedef char WSLCContainerId[WSLC_CONTAINER_ID_LENGTH + 1] ;
Expand Down
6 changes: 6 additions & 0 deletions src/windows/wslc/arguments/ArgumentDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ _(ForwardArgs, "arguments", NO_ALIAS, Kind::Forward, L
_(Gateway, "gateway", NO_ALIAS, Kind::Value, Localization::WSLCCLI_NetworkGatewayArgDescription()) \
_(Gpus, "gpus", NO_ALIAS, Kind::Value, Localization::WSLCCLI_GpusArgDescription()) \
/*_(GroupId, "groupid", NO_ALIAS, Kind::Value, Localization::WSLCCLI_GroupIdArgDescription())*/ \
_(HealthCmd, "health-cmd", NO_ALIAS, Kind::Value, Localization::WSLCCLI_HealthCmdArgDescription()) \
_(HealthInterval, "health-interval", NO_ALIAS, Kind::Value, Localization::WSLCCLI_HealthIntervalArgDescription()) \
_(HealthRetries, "health-retries", NO_ALIAS, Kind::Value, Localization::WSLCCLI_HealthRetriesArgDescription()) \
_(HealthStartPeriod, "health-start-period", NO_ALIAS, Kind::Value, Localization::WSLCCLI_HealthStartPeriodArgDescription()) \
_(HealthTimeout, "health-timeout", NO_ALIAS, Kind::Value, Localization::WSLCCLI_HealthTimeoutArgDescription()) \
_(Help, "help", WSLC_CLI_HELP_ARG, Kind::Flag, Localization::WSLCCLI_HelpArgDescription()) \
_(Hostname, "hostname", L"h", Kind::Value, Localization::WSLCCLI_HostnameArgDescription()) \
_(ImageForce, "force", L"f", Kind::Flag, Localization::WSLCCLI_ImageForceArgDescription()) \
Expand All @@ -83,6 +88,7 @@ _(NetworkName, "network-name", NO_ALIAS, Kind::Positional, L
/*_(NoDNS, "no-dns", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoDNSArgDescription())*/ \
_(NoCache, "no-cache", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoCacheArgDescription()) \
_(NoColor, "no-color", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoColorArgDescription()) \
_(NoHealthcheck, "no-healthcheck", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoHealthcheckArgDescription()) \
_(NoPrune, "no-prune", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoPruneArgDescription()) \
_(NoTrunc, "no-trunc", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoTruncArgDescription()) \
_(ObjectId, "object-id", NO_ALIAS, Kind::Positional, Localization::WSLCCLI_ObjectIdArgDescription()) \
Expand Down
Loading
Loading