-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Add support for wslc container restart command #41005
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| /*++ | ||
|
|
||
| Copyright (c) Microsoft. All rights reserved. | ||
|
|
||
| Module Name: | ||
|
|
||
| ContainerRestartCommand.cpp | ||
|
|
||
| Abstract: | ||
|
|
||
| Implementation of command execution logic. | ||
|
|
||
| --*/ | ||
|
|
||
| #include "ContainerCommand.h" | ||
| #include "CLIExecutionContext.h" | ||
| #include "ContainerTasks.h" | ||
| #include "SessionTasks.h" | ||
| #include "Task.h" | ||
|
|
||
| using namespace wsl::windows::wslc::execution; | ||
| using namespace wsl::windows::wslc::task; | ||
| using namespace wsl::shared; | ||
|
|
||
| namespace wsl::windows::wslc { | ||
| // Container Restart Command | ||
| std::vector<Argument> ContainerRestartCommand::GetArguments() const | ||
| { | ||
| return { | ||
| Argument::Create(ArgType::ContainerId, std::nullopt, NO_LIMIT), | ||
| Argument::Create(ArgType::Signal), | ||
| Argument::Create(ArgType::Time), | ||
| }; | ||
| } | ||
|
|
||
| std::wstring ContainerRestartCommand::ShortDescription() const | ||
| { | ||
| return Localization::WSLCCLI_ContainerRestartDesc(); | ||
| } | ||
|
|
||
| std::wstring ContainerRestartCommand::LongDescription() const | ||
| { | ||
| return Localization::WSLCCLI_ContainerRestartLongDesc(); | ||
| } | ||
|
|
||
| // clang-format off | ||
| void ContainerRestartCommand::ExecuteInternal(CLIExecutionContext& context) const | ||
| { | ||
| context | ||
| << ResolveSession | ||
| << RestartContainers; | ||
| } | ||
| // clang-format on | ||
| } // namespace wsl::windows::wslc | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2524,6 +2524,40 @@ void WSLCContainerImpl::DisconnectFromNetwork(LPCSTR NetworkName) | |
| TraceLoggingValue(NetworkName, "NetworkName")); | ||
| } | ||
|
|
||
| void WSLCContainerImpl::Restart(WSLCSignal Signal, LONG TimeoutSeconds) | ||
| { | ||
| // N.B. Snapshot under a brief shared lock and release before composing Stop/Start. | ||
| // m_lock is a non-recursive srwlock; Stop and Start each take it exclusively. | ||
| WSLCContainerState snapshotState{}; | ||
| WSLCContainerFlags snapshotFlags{}; | ||
| { | ||
| auto lock = m_lock.lock_shared(); | ||
| snapshotState = m_state; | ||
| snapshotFlags = m_containerFlags; | ||
| } | ||
|
|
||
| // Refuse --rm before stopping: Stop -> OnStopped would delete the container. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Locking wise, I don't think that we can drop the lock here unfortunately, otherwise another stop / start operation could arrive before we complete, which would leak to weird states |
||
| THROW_HR_WITH_USER_ERROR_IF( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is the behavior we want: Docker supports restarting containers when --rm is set. |
||
| HRESULT_FROM_WIN32(ERROR_INVALID_STATE), | ||
| Localization::MessageWslcContainerRestartAutoRemove(m_id), | ||
| WI_IsFlagSet(snapshotFlags, WSLCContainerFlagsRm)); | ||
|
|
||
| THROW_HR_IF_MSG( | ||
| HRESULT_FROM_WIN32(ERROR_INVALID_STATE), | ||
| snapshotState != WslcContainerStateRunning && snapshotState != WslcContainerStateExited && snapshotState != WslcContainerStateCreated, | ||
| "Cannot restart container '%hs', state %i", | ||
| m_id.c_str(), | ||
| snapshotState); | ||
|
|
||
| if (snapshotState == WslcContainerStateRunning) | ||
| { | ||
| // N.B. If the container exits on its own before Stop acquires m_lock, Stop no-ops on Exited. | ||
| Stop(Signal, TimeoutSeconds, /*Kill*/ false); | ||
| } | ||
|
|
||
| Start(WSLCContainerStartFlagsNone, nullptr); | ||
| } | ||
|
|
||
| HRESULT WSLCContainer::GetLabels(WSLCLabelInformation** Labels, ULONG* Count) | ||
| try | ||
| { | ||
|
|
@@ -2553,6 +2587,15 @@ try | |
| } | ||
| CATCH_RETURN(); | ||
|
|
||
| HRESULT WSLCContainer::Restart(_In_ WSLCSignal Signal, _In_ LONG TimeoutSeconds, _In_opt_ IWarningCallback* WarningCallback) | ||
| try | ||
| { | ||
| // N.B. WarningCallback is ambient here so EMIT_USER_WARNING reaches the client from both the Stop and Start phases. | ||
| WSLCExecutionContext context(&m_session, WarningCallback); | ||
| return CallImpl(&WSLCContainerImpl::Restart, Signal, TimeoutSeconds); | ||
| } | ||
| CATCH_RETURN(); | ||
|
|
||
| HRESULT WSLCContainer::InterfaceSupportsErrorInfo(REFIID riid) | ||
| { | ||
| return riid == __uuidof(IWSLCContainer) || riid == __uuidof(IWSLCCompatContainer) ? S_OK : S_FALSE; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.