使用 Fuchsia 软件包进行开发

Fuchsia 系统上存在的几乎所有内容都是紫色软件包。无论是非常明显,您在紫红色上看到的几乎所有东西都是包装中的。本文档将介绍软件包驱动型工作流的基础知识,在这种工作流中,您将构建软件包并将其推送到可通过 IP 从开发主机访问的 Fuchsia 设备。

前提条件和概览

主机和目标必须能够通过 IP 进行通信。具体而言,必须能够从开发主机通过 SSH 连接到目标设备,并且目标设备必须能够通过 TCP 连接到端口 8083 上的开发主机。SSH 连接用于向目标设备发出命令。

开发主机将运行一个简单的静态文件 HTTP 服务器,该服务器会将更新提供给目标使用。此 HTTP 服务器是 Fuchsia 源代码的一部分,是自动构建的。

系统会通过一系列手动运行的命令指示目标在开发主机上查找更改。当目标上的更新系统发现这些更改时,它会从主机上运行的 HTTP 服务器提取新软件。在目标重新启动之前,新软件将一直可用。

建筑

如需构建包含所需代码的软件包,可以使用软件包类型构建规则。如果需要为目标软件包创建其中任何一个,请参阅相关参考页面

在适当的构建规则可用后,可以通过运行 fx build 重新生成目标软件包。

检查软件包

Fuchsia 附带 far 工具用于处理软件包归档。完成 Fuchsia build 后,可使用 far 程序创建、列出、转储或提取软件包归档:

$ fx host-tool far
...
Usage: far <command> ...
  where <command> is create, list, cat, extract, or extract-file.

例如,如需列出软件包的内容,请观察其 meta.far 是否包含 meta/contents

$  fx host-tool far list --archive=out/default/obj/third_party/sbase/sed/meta.far
meta/contents
meta/fuchsia.abi/abi-revision
meta/package

meta/contents 文件会将软件包面向用户的文件名映射到这些文件的 Merkle 根目录,从而允许查看哪些文件属于它:

$ fx host-tool far cat --archive=out/default/obj/third_party/sbase/sed/meta.far --file=meta/contents
bin/sed=6a07c6a584dadc9700ad6904ad920704592f706b4b8f55ec6fc736391588a1ef
lib/ld.so.1=2debd7e1b8542e3a9004794a4417a55d27c928030277364e597cc3e6f80f5407
lib/libasync-default.so=55482d52d72b63a0f51d20991ea49fa939b2559d4a7002606bc9e50e42af64e4
lib/libbackend_fuchsia_globals.so=8da42bd2ad7fc246a6ecba016753fa4e9b0b7f6c685e22da4de997888fd18b06
lib/libc++.so.2=e4145c4b3fd40b6d5371a5f21b46fb965d7c82d4b8bb438c9e94254ea58d8cba
lib/libc++abi.so.1=1b5b77954855602b64b877c37defc450d8741d4bb95bd60427cbf234561090e2
lib/libfdio.so=1e47faf9e335206ca73a253dece42a5d537912fc6abceadd0a06ea1462aa8e33
lib/libunwind.so.1=dffab54d807a4352e088529a7a2112b651042bf511e7df7d2adca40aaec77c86

正在连接主机和目标

Fuchsia 来源包含一个传送静态文件的简单 HTTP 服务器。build 会生成并提供 TUF 文件树。

目标上的更新代理最初不知道在哪里查找更新。如需将目标上的代理连接到在开发主机上运行的 HTTP 服务器,必须告知该代理开发主机的 IP 地址。启动主机 HTTP 服务器,并通过调用 fx serve -v 来配置更新代理。fx serve:用于运行更新服务器,通常是用户使用的服务。建议使用 -v,因为该命令将输出更多输出,这可能有助于调试。如果主机成功连接到目标,您会在主机上的 shell 中看到消息 Ready to push packages!

目标上的更新代理将保持配置状态,直到恢复该代理或持久性数据丢失。当目标重新启动时,主机将尝试重新配置更新代理。

触发软件包更新

Fuchsia 中的软件包不是“安装”的,而是会根据需要缓存。Fuchsia 系统上有两个软件包集合:

  • 基本 base 软件包集是一组对系统正常运行至关重要的软件,必须保持一致。当使用 --with-base 标志将软件包提供给 fx set 时,Fucsia 构建系统会将软件包分配给 base。这组软件只能通过执行整个系统更新(通常称为 OTA)进行更新,如下所述。这是使用 fx ota 进行更新的。

  • cacheuniverse 软件包集中包含的临时软件软件包是临时软件,可按需提供更新。当使用 --with 标志将软件包提供给 fx set 时,Fucsia 构建系统会将软件包分配给 universe。每当解析软件包网址时,软件都会将临时软件更新到最新可用版本。

触发 OTA

有时,很多软件包发生更改,内核可能会发生变化,或者系统软件包中可能有一些更改。若要获取系统软件包中的内核更改或变更,必须使用 OTA 或 pave,因为基础软件包在系统运行时是不可变的。OTA 更新通常比平铺或刷写设备更快。

fx ota 命令会要求目标设备从它可用的任何可用更新源执行更新。如需将在开发主机上创建的 build 通过 OTA 方式更新到同一 LAN 中的目标,请先构建所需的系统。如果 fx serve [-v] 尚未运行,请启动它,以便目标可以将开发主机用作更新来源。-v 选项将显示有关目标从主机请求的文件的更多信息。如果使用了 -v 标志,那么在目标检索所有新文件时,应该会有一系列输出。OTA 完成后,设备将重新启动。

仅命令

  • fx serve -v(用于同时为 build-push 和 ota 运行更新服务器)
  • fx test <component-url>(用于构建和运行测试)
  • fx ota(用于触发完整的系统更新并重新启动)

问题和注意事项

你可以填满磁盘

推送的每个更新都存储在内容寻址文件系统 blobfs 中。重新启动后,更新软件包可能不可用,因为在 blobfs 中找到这些软件包的索引仅保存在 RAM 中。系统目前不会对无法访问或不再使用的软件包进行垃圾回收(回收垃圾回收是一项最新创新!),但最终会这样做。

fx gc 命令会重新启动目标设备,然后从设备中移除所有旧的临时软件,从而释放空间。

在不重启的情况下重启

如果要更新的软件包托管由 Fuchsia 管理的服务,则该服务可能需要重启。重新启动是不可取的,因为重新启动速度很慢,并且软件包将还原为在设备上铺垫的版本。通常,用户可以通过请求正常终止或使用 ffx component stop <component-moniker> 强制停止组件来终止系统上正在运行的一个或多个组件。重新连接到组件服务或通过 ffx component startfx test 调用后,软件包服务器中可用的新版本会在发布之前进行缓存。

Fuchsia 树外部的包装代码

可以打包和推送位于 Fuchsia 树之外的代码,但需要完成更多工作。Fuchsia 软件包格式非常简单。它包含一个描述软件包内容的元数据文件,Fuchsia 软件包文档中对该文件进行了更详细的介绍。元数据文件会添加到 TUF 文件树中,所有内容都以其 Merkle 根哈希命名,并放在 TUF 文件树根目录下的名为“blob”的目录中。