开发 Fuchsia 包

几乎所有在 Fuchsia 系统中存在的东西都是一个 Fuchsia 包。不论是否显而易见,Fuchsia 中任何东西都是在以包的形式存在。这份文档将涵盖包驱动的工作流的基础知识,在该工作流中您将 构建 包,并将其推送到任何一个能通过 IP 访问到您的开发主机的 Fuchsia 设备。

必备条件以及概述

开发主机与目标设备必须能通过 IP 互相访问。特别的,必须能够通过 SSH 从开发主机连接到目标设备,而且目标设备必须能够通过 TCP 连接到开发主机的 8083 端口。SSH 连接用于向目标设备下发命令。

开发主机会运行一个简单的静态文件,HTTP 服务器会使该更新对目标设备可用。这个 HTTP 服务器使 Fuchsia 源码的一部分,会自动构建。

目标设备会通过手动运行一些指令来查找开发主机上的更改。当目标设备上的更新系统发觉了这些改变就会从开发主机上运行着的 HTTP 服务器获取新的软件。新软件将一直可用,直到目标设备重新启动。

构建

为了构建一个包含所需代码的包,需要使用包类型构建规则。如果需要为目标包创建一个规则,请查阅 这份文档。某些构建规则类型实际上只是包规则类型的扩展,例如,flutter_app 扩展了包规则。

一旦有可用的恰当的构建规则,目标包就能通过运行 fx build 命令来重新生成。

Connecting host and target

The Fuchsia source contains a simple HTTP server that serves static files. The build generates and serves a TUF file tree.

连接主机与目标设备

目标设备上的更新管理器最初并不知道要去哪里查找更新。为了连接目标设备与开发主机上的 HTTP 服务器就必须将开发主机的 IP 地址告知目标设备上的更新管理器。

当主机上的 HTTP 服务器启动之后,更新管理器会通过调用 fx serve -vfx serve-updates -v 命令得到配置。常用的命令 fx serve 会同时运行引导服务器和更新服务器。在两种情况下,-v 参数会让命令打印出更多的信息,以便于调试。

如果主机成功与目标设备相连,主机的终端中会出现 准备推送包! 这样的信息。

目标设备上的更新管理器会保持之前的配置,知道设备被重新铺设或保存的数据丢失。在目标设备重启之后,主机将会尝试重新配置其更新管理器。

启动包更新

Fuchsia 中的包并非是被「安装」的,它们是按需被缓存的。Fuchsia 中的包主要有两种:

  • 基本包 基本包是一组对正确的系统功能至关重要的软件,必须保持一致。基本包只能通过完全的系统更新获得更新,通常被称为 OTA,后续将对其进行描述。这是使用 fx ota 进行更新的。
  • 临时包 临时包会通过以下两种方式的其中之一来提供给系统,一种是「缓存」构建组,另一种是完全临时。通常用户会通过 fx set 命令并设置诸如 --with //examples/rolldice 这样的参数在构建中将该包配置为临时可用。无论是「缓存」还是完全临时的临时包,都只会在一个组件通过包 URL 加载时才会获得更新。例如,如果一个用户运行 fx run fuchsia-pkg://fuchsia.com/rolldice#meta/rolldice.cmx,rolldice 的最新包会在执行前被缓存。

启动一次 OTA

有时会有很多包改变或内核改变或者系统包发生改变。由于系统运行期间 基本包 无法被改变,因此需要通过 OTA 或 铺设 来获取内核更新或系统包更新。OTA 更新通常要比铺设或刷写设备要快。

fx ota 会要求目标设备从任意可用更新源执行更新。若要通过 OTA 将在开发主机上进行的构建更新到同一局域网上的目标设备,首先需要构建你所需的系统。如果 fx serve [-v] 还没有运行,那么先运行该命令使目标设备将开发主机作为更新源。-v 选项会展示更多关于目标设备所请求的主机文件的信息。如果 -v 选项被打开,在目标设备获取所有新文件时,都会有一系列输出。OTA 结束之后,设备将会重启。

仅需这些命令

  • fx serve -v (为构建-推送和 OTA 启动更新服务器)
    • fx serve-updates -v (只启动更新服务器而不启动引导服务器)
  • fx run <component-url> (每次做出更改时,当你想要运行它时)
  • fx test <component-url> (构建并运行测试)
  • fx ota (触发一次完整系统升级并重启设备)

问题与注意事项

你的硬盘可能会被装满

每次更新的推送都保存在内容寻址的文件系统,blobfs 中。重启之后,更新包可能不再可用,因为它们在 blobfs 中的索引只保存在内存中。Fuchsia 系统目前不收集不可访问或不再使用的包(垃圾收集是最近才提出来的),但我们最终一定会有垃圾回收!

fx gc 命令会重启目标设备并删除所有旧临时软件包来回收空间。

不重启设备的情况下重启服务

如果正被更新的包含有由 Fuchsia 管理的服务,那么该服务可能需要重启。重启是不可取的,因为很慢而且更新的那个包会被恢复到更新前的版本。通常,用户可以终止一个或多个系统中正在运行的组件,既可以要求组件正常终止,也可以通过 fx shell killall <component-name> 命令来强制终止一个组件。一旦重新连接到组件服务,或通过 fx runfx test 调用,包服务器中可用的新版本将在启动前缓存。

在 Fuchsia 环境外打包代码

在 Fuchsia 环境外打包并发布代码是可能的,但是需要做更多的工作。Fuchsia 包结构非常简单。它含有一个描述包内容的元数据文件,在 Fuchsia 包 文档中描述了它的更多细节。元数据文件被添加到 TUF 文件树中,每个内容都以它们的墨克根哈希命名,并放在 TUF 文件树的根的一个目录里,并称之为 「blobs」。