mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-10 17:47:59 -06:00
Implement open
This commit is contained in:
parent
02abdcd90e
commit
f7c8778c83
@ -31,11 +31,6 @@ WSLAContainer::WSLAContainer(WSLAVirtualMachine* parentVM, ServiceRunningProcess
|
||||
{
|
||||
}
|
||||
|
||||
const std::string& WSLAContainer::Name() const noexcept
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::string& WSLAContainer::Image() const noexcept
|
||||
{
|
||||
return m_image;
|
||||
|
||||
@ -35,7 +35,6 @@ public:
|
||||
IFACEMETHOD(GetInitProcess)(_Out_ IWSLAProcess** process) override;
|
||||
IFACEMETHOD(Exec)(_In_ const WSLA_PROCESS_OPTIONS* Options, _Out_ IWSLAProcess** Process, _Out_ int* Errno) override;
|
||||
|
||||
const std::string& Name() const noexcept;
|
||||
const std::string& Image() const noexcept;
|
||||
|
||||
static Microsoft::WRL::ComPtr<WSLAContainer> Create(const WSLA_CONTAINER_OPTIONS& Options, WSLAVirtualMachine& parentVM);
|
||||
|
||||
@ -228,16 +228,23 @@ try
|
||||
|
||||
THROW_IF_FAILED(container.CopyTo(__uuidof(IWSLAContainer), (void**)Container));
|
||||
|
||||
m_containers.emplace_back(std::move(container));
|
||||
m_containers.emplace(containerOptions->Name, std::move(container));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
HRESULT WSLASession::OpenContainer(LPCWSTR Name, IWSLAContainer** Container)
|
||||
HRESULT WSLASession::OpenContainer(LPCSTR Name, IWSLAContainer** Container)
|
||||
try
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
std::lock_guard lock{m_lock};
|
||||
auto it = m_containers.find(Name);
|
||||
RETURN_HR_IF_MSG(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), it == m_containers.end(), "Container not found: '%hs'", Name);
|
||||
|
||||
it->second.CopyTo(__uuidof(IWSLAContainer), (void**)Container);
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
HRESULT WSLASession::ListContainers(WSLA_CONTAINER** Containers, ULONG* Count)
|
||||
try
|
||||
@ -250,11 +257,11 @@ try
|
||||
auto output = wil::make_unique_cotaskmem<WSLA_CONTAINER[]>(m_containers.size());
|
||||
|
||||
size_t index = 0;
|
||||
for (const auto& e : m_containers)
|
||||
for (const auto& [name, container] : m_containers)
|
||||
{
|
||||
THROW_HR_IF(E_UNEXPECTED, strcpy_s(output[index].Image, e->Image().c_str()) != 0);
|
||||
THROW_HR_IF(E_UNEXPECTED, strcpy_s(output[index].Name, e->Name().c_str()) != 0);
|
||||
THROW_IF_FAILED(e->GetState(&output[index].State));
|
||||
THROW_HR_IF(E_UNEXPECTED, strcpy_s(output[index].Image, container->Image().c_str()) != 0);
|
||||
THROW_HR_IF(E_UNEXPECTED, strcpy_s(output[index].Name, name.c_str()) != 0);
|
||||
THROW_IF_FAILED(container->GetState(&output[index].State));
|
||||
index++;
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ public:
|
||||
|
||||
// Container management.
|
||||
IFACEMETHOD(CreateContainer)(_In_ const WSLA_CONTAINER_OPTIONS* Options, _Out_ IWSLAContainer** Container) override;
|
||||
IFACEMETHOD(OpenContainer)(_In_ LPCWSTR Name, _In_ IWSLAContainer** Container) override;
|
||||
IFACEMETHOD(OpenContainer)(_In_ LPCSTR Name, _In_ IWSLAContainer** Container) override;
|
||||
IFACEMETHOD(ListContainers)(_Out_ WSLA_CONTAINER** Images, _Out_ ULONG* Count) override;
|
||||
|
||||
// VM management.
|
||||
@ -63,7 +63,7 @@ private:
|
||||
Microsoft::WRL::ComPtr<WSLAVirtualMachine> m_virtualMachine;
|
||||
std::wstring m_displayName;
|
||||
std::filesystem::path m_storageVhdPath;
|
||||
std::vector<Microsoft::WRL::ComPtr<WSLAContainer>> m_containers;
|
||||
std::map<std::string, Microsoft::WRL::ComPtr<WSLAContainer>> m_containers;
|
||||
std::mutex m_lock;
|
||||
|
||||
// TODO: Add container tracking here. Could reuse m_lock for that.
|
||||
|
||||
@ -284,7 +284,7 @@ interface IWSLASession : IUnknown
|
||||
|
||||
// Container management.
|
||||
HRESULT CreateContainer([in] const struct WSLA_CONTAINER_OPTIONS* Options, [out] IWSLAContainer** Container);
|
||||
HRESULT OpenContainer([in] LPCWSTR Name, [out] IWSLAContainer** Container);
|
||||
HRESULT OpenContainer([in] LPCSTR Name, [out] IWSLAContainer** Container);
|
||||
HRESULT ListContainers([out, size_is(, *Count)] struct WSLA_CONTAINER** Images, [out] ULONG* Count);
|
||||
|
||||
// Create a process at the VM level. This is meant for debugging.
|
||||
|
||||
@ -1154,30 +1154,50 @@ class WSLATests
|
||||
}
|
||||
};
|
||||
|
||||
// Create a stuck container.
|
||||
WSLAContainerLauncher launcher(
|
||||
"debian:latest", "test-container-1", "/bin/cat", {}, {}, ProcessFlags::Stdin | ProcessFlags::Stdout | ProcessFlags::Stderr);
|
||||
{
|
||||
// Validate that the container list is initially empty.
|
||||
expectContainerList({});
|
||||
|
||||
auto container = launcher.Launch(*session);
|
||||
// Create a stuck container.
|
||||
WSLAContainerLauncher launcher(
|
||||
"debian:latest", "test-container-1", "/bin/cat", {}, {}, ProcessFlags::Stdin | ProcessFlags::Stdout | ProcessFlags::Stderr);
|
||||
|
||||
// Verify that the container is in running state.
|
||||
VERIFY_ARE_EQUAL(container.State(), WslaContainerStateRunning);
|
||||
expectContainerList({{"test-container-1", "debian:latest", WslaContainerStateRunning}});
|
||||
auto container = launcher.Launch(*session);
|
||||
|
||||
// Kill the container init process and expect it to be in exited state.
|
||||
auto initProcess = container.GetInitProcess();
|
||||
initProcess.Get().Signal(9);
|
||||
// Verify that the container is in running state.
|
||||
VERIFY_ARE_EQUAL(container.State(), WslaContainerStateRunning);
|
||||
expectContainerList({{"test-container-1", "debian:latest", WslaContainerStateRunning}});
|
||||
|
||||
// Wait for the process to actually exit.
|
||||
wsl::shared::retry::RetryWithTimeout<void>(
|
||||
[&]() {
|
||||
initProcess.GetExitState(); // Throw if the process hasn't exited yet.
|
||||
},
|
||||
std::chrono::milliseconds{100},
|
||||
std::chrono::seconds{30});
|
||||
// Kill the container init process and expect it to be in exited state.
|
||||
auto initProcess = container.GetInitProcess();
|
||||
initProcess.Get().Signal(9);
|
||||
|
||||
// Expect the container to be in exited state.
|
||||
VERIFY_ARE_EQUAL(container.State(), WslaContainerStateExited);
|
||||
expectContainerList({{"test-container-1", "debian:latest", WslaContainerStateExited}});
|
||||
// Wait for the process to actually exit.
|
||||
wsl::shared::retry::RetryWithTimeout<void>(
|
||||
[&]() {
|
||||
initProcess.GetExitState(); // Throw if the process hasn't exited yet.
|
||||
},
|
||||
std::chrono::milliseconds{100},
|
||||
std::chrono::seconds{30});
|
||||
|
||||
// Expect the container to be in exited state.
|
||||
VERIFY_ARE_EQUAL(container.State(), WslaContainerStateExited);
|
||||
expectContainerList({{"test-container-1", "debian:latest", WslaContainerStateExited}});
|
||||
|
||||
// Open a new reference to the same container.
|
||||
wil::com_ptr<IWSLAContainer> sameContainer;
|
||||
VERIFY_SUCCEEDED(session->OpenContainer("test-container-1", &sameContainer));
|
||||
|
||||
// Verify that the state matches.
|
||||
WSLA_CONTAINER_STATE state{};
|
||||
VERIFY_SUCCEEDED(sameContainer->GetState(&state));
|
||||
VERIFY_ARE_EQUAL(state, WslaContainerStateExited);
|
||||
}
|
||||
|
||||
// Verify that trying to open a non existing container fails.
|
||||
{
|
||||
wil::com_ptr<IWSLAContainer> sameContainer;
|
||||
VERIFY_ARE_EQUAL(session->OpenContainer("does-not-exist", &sameContainer), HRESULT_FROM_WIN32(ERROR_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user