WSL/Building in OBS
Appx 文件内容
通过 Microsoft Store 发行 Windows 应用的格式是 Appx 包。Appx 包实际上是一个带有额外元数据和加密签名的 zip 文件。在 WSL 的上下文中,Appx 包的内容如下
openSUSE-Tumbleweed.exe [1] install.tar.gz [2] images/icon.ico [3] Assets/*.png [4] Resources.pri [4] AppxManifest.xml [5] AppxBlockMap.xml [6] [Content_Types].xml [6] AppxSignature.p7x [7]
- [1] 启动器
- 一个基于 Microsoft 的 示例实现 的 EXE 文件。该程序安装在 Windows 上,并在安装后启动以准备发行版。之后可以直接调用它来启动给定发行版的 WSL “chroot” 实例。
- [2] openSUSE 系统的压缩 tarball
bash、zypper、yast 等都在其中
- [3-4] Appx 安装程序的资源
Windows 为安装 Appx 包提供了一些通用的用户界面。该安装程序的资源可以在 Assets 目录中找到。Resources.pri 文件是一种带有资源索引的二进制格式。目前只能在 Windows 上使用 Visual Studio 创建它。
- [5] 安装程序的元数据
- 清单文件向通用的 Appx 安装程序提供一些数据。例如,应用程序名称、供应商、体系结构和图标。该文件中的 Publisher 属性对于 加密签名 来说很重要。有关此文件格式的文档可以在 Microsoft 上找到。
- [6] 安装程序的元数据
- 这些文件也用于安装程序,但由 appx 工具自动创建。
- [7] Authenticode 签名
- Appx 包的加密签名
在 OBS 中构建 WSL Appx 包
构建 WSL appx 包以及包含在 app 中的 Windows EXE 文件遵循常见的 openSUSE 标准。这意味着组件在 OBS 中以完全自动、无人值守和可重现的方式构建。
WSL app 本身以及 OBS 中密切相关的工具的开发项目是 Virtualization:WSL。 MinGW 工具链在基本发行版中可用,并在 OBS 的 windows:mingw 项目空间中维护。
下图概述了构建过程中各个组件之间的关系
Kiwi 目前不支持创建 appx 包,因此该过程包含一些技巧才能使构建成为可能。一旦 Kiwi 支持 appx,该过程将得到简化。
- WSL-Distrolauncher
- 启动器使用 gcc 交叉编译器编译,该编译器在 Linux 上生成 Windows 二进制文件 (mingw64-cross-gcc)。
- fb-util-for-appx
- 使用 fb-util-for-appx 工具创建 Appx 包和其中的 AppxBlockMap.xml。该工具的签名功能未被使用。OBS 会自行完成签名
- kiwi-images-wsl
- 一个常规的 kiwi 镜像构建。它将 Linux rpm 安装到 chroot 环境中,并将所有内容打包到 tarball 中。
- containment-rpm-docker
- 一个特殊的技巧,用于将 kiwi 生成的 Linux 系统 tarball 包装到 rpm 包中,以便它可以作为其他 rpm 的依赖项使用。
- wsl-appx
- 使用 fb-util-for-appx,此包获取重新打包的 kiwi 生成的 tarball、一些 appx 特定元数据和资源(如图标)以及 WSL-Distrolauncher,以生成可以安装在 Windows 上的实际 appx 文件。
生成的 appx 文件将由 OBS 使用存储在 OBS 内部的证书自动签名。
特殊项目设置
在 OBS 术语中,构建镜像(即 kiwi)与构建包(即 rpmbuild)之间存在差异。每个项目中的存储库必须配置其构建类型。默认情况下是构建包。按照惯例,官方项目中的 kiwi 镜像是在 images 存储库中构建的,该存储库从 standard 存储库中获取包。Kiwi 镜像被视为已发布的最终产品。包不能依赖镜像。但是,为了生成 appx 镜像,wsl-appx 包实际上需要 kiwi 生成的镜像。因此,containment-rpm-docker 技巧将镜像包装在 rpm 中,以便 wsl-appx 可以 BuildRequire。为了使之工作,openSUSE:Factory:WSL 中的存储库顺序相反。因此,包含 wsl-appx 的 standard 存储库实际上会针对 images 构建,以便访问由 kiwi-images-wsl 生成的 rpm。
在 开发项目 中,使用了不同的解决方案,以避免第三个存储库。那里使用了一个特殊的 聚合包,将 kiwi 生成的 rpm 从 images 存储库复制回 standard 存储库。
签名
为了使 Windows 接受 Appx 包,需要对其进行加密签名。默认情况下,Windows 仅接受在提交到商店期间由 Microsoft 进行的签名。因此,不可能完全自动生成可以在开箱即用的 Windows 机器上安装的 Appx 包。
虽然可以使用自定义证书对 Appx 包进行签名,并将这些证书作为受信任的根证书导入到 Windows。因此,就像 rpm 一样,使用 openSUSE 构建服务构建的 Appx 包将由项目特定的密钥签名。包含该密钥的证书然后可以 导入到 Windows 以信任它。
必须特别注意证书的主题。证书的主题必须与 AppxManifest.xml 文件中的 Publisher 属性匹配。常规 OBS 项目具有一个自动生成的证书,其中包含项目特定的主题。例如
$ osc signkey --sslcert Virtualization:WSL|openssl x509 -noout -subject subject=CN = Virtualization OBS Project, emailAddress = Virtualization@build.opensuse.org
因此,需要根据目标项目调整 AppxManifest.xml。wsl-appx 包负责处理此问题。
打算提交到 Microsoft Store 的 Appx 包需要 Microsoft 分配的特殊发布者值。原始证书和密钥与该值由 Microsoft 保留,因此 OBS 无法使用与 Windows Store 相同的证书对 Appx 包进行签名。为了至少拥有可用于上传到商店的 AppxManifest.xml 文件,用于构建官方 openSUSE WSL Appx 包的 OBS 项目使用具有与 Microsoft 证书匹配的主题的专门制作的证书。将 OBS 构建的 Appx 包上传到商店时,Microsoft 仅替换数字签名。
发布流程
虽然实际的包位于 openSUSE:Factory 中,但由于前面提到的特殊存储库设置,镜像是在 openSUSE:Factory:WSL 中构建的。WSL 镜像构建在 Factory snapshot 存储库(也称为 Tumbleweed)之上。这是为了确保创建的 WSL app 包仅包含已经通过 Tumbleweed 质量控制的包。但是,这意味着对任何 WSL 相关包的任何更改仅在发布 TW 后才会对 WSL 镜像产生影响。
一旦构建了新的 WSL appx 包,该镜像将自动复制到 openSUSE:Factory:WSL:ToTest 并同步到 openQA 进行测试。如果所有测试都通过,则该构建将发布到 下载服务器。
未来工作流程
下图显示了一旦 kiwi 获得生成 appx 文件本身的支持后的工作流程
在新工作流程中,不再需要 containment-rpm-docker 技巧。现在,wsl-appx 包不再生成 appx 文件,而是打包 kiwi 将使用的资源和元数据。

