Software delivery

Fuchsia software is delivered on demand to the system through packages. This is a critical component to Fuchsia's core design principles of security and updatability. Packages can be updated independently and delivered on demand, like a web page. This enables a vulnerability patch to be pushed to all Fuchsia products at once without the need for individual product coordination.

A package is not a single archive or image file, but rather a tree of Binary Large Objects (BLOBs). The root of the tree is a BLOB called "meta.far" which contains metadata for the package, including a "meta/contents" file which contains references to the rest of the BLOBs. The BLOBs inside Fuchsia packages are content-addressed, meaning they are referenced using a hash of their contents. The content address of the meta.far itself is known as the package hash.

The meta.far contains a meta/ directory with at least the following two items:

  • meta/package: JSON file containing the package's identity information such as name and version.
  • meta/contents: A map of the human-readable file names in a package to their content addresses.

Diagram showing the contents of a Fuchsia package consisting of "meta.far"
  metadata and a collection of content BLOBs.

If two or more packages share the same content (such as a library dependency, or font resource), their metadata will point to the same content address for that resource. This enables Fuchsia to optimize package distribution and storage by avoiding the need to fetch and save a content BLOB that already exists.

Hosting and serving packages

Packages are hosted in repositories based on The Update Framework (TUF). This framework is a specification designed to enable secure delivery of software updates. TUF repositories secure updates through signed metadata attached to records that are verifiable against known trusted public and private keys. This means that any HTTP server can serve a TUF repository without the need for transport-level security, including a developer's workstation!

Packages within a repository are identified by a URL with the fuchsia-pkg scheme:

fuchsia-pkg://repo-hostname/pkg-name#resource-path
  • repo-hostname: Hostname of a trusted package repository, such as fuchsia.com.
  • pkg-name: Unique identifier for the package in this repository.
  • resource-path: Resource contained within the package, such as a component manifest.

Diagram showing how packages are resolved from a TUF repository and cached
 locally on the device.

Requests for software on a Fuchsia device are handled by the package resolver. The package resolver determines if the system already has the package cached locally. If not, the resolver fetches the meta.far from the repository and updates the necessary content BLOBs.

Storing packages

On the device, package BLOBs are stored in a content-addressable filesystem optimized for write-once, read-often files called blobfs. This allows them to be de-duplicated across all packages and cryptographically verified using their hash. Fuchsia runs the pkg-cache service on top of blobfs to facilitate package management.

Diagram illustrating how the package cache is built on top of "blobfs" — a
 content-addressable filesystem that de-duplicates BLOBs allowing them to be
 shared between packages.

The pkg-cache layer tracks which packages in the system are currently active. Packages are not explicitly installed or removed in Fuchsia. Software is delivered on demand and likewise space can be reclaimed from packages that are no longer active through periodic garbage collection. When pkg-cache triggers garbage collection to reclaim space, content BLOBs not referenced by any active package are deleted.

Exercise: Packages

So far in this codelab, you've been experiencing on demand software delivery to your device and you probably didn't even know it! In this exercise, you'll peel back the covers and see the details of how packages are delivered and stored on a Fuchsia device.

Restart the emulator

  1. Run the following command to close any emulator instances you currently have open:

    ffx emu stop --all
  2. Start a new emulator instance:

    ffx emu start --headless

    When startup is complete, the emulator prints the following message and returns:

    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.
    

Start a local package server

Run the following command to start a package server and enable the emulator to load software packages:

fx serve

The command prints output similar to the following, indicating the server is running and has successfully registered the emulator as a target device:

[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

Examine the package server

The fx serve command runs a local package server used to deliver packages to the target devices. By default, this server runs at on port 8083.

Open a browser to http://localhost:8083. This loads an HTML page listing all the packages currently available in the package repository. Each one of these are packages that can be delivered to the device.

Monitor package loading

Packages are resolved and loaded on demand by a Fuchsia device. Take a look at this in action with the spinning-square example package.

From the device shell prompt, you can confirm whether a known package is currently on the device:

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

Open a new terminal and begin streaming the device logs for pkg-resolver:

ffx log --filter pkg-resolver

This shows all the instances where a package was loaded from the package server.

From the device shell prompt, attempt to resolve the package:

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

Notice the new lines added to the log output for 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

From the device shell prompt, check the package status again on the device:

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 resolved the package and loaded it from the local TUF repository on demand!

Explore package metadata

Now that the spinning-square package has successfully been resolved, you can explore the package contents. Once resolved, the package is referenced on the target device using its content address.

From the device shell prompt, use the pkgctl get-hash command to determine the package hash for spinning-square:

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

The command returns the unique package hash:

ef65e2ed...

Provide the full package hash to the pkgctl open command to view the package contents:

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

This lists the package metadata and each of the content BLOBs in the package. You can see bin/ entries for executables, lib/ entries for shared library dependencies, additional metadata and resources.

What's Next?

Congratulations! You now have a better understanding of what makes Fuchsia unique and the goals driving this new platform's design.

In the next module, you'll learn more about the Fuchsia open source project and the tools used to build and customize the system:

Building Fuchsia