This commit is contained in:
yao-msft 2025-12-09 21:13:52 -08:00
parent 5487790459
commit 04441d56d8
1 changed files with 80 additions and 3 deletions

View File

@ -19,6 +19,36 @@ Abstract:
#include "ServiceProcessLauncher.h"
#include "WslCoreFilesystem.h"
namespace
{
constexpr const char* nerdctlPath = "/usr/bin/nerdctl";
HRESULT TransferFileContent(HANDLE from, HANDLE to)
{
const DWORD FILE_BUFFER_SIZE = 4 * 1024 * 1024; // 4MB buffer
std::vector<char> buffer;
buffer.resize(FILE_BUFFER_SIZE);
DWORD bytesRead = 0;
DWORD bytesWritten = 0;
do
{
RETURN_LAST_ERROR_IF(!ReadFile(from, buffer.data(), FILE_BUFFER_SIZE, &bytesRead, nullptr));
if (bytesRead == 0)
{
break;
}
RETURN_LAST_ERROR_IF(!WriteFile(to, buffer.data(), bytesRead, &bytesWritten, nullptr) || bytesRead != bytesWritten);
} while (bytesWritten > 0);
return S_OK;
}
}
using namespace wsl::windows::common;
using wsl::windows::service::wsla::WSLASession;
using wsl::windows::service::wsla::WSLAVirtualMachine;
@ -199,19 +229,66 @@ void WSLASession::CopyDisplayName(_Out_writes_z_(bufferLength) PWSTR buffer, siz
}
HRESULT WSLASession::PullImage(LPCSTR ImageUri, const WSLA_REGISTRY_AUTHENTICATION_INFORMATION* RegistryAuthenticationInformation, IProgressCallback* ProgressCallback)
try
{
return E_NOTIMPL;
RETURN_HR_IF_NULL(E_POINTER, ImageUri);
std::lock_guard lock{m_lock};
ServiceProcessLauncher launcher{nerdctlPath, {nerdctlPath, "pull", ImageUri}};
auto result = launcher.Launch(*m_virtualMachine.Get()).WaitAndCaptureOutput();
RETURN_HR_IF_MSG(E_FAIL, result.Code != 0, "Pull image failed: %hs", launcher.FormatResult(result).c_str());
return S_OK;
}
CATCH_RETURN();
HRESULT WSLASession::LoadImage(ULONG ImageHandle, IProgressCallback* ProgressCallback)
try
{
return E_NOTIMPL;
HANDLE imageFileHandle = ULongToHandle(ImageHandle);
RETURN_HR_IF(E_INVALIDARG, INVALID_HANDLE_VALUE == imageFileHandle);
// Directly invoking "nerdctl load" will immediately return with failure
// "stdin is empty and input flag is not specified".
// TODO: Change the workaround when nerdctl has a fix.
ServiceProcessLauncher launcher{"/bin/sh", {"/bin/sh", "-c", "cat | /usr/bin/nerdctl load"}, {}, ProcessFlags::Stdin | ProcessFlags::Stdout | ProcessFlags::Stderr};
auto loadProcess = launcher.Launch(*m_virtualMachine.Get());
auto loadProcessStdin = loadProcess.GetStdHandle(0);
RETURN_IF_FAILED(TransferFileContent(imageFileHandle, loadProcessStdin.get()));
loadProcessStdin.reset();
auto result = loadProcess.WaitAndCaptureOutput();
RETURN_HR_IF_MSG(E_FAIL, result.Code != 0, "Load image failed: %hs", launcher.FormatResult(result).c_str());
return S_OK;
}
CATCH_RETURN();
HRESULT WSLASession::ImportImage(ULONG ImageHandle, LPCSTR ImageName, IProgressCallback* ProgressCallback)
try
{
return E_NOTIMPL;
HANDLE imageFileHandle = ULongToHandle(ImageHandle);
RETURN_HR_IF(E_INVALIDARG, INVALID_HANDLE_VALUE == imageFileHandle);
RETURN_HR_IF_NULL(E_POINTER, ImageName);
ServiceProcessLauncher launcher{nerdctlPath, {nerdctlPath, "import", "-", ImageName}, {}, ProcessFlags::Stdin | ProcessFlags::Stdout | ProcessFlags::Stderr};
auto importProcess = launcher.Launch(*m_virtualMachine.Get());
auto importProcessStdin = importProcess.GetStdHandle(0);
RETURN_IF_FAILED(TransferFileContent(imageFileHandle, importProcessStdin.get()));
importProcessStdin.reset();
auto result = importProcess.WaitAndCaptureOutput();
RETURN_HR_IF_MSG(E_FAIL, result.Code != 0, "Import image failed: %hs", launcher.FormatResult(result).c_str());
return S_OK;
}
CATCH_RETURN();
HRESULT WSLASession::ListImages(WSLA_IMAGE_INFORMATION** Images, ULONG* Count)
{