Developing with Fuchsia packages

This document explains the basics of Fuchsia product development using Fuchsia packages.

Overview

A Fuchsia package is a hierarchical collection of files and resourcesthat provides one or more programs, components or services to a Fuchsia system. Whether it is immediately apparent or not, almost everything you see on Fuchsia lives in a Fuchsia package.

During Fuchsia product development, if you want to make new software available to your target Fuchsia device, you can build a Fuchsia package to include changes and publish it to a local package server running on your development host machine. Then the Fuchsia device will download the package and update the software.

In this setup, your development host machine runs a simple static file HTTP server that makes Fuchsia packages available to the target device. This HTTP server (which is referred to as the Fuchsia package server) is part of the Fuchsia source code and is built automatically when the fx build command is run.

Fuchsia target devices are usually configured to look for changes on the Fuchsia package server. When the update system on a target device sees changes, it fetches the new package from the package server. Once the package is downloaded, the new software in the package becomes available on the target device.

Prerequisites

Your development host machine and Fuchsia target device must be able to communicate over TPC/IP. In particular, it must be possible to establish an SSH connection from the development host machine to the target device. This SSH connection is used to issue commands to the target device.

Building packages

For building a package containing your code in the Fuchsia source checkout, you need to specify a package build rule. For more details on adding build rules for a package, see Fuchsia build system.

Once an appropriate build rule is added, run the following command to generate your package:

fx build

Inspecting packages

Fuchsia comes with the ffx tool to work with package archives. After the completion of a Fuchsia build (fx build), you can use the ffx package archive command to create, list, dump or extract package archives, for example:

ffx package archive list

The ffx package archive list command example below lists the contents of a package named meta.far in the ~/fuchsia/out/default/obj/third_party/sbase/sed_pkg/ directory:

$ ffx package archive list ~/fuchsia/out/default/obj/third_party/sbase/sed_pkg/meta.far
+-------------------------------+
| NAME                          |
+===============================+
| meta/contents                 |
+-------------------------------+
| meta/fuchsia.abi/abi-revision |
+-------------------------------+
| meta/package                  |
+-------------------------------+

Notice that this meta.far package contains a file named meta/contents. The meta/contents file maps the package's user-facing filenames to the merkle root of those files, for example:

$ ffx package archive cat ~/fuchsia/out/default/obj/third_party/sbase/sed_pkg/meta.far meta/contents
bin/sed=361c6e3a027cf38af0d53e1009ef3b3448f4aeb60270910a116396f5ec8eccba
lib/ld.so.1=c8ec55a14590e7e6f06f311d632744012f85084968d98a335c778f29207caa14
lib/libc++.so.2=d8a45259c74cf65c1f8470ac043c6459403fdd0bbf676092ba82f36451e4e571
lib/libc++abi.so.1=f12b37c2b9bfb43fbe33d446794a6ffeee1452b16b7c8d08b3438f3045d1f19a
lib/libfdio.so=9834d890adedc8e532899a673092271e394458e98e6cee049cb78f5a95372b11
lib/libunwind.so.1=89e5dee07ff8d2a03c58d524d8d832e79c70dcb81508f8a83c6fbf07e1539e83

For more details on Fuchsia packages and their contents, see Structure of a package.

Managing package servers

Virtually all software running on a Fuchsia system is collected into Fuchsia packages. Beyond the base packages that comprise the foundation of the Fuchsia platform, additional packages can be downloaded from the Fuchsia package server. The Fuchsia package server is an HTTP(S) server managing Fuchsia packages using TUF (The Update Framework). This framework uses cryptographically signed BLOBs to securely distribute updated packages to devices running Fuchsia.

For more information on how to start, stop, and list Fuchsia package servers running on your development host machine, see the following guides:

Connecting host and target

The Fuchsia source checkout (fuchsia.git) contains the Fuchsia package server, a simple HTTP server that serves static files. And a Fuchsia build generates and serves a TUF file tree to the server.

The update agent on a target Fuchsia device does not initially know where to look for updates. To connect the update agent on the target to the package server running on the development host machine, the target must be told the IP address of the development host machine.

By default, the Fuchsia package server automatically registers itself with the default target. This behavior can be disabled by using the --no-device option when starting the server.

The following commands are used for managing package repositories on target devices:

To start the Fuchsia package server and configure the update agent on target devices, you can run the following command (or simply fx serve):

fx serve -v

The fx serve command runs the package server and is often what developers use. However, the -v option is recommended because it allows the command to print more output, which can help you with debugging. If the packager server connects successfully to the target devices, the command prints the Ready to push packages! message in the shell on the development host machine.

The update agent on a target device remains configured until it is re-flashed. The Fuchsia package server attempts to reconfigure the update agent when the target device is rebooted.

Triggering package updates

In Fuchsia, packages are not "installed" but they are cached on an as-needed basis.

There are two collections of packages in a Fuchsia ecosystem:

  • Base: The base package set is a group of software critical to proper system function that must remain congruent. The Fuchsia build system assigns packages to base when they are provided to the fx set command using the --with-base flag.

    This type of software can only be updated by performing a whole system update, typically referred to as an OTA (Over The Air) update, which is performed using the fx ota command.

  • Ephemeral software: Packages included in the cache or universe package set are ephemeral software. These updates are delivered on demand. The Fuchsia build system assigns packages to universe when they are provided to the fx set command using the --with flag.

    Ephemeral software is updated to the latest available versions when new packages are fetched to the target.

The following commands are used for publishing Fuchsia packages and updating target devices:

  • fx serve: Run the Fuchsia package server locally for both build-push and OTA to target devices.
  • fx ota: Trigger a full system update and reboot on target devices.
  • fx test: Build and run tests for testing target devices.

Triggering an OTA

Sometimes there may be many packages changed. For instance, the kernel may change or there may be changes in the system package. To introduce kernel changes or changes in the system package to target devices, an OTA or flashing is required since base packages are immutable for the runtime of a system. (An OTA update will usually be faster than flashing the device.)

To trigger an OTA update to your target devices, run the following command:

fx ota

The fx ota command asks the target device to perform an update from any of the update sources available to it. To OTA update a build on the development host machine to a target device on the same LAN, you first need to build the system (fx build). Once the build is finished, if the fx serve [-v] command isn't already running on your development host machine, run the command so the target device can use the Fuchsia package server as an update source. The -v option prints more information about the files that the target device is requesting from the package server. With the -v option, there will be a flurry of output as the target device retrieves all the new files.

After completing the OTA, the target device will reboot.

Issues and considerations

Consider the following issues that can occur while working with Fuchsia packages.

You can fill up your disk

Every update pushed is stored in the content-addressed file system, blobfs. Following a reboot, the updated packages may not be available because the index that locates them in blobfs is only held in RAM. The system currently does not garbage collect inaccessible or no-longer-used packages (having garbage to collect is a recent innovation!), but will eventually.

The fx gc command will reboot the target device and then evict all old ephemeral software from the device, freeing up space.

Restarting without rebooting

If the package being updated hosts a service managed by Fuchsia, that service may need to be restarted. Rebooting is undesirable because both it is slow and the package will revert to the version flashed on the device. Typically a developer can terminate one or more running components on the system, either by asking the component to terminate gracefully, or by forcefully stopping the component using the ffx component stop command. Upon reconnection to the component services, or by invocation via ffx component start or fx test, new versions available in the package server will be cached before launch.

Packaging code outside the Fuchsia tree

Packaging and pushing code that lives outside the Fuchsia tree is possible, but will require more work. The Fuchsia package format is quite simple. It consists of a metadata file describing the package contents, which is described in more detail in the Fuchsia package documentation. The metadata file is added to a TUF file tree and each of the contents are named after their merkle root hash and put in a directory at the root of the TUF file tree called blobs.