WSL C SDK 镜像推送:PushImageOptions 完整配置指南
2026/9/10 17:08:35 网站建设 项目流程

WSL C# SDK 镜像推送:PushImageOptions 完整配置指南

【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL

本文围绕 WSL(Windows Subsystem for Linux)容器 SDK(WSLC)C# 投影中的PushImageOptions配置类展开,讲解如何将 WSL 容器会话内的镜像推送至远程镜像仓库,涵盖参数语义、底层调用链、错误处理与异步进度用法。读完本文,你将掌握 WSL C# SDK 中PushImageOptions的完整配置与实战调用方式,并理解其与底层 C/WinRT 实现的对应关系。

一、概述:PushImageOptions 是什么

PushImageOptions是 WSL 容器 SDK 中用于配置"镜像推送(Push)"操作的参数对象。在 WSL 容器工作流中,开发者通常先在本地构造、拉取或导入镜像,随后需要将其推送到 Docker Registry 等远程仓库以便分发或备份,此时即可使用Session.PushImage/Session.PushImageAsync配合PushImageOptions完成。

该类的定位与PullImageOptionsTagImageOptions同属 SDK 的"设置类(Settings Classes)"一族,相关的类索引见 doc/docs/api-reference/csharp/settings-classes/index.md。

类定义与构造

根据 doc/docs/api-reference/csharp/settings-classes/pushimageoptions.md,该类在 C# 投影中的定义为:

public sealed class PushImageOptions { public PushImageOptions(string image, string registryAuth); public string Image { get; set; } public string RegistryAuth { get; set; } }

要点:

  • 构造时需同时提供imageregistryAuth两个参数;
  • ImageRegistryAuth均提供可读写的属性;
  • 类是sealed(密封)的,不可被继承,表明其作为纯数据承载对象使用。

与底层 API 的对应关系

PushImageOptions并非凭空设计,它在 SDK 各语言层有一一对应的实现:

  • C# 层(本文主角)src/windows/WslcSDK/csharp/下的投影类,作为 WinRT 投影暴露给 C# 开发者;
  • WinRT 层src/windows/WslcSDK/winrt/PushImageOptions.h与 PushImageOptions.cpp 中的winrt::Microsoft::WSL::Containers::implementation::PushImageOptions
  • MIDL 定义src/windows/WslcSDK/winrt/wslcsdk.idl中的runtimeclass PushImageOptions,它是 WinRT 投影的契约来源:
    runtimeclass PushImageOptions { PushImageOptions(String image, String registryAuth); String Image; String RegistryAuth; };
  • C API 层WslcPushImageOptions结构体,定义见 doc/docs/api-reference/c/structures/wslcpushimageoptions.md,结构体比 C# 类多出progressCallbackprogressCallbackContext两个用于进度回调的字段。

二、字段详解

2.1 Image(镜像引用)

Image指定要推送的镜像引用。它必须包含完整的仓库地址(registry 主机 + 仓库路径 + 标签),例如:

var pushOptions = new PushImageOptions("registry.example.com/demo:latest", authToken);

镜像引用通常形如registry.example.com/demo:latest,其中:

片段说明示例
registry 主机镜像仓库服务器地址(含端口可省略)registry.example.com
仓库路径仓库与命名空间demo
标签版本标签,缺省一般为latestlatest

实战提示:推送前通常先用TagImage将本地镜像打上带 registry 前缀的标签,再执行推送。测试代码 test/windows/WslcSdkWinRTTests.cpp 中正是先TagImage(imageName, registryRepo, tag),再构造带 registry 前缀的PushImageOptions进行推送,并在推送后用DELETE_IMAGE_ON_SCOPE_EXIT清理临时镜像。

2.2 RegistryAuth(注册表认证)

RegistryAuth指定访问私有镜像仓库所需的认证信息。从 C API 注释可知,该字段语义是Base64 编码的X-Registry-AuthHTTP 请求头值(见 doc/docs/api-reference/c/structures/wslcpushimageoptions.md)。也就是说,推送私有仓库镜像时,需要把 Docker 风格的认证令牌(token)或用户名/密码构造为 registry auth 头,再进行 Base64 编码后传入。

SDK 内部在src/windows/WslcSDK/wslcsdk.cpp中提供了BuildRegistryAuthHeader辅助逻辑,用于在认证后生成合法的 registry auth 头字符串,说明该字段承载的是完整的鉴权头载荷,而非裸的用户名密码。

三、构造约束与校验规则

从 PushImageOptions.cpp 的实现可以总结出以下严格的参数校验规则:

3.1 空值校验(E_INVALIDARG)

无论是构造函数还是属性 setter,imageregistryAuth不允许为空字符串

// 以下均会抛出异常: new PushImageOptions("", authToken); // Image cannot be empty new PushImageOptions("repo/img:tag", ""); // Registry auth cannot be empty

对应 WinRT 实现抛出的异常为hresult_invalid_argument(HRESULTE_INVALIDARG),错误信息分别为"Image cannot be empty""Registry auth cannot be empty"。测试代码 test/windows/WslcSdkWinRTTests.cpp 中亦有对应验证:

VERIFY_THROWS_HR(m_defaultSession.PushImageAsync(WSLCSDK::PushImageOptions(L"", winrt::to_hstring(xRegistryAuth))).get(), E_INVALIDARG);

3.2 应用后锁定(E_ILLEGAL_STATE_CHANGE)

PushImageOptions在把参数转换为底层结构体(ToStruct())之后,属性值即被锁定。若在选项已被应用后再尝试修改ImageRegistryAuth,会抛出hresult_illegal_state_change,错误信息为"Cannot change value after options have been applied"。这保证了在一次推送操作中参数的一致性,避免调用中途静默篡改配置。

因此推荐的最佳实践是:先完整构造并配置好PushImageOptions,再调用Session.PushImage/PushImageAsync,不要在调用后复用并修改同一个选项对象。

四、与 Session 的协作:从选项到推送完成

4.1 底层调用链

PushImageOptions最终通过Session的推送方法发挥作用。以异步版本为例,Session.cpp 中PushImageAsync的实现流程为:

  1. 空指针检查:options为 null 时抛出hresult_error(E_POINTER, "Options for push cannot be null")
  2. EnsureStarted():确保 Session 已启动,否则操作无法执行;
  3. GetStruct(options):将 WinRT 对象转换为底层WslcPushImageOptions结构体(即触发ToStruct()与应用后锁定);
  4. 挂接progressCallbackprogressCallbackContext(异步版本将进度事件桥接到 WinRT 的IAsyncActionWithProgress<ImageProgress>);
  5. 调用 C APIWslcPushSessionImage(ToHandle(), &pushOptions, errorMessage.put())(见 wslcsdk.cpp),并在失败时抛出携带错误消息的 HRESULT 异常。

同步版本PushImage的流程与此一致,只是不挂接进度回调。C API 的签名定义在 doc/docs/api-reference/c/image-apis/wslcpushsessionimage.md:

STDAPI WslcPushSessionImage(_In_ WslcSession session, _In_ const WslcPushImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage);

C API 层同样会校验optionsoptions->imageoptions->registryAuth不为空(空则返回E_INVALIDARG),随后调用内部运行时internalType->session->PushImage(...)

4.2 同步与异步两种调用方式

// 同步方式:阻塞直到推送完成或抛异常 session.PushImage(pushOptions); // 异步方式:返回带进度的 IAsyncActionWithProgress<ImageProgress> var progress = session.PushImageAsync(pushOptions);

异步版本可配合Progress<ImageProgress>接收推送过程中的阶段事件。进度事件类型ImageProgresswslcsdk.idl中定义,包含IdStatusCurrentBytesTotalBytes等字段,可用于展示推送的拉取/下载/校验/解压等阶段状态。

4.3 完整调用示例

综合以上内容,一次完整的镜像推送流程如下:

// 1. 构造推送选项(image 与 registryAuth 均不能为空) var pushOptions = new PushImageOptions("registry.example.com/demo:latest", authToken); // 2. 通过已启动的 Session 执行推送(异步 + 进度) var progress = session.PushImageAsync(pushOptions); progress.Progress = (asyncInfo, imageProgress) => { Console.WriteLine($"Image {imageProgress.Id}: {imageProgress.Status}, " + $"{imageProgress.CurrentBytes}/{imageProgress.TotalBytes} bytes"); }; await progress;

五、常见错误与排查

场景表现原因与对策
imageregistryAuth为空抛出E_INVALIDARG("Image/Registry auth cannot be empty")构造参数不合法,检查是否传入了空字符串
选项对象为 null 传入 Session抛出E_POINTER("Options for push cannot be null")未实例化选项,先new PushImageOptions(...)
Session 未启动抛出无效状态相关错误先调用Session.Start()再推送
推送不存在的镜像测试中以E_FAIL捕获(如推送"does-not-exist"确认镜像已在会话内存在(先用PullImage/ImportImage/TagImage准备)
修改已应用的选项抛出E_ILLEGAL_STATE_CHANGE不要复用已用于推送的选项对象,重新构造新实例
私有仓库认证失败推送报错确认registryAuth是 Base64 编码的X-Registry-Auth头值

依据 test/windows/WslcSdkWinRTTests.cpp 中的相关测试,空镜像参数(L"")会按E_INVALIDARG捕获,而推送不存在的镜像则按E_FAIL处理,可作为异常语义的参考。

六、小结

PushImageOptions是 WSL 容器 SDK C# 投影中面向"镜像推送"场景的配置对象,核心只有两个字段:Image(目标镜像引用)与RegistryAuth(Base64 编码的 registry 认证头)。使用时需注意三点:两个字段均不可为空;选项在应用(调用Session.PushImage/PushImageAsync)后即锁定;推送前确保 Session 已启动且镜像已在会话中。其实现横跨 MIDL 契约(wslcsdk.idl)、WinRT 包装(PushImageOptions.cpp)与 C API(wslcsdk.cpp),并得到 WinRT 测试(WslcSdkWinRTTests.cpp)的覆盖验证,是理解 WSL 容器镜像分发链路的一个典型切入点。

【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询