blob: 2675fa637cd47f3fa21753ae08d19b79186a7d22 [file] [log] [blame] [view]
# Developing with Fuchsia packages
This document explains the basics of Fuchsia product development using
[Fuchsia packages][packages].
## Overview
A [Fuchsia package][fuchsia-packages] 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][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][pkg-doc].
Once an appropriate build rule is added, run the following command to
generate your package:
```posix-terminal
fx build
```
## Inspecting packages
Fuchsia comes with the `ffx` tool to work with package archives. After the
completion of a [Fuchsia build][fuchsia-build] (`fx build`), you can use the
[`ffx package archive`][ffx-package-archive] command to create, list, dump or
extract package archives, for example:
```posix-terminal
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:
```none {:.devsite-disable-click-to-copy}
$ 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:
```none {:.devsite-disable-click-to-copy}
$ 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][pkg-struct].
## 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][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:
* [Start package servers][start-package-servers]
* [List running package servers][list-package-servers]
* [Stop running package servers][stop-package-servers]
## Connecting host and target
The [Fuchsia source checkout][fuchsia-source] (`fuchsia.git`) contains the Fuchsia
package server, a simple HTTP server that serves static files. And a Fuchsia build
generates and serves a [TUF][TUF-home] 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:
* [`ffx target repository list`][ffx-target-repo-list]: Inspect registered
package repositories on a target device.
* [`ffx target repository register`][ffx-target-repo-register]: Register a new
package repository or update an existing entry.
* [`ffx target repository deregister`][ffx-target-repo-deregister]: Remove a
package repository registration from a target device.
To start the Fuchsia package server and configure the update agent on target
devices, you can run the following command (or simply `fx serve`):
```posix-terminal
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`][fx-serve]: Run the Fuchsia package server locally for both
build-push and OTA to target devices.
* [`fx ota`][fx-ota]: Trigger a full system update and reboot on target
devices.
* [`fx test`][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:
```posix-terminal
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][gc] 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`][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][pkg-struct] 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`.
<!-- Reference links -->
[packages]: /docs/concepts/packages/README.md
[fuchsia-packages]: /docs/concepts/packages/package.md
[pkg-struct]: /docs/concepts/packages/package.md#structure-of-a-package
[TUF-home]: https://theupdateframework.github.io "TUF Homepage"
[pkg-doc]: /docs/development/build/build_system/fuchsia_build_system_overview.md
[fuchsia-build]: /docs/get-started/learn/build/build-system.md
[ffx-target-repo-list]: https://fuchsia.dev/reference/tools/sdk/ffx#ffx_target_repository_list
[ffx-target-repo-register]: https://fuchsia.dev/reference/tools/sdk/ffx#ffx_target_repository_register
[ffx-target-repo-deregister]: https://fuchsia.dev/reference/tools/sdk/ffx#ffx_target_repository_deregister
[fuchsia-package-server]: /docs/concepts/packages/fuchsia_package_server.md
[ffx-package-archive]: https://fuchsia.dev/reference/tools/sdk/ffx#ffx_package_archive
[fx-serve]: https://fuchsia.dev/reference/tools/fx/cmd/serve
[fx-ota]: https://fuchsia.dev/reference/tools/fx/cmd/ota
[fx-test]: https://fuchsia.dev/reference/tools/fx/cmd/test
[start-package-servers]: /docs/development/tools/ffx/workflows/start-package-servers.md
[list-package-servers]: /docs/development/tools/ffx/workflows/list-package-servers.md
[stop-package-servers]: /docs/development/tools/ffx/workflows/stop-package-servers.md
[fuchsia-source]: /docs/get-started/get_fuchsia_source.md
[gc]: /docs/concepts/packages/garbage_collection.md
[ffx-component-stop]: /docs/development/tools/ffx/workflows/start-a-component-during-development.md#stop-a-component