软件交付

Fuchsia 软件通过软件包按需提供给系统。这是 Fuchsia 的核心设计原则(安全性可更新性)的重要组成部分。软件包可以独立更新,并按需交付,就像网页一样。这样一来,即可将漏洞修复程序一次推送到所有 Fuchsia 产品,而无需单独协调各个产品。

软件包不是单个归档文件或映像文件,而是一棵 Binary Large Object (BLOB) 树。树的根是名为“meta.far”的 BLOB,其中包含软件包的元数据,包括包含对其余 BLOB 的引用的“meta/contents”文件。Fuchsia 软件包中的 BLOB 是内容寻址的,这意味着它们是使用其内容的哈希进行引用的。meta.far 本身的内容地址称为软件包哈希

meta.far 包含一个 meta/ 目录,其中至少包含以下两项:

  • meta/package:包含软件包的身份信息(例如名称和版本)的 JSON 文件。
  • meta/contents:将软件包中人类可读的文件名与其内容地址相关联的映射。

显示 Fuchsia 软件包内容的图表,其中包含“meta.far”元数据和一组内容 BLOB。

如果两个或更多软件包共享相同的内容(例如库依赖项或字体资源),则其元数据将指向该资源的相同内容地址。这样,Fuchsia 便无需提取和保存已存在的内容 BLOB,从而优化软件包分发和存储。

托管和分发软件包

软件包托管在基于更新框架 (TUF) 的代码库中。此框架是一项规范,旨在实现安全地分发软件更新。TUF 代码库通过附加到可通过已知可信公钥和私钥进行验证的记录的已签名元数据来保护更新。这意味着,任何 HTTP 服务器都可以托管 TUF 代码库,而无需传输层安全性,包括开发者的工作站!

代码库中的软件包通过采用 fuchsia-pkg 架构的网址进行标识:

fuchsia-pkg://repo-hostname/pkg-name#resource-path
  • repo-hostname:受信任软件包仓库的主机名,例如 fuchsia.com
  • pkg-name:此代码库中软件包的唯一标识符。
  • resource-path:软件包中包含的资源,例如组件清单。

显示如何从 TUF 代码库解析软件包并将其缓存在设备本地的图表。

Fuchsia 设备上的软件请求由软件包解析器处理。软件包解析器会确定系统是否已在本地缓存该软件包。如果没有,解析器会从代码库提取 meta.far 并更新必要的内容 BLOB。

存储软件包

在设备上,软件包 BLOB 存储在内容寻址文件系统中,该文件系统针对一次写入、多次读取的文件进行了优化,称为 blobfs。这样,系统就可以在所有软件包中删除重复项,并使用哈希进行加密验证。Fuchsia 在 blobfs 之上运行 pkg-cache 服务,以便于软件包管理。

一张示意图,展示了如何在“blobfs”(一种内容寻址文件系统,用于删除重复的 BLOB 以便在软件包之间共享)之上构建软件包缓存。

pkg-cache 层会跟踪系统中当前处于活动状态的软件包。在 Fuchsia 中,软件包不会被明确安装或移除。软件是按需提交的,同样,系统也可以通过定期进行垃圾回收,从不再活跃的软件包中回收空间。当 pkg-cache 触发垃圾回收以回收空间时,系统会删除未被任何有效软件包引用的内容 BLOB。

练习:软件包

到目前为止,您已在本 Codelab 中体验了按需向设备分发软件,而您可能还不知道!在本练习中,您将揭开 Fuchsia 设备的神秘面纱,详细了解软件包在 Fuchsia 设备上的传送和存储方式。

重启模拟器

  1. 运行以下命令可关闭您当前打开的所有模拟器实例:

    ffx emu stop --all
  2. 启动新的模拟器实例:

    ffx emu start --headless

    启动完成后,模拟器会输出以下消息并返回:

    Logging to "$HOME/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log"
    Waiting for Fuchsia to start (up to 60 seconds)........
    Emulator is ready.
    

启动本地软件包服务器

运行以下命令启动软件包服务器,并允许模拟器加载软件包:

fx serve

该命令会输出类似于以下内容的输出,表示服务器正在运行,并且已成功将模拟器注册为目标设备:

[serve] Discovery...
[serve] Device up
[serve] Registering devhost as update source
[serve] Ready to push packages!
[serve] Target uptime: 139
[pm auto] adding client: [fe80::5888:cea3:7557:7384%qemu]:46126
[pm auto] client count: 1

检查软件包服务器

fx serve 命令会运行一个本地软件包服务器,用于将软件包提交到目标设备。默认情况下,此服务器在端口 8083 上运行。

打开浏览器,前往 http://localhost:8083。这会加载一个 HTML 页面,其中列出了软件包仓库中当前可用的所有软件包。其中每种都是可分发到设备的软件包。

监控软件包加载

Fuchsia 设备会按需解析和加载软件包。请查看 spinning-square 示例软件包,了解此功能的实际运作方式。

您可以通过设备 shell 提示确认设备上当前是否存在已知软件包:

fx shell pkgctl pkg-status fuchsia-pkg://fuchsia.com/spinning-square-rs
Package in registered TUF repo: yes (merkle=ef65e2ed...)
Package on disk: no

打开一个新终端,然后开始流式传输 pkg-resolver 的设备日志:

ffx log --filter pkg-resolver

此处会显示从软件包服务器加载软件包的所有实例。

在设备 shell 提示符中,尝试解析软件包:

fx shell pkgctl resolve fuchsia-pkg://fuchsia.com/spinning-square-rs

请注意,系统会向 pkg-resolver 的日志输出添加新行:

[pkg-resolver] INFO: attempting to resolve fuchsia-pkg://fuchsia.com/spinning-square-rs as fuchsia-pkg://default/spinning-square-rs with TUF
[pkg-resolver] INFO: resolved fuchsia-pkg://fuchsia.com/spinning-square-rs as fuchsia-pkg://default/spinning-square-rs to 21967ecc643257800b8ca14420c7f023c1ede7a76068da5faedf328f9d9d3649 with TUF

在设备 shell 提示中,再次检查设备上的软件包状态:

fx shell pkgctl pkg-status fuchsia-pkg://fuchsia.com/spinning-square-rs
Package in registered TUF repo: yes (merkle=21967ecc...)
Package on disk: yes

Fuchsia 解析了该软件包,并按需从本地 TUF 代码库加载了该软件包!

浏览软件包元数据

现在,spinning-square 软件包已成功解析,您可以探索软件包内容了。解析完成后,系统会在目标设备上使用内容地址引用该软件包。

在设备 shell 提示符中,使用 pkgctl get-hash 命令确定 spinning-square 的软件包哈希:

fx shell pkgctl get-hash fuchsia-pkg://fuchsia.com/spinning-square-rs

该命令会返回唯一的软件包哈希:

ef65e2ed...

pkgctl open 命令提供完整的软件包哈希以查看软件包内容:

fx shell pkgctl open ef65e2ed...
opening ef65e2ed...
package contents:
/bin/spinning_square
/lib/VkLayer_khronos_validation.so
/lib/ld.so.1
/lib/libasync-default.so
/lib/libbackend_fuchsia_globals.so
/lib/libc++.so.2
/lib/libc++abi.so.1
/lib/libfdio.so
/lib/librust-trace-provider.so
/lib/libstd-e3c06c8874beb723.so
/lib/libsyslog.so
/lib/libtrace-engine.so
/lib/libunwind.so.1
/lib/libvulkan.so
/meta/contents
/meta/package
/meta/spinning-square-rs.cm
/data/fonts/RobotoSlab-Regular.ttf
/meta/fuchsia.abi/abi-revision
/data/vulkan/explicit_layer.d/VkLayer_khronos_validation.json

此部分列出了软件包元数据以及软件包中的每个内容 BLOB。您可以看到可执行文件的 bin/ 条目、共享库依赖项的 lib/ 条目、其他元数据和资源。

后续操作

恭喜!现在,您已经更好地了解了 Fuchsia 的独特之处以及推动此新平台设计的目标。

在下一个单元中,您将详细了解 Fuchsia 开源项目以及用于构建和自定义该系统的工具:

构建 Fuchsia