blob: b8d043a4e78e91991cefbc08c0aceae38331a2ca [file] [log] [blame] [view]
# Fuchsia packages
A Fuchsia package is a hierarchical collection of files that provides one or more programs,
components or services to a Fuchsia system. A Fuchsia package is a term representing a
unit of distribution, though unlike many other package systems, that unit is composed of
parts and is not a single binary `BLOB`.
Note: For more information on components, see
[Introduction to the Fuchsia component framework](/docs/concepts/components/v2/introduction.md).
Some packages are present on a Fuchsia system at startup, and
additional packages can be downloaded from a Fuchsia package server in `BLOB`s.
The Fuchsia package server is an HTTP(S) server. These `BLOB`s are uniquely defined by a Merkle
root. A `BLOB` is named after its content, using the
[Fuchsia Merkle Root](merkleroot.md) algorithm. If two `BLOB`s have the same content,
they have the same name. As a result, each `BLOB` has a unique identifier and is
written to persistent storage using this Merkle
root as a key. This process is done to eliminate duplication of `BLOB`s that
may exist between packages. For example, a shared library which exists in
multiple packages is only stored once on the device.
The package server serves as a root of trust as it validates the authenticity of
each package.
Packages can also declare dependencies on named
[subpackage][glossary.subpackage]s, creating a hierarchy of nested packages.
Build rules link a package with the build target of each subpackage. At build
time, the package build tool records the subpackages in the parent package's
metadata, mapping each subpackage name to its package hash (the `BLOB` id that
identifies the subpackage). This ensures the list of subpackages and the
internals of each subpackage cannot change without also changing the Merkle
(package hash) of the parent.
_Subpackages enable:_
* Encapsulated dependencies (packages are inherently "package trees")
* Isolated `/pkg` directories (grouped components don't need to merge their
files, libraries, and metadata into a single shared namespace)
* Assured dependency resolution (system and build tools ensure subpackages
always "travel with" their packages)
For more information on packaging components with their dependencies using
Subpackages, see [Subpackaging components].
Note: To understand how components and packages work together in Fuchsia,
see [Fuchsia's software model](/docs/concepts/software_model.md).
## Types of packages
The packages that comprise the Fuchsia operating system are categorized into
three groups, which affect how they are managed:
Note: To understand how these packages work in a Fuchsia build, see
[Dependency sets](/docs/development/build/build_system/boards_and_products.md#dependency_sets)
* [Base packages](#base-packages)
* [Cached packages](#cached-packages)
* [Universe packages](#universe-packages)
### Base packages {#base-packages}
Note: Base packages are part of the system assembly process.
There is no way to determine if a package is a base package.
These are the packages that are part of the foundation of the Fuchsia
operating system and are considered critical for security and the system.
Resolving a package which is in base on a running Fuchsia system always
returns the version that is on the device, and not a new version which
may exist on a package server. However, base packages can be updated as part of
the [OTA process](/docs/concepts/packages/ota.md).
Since these packages are immutable for the runtime of a
system, these packages must be updated with
[`fx ota`](https://fuchsia.dev/reference/tools/fx/cmd/ota) which triggers an
over-the-air (OTA) update.
### Cached packages {#cached-packages}
These are packages on the device which are not part of base. These
packages exist when the device is flashed or paved, so these packages
are usable if the device boots without a network connection. Cached packages
are updated during the resolution process if a different package is available
on the package server. These packages are not updated during a system update,
but are updated ephermerally.
Fuchsia can also evict cached packages on a running system to free up
resources based on runtime resource demands.
### Universe packages {#universe-packages}
These are packages that exist on the package server, but not on the device.
## Structure of a package {#structure-of-a-package}
In most cases, a package in Fuchsia is a collection of `BLOB`s, which at a
minimum contains one content-addressed `BLOB` named [`meta.far`](#meta-far).
Note: For more information on the Fuchsia archive format (FAR), see
[Fuchsia archive format (FAR)](/docs/development/source_code/archive_format.md).
In Fuchsia, you build a package with the `ffx package build` command or the
legacy `pm` tool, which both exist in the `//tools/` directory of the
Fuchsia IDK.
Essentially, a package is a tree of zero or more content-addressed items.
A package contains the following:
* [`meta.far`](#meta-far)
* [`BLOB`s outside of `meta/`](#outside-blobs)
### `meta.far` {#meta-far}
Note: For more information on the Fuchsia archive format (FAR), see
[Fuchsia archive format (FAR)](/docs/development/source_code/archive_format.md).
The package metadata archive, `meta.far`, contains metadata about
a package, presented as the `meta/` directory. `meta.far` has a
[merkleroot](merkleroot.md) which in practical terms is also known as the
merkleroot of a package.
The `meta/` directory of a package contains at minimum two files:
* `meta/package`
The package identity file. This is a JSON file that contains the name and
version of the package.
* `meta/contents`
The contents file. This file is created by the `ffx package build` command,
(or the legacy `pm update` and `pm build` commands). This file maps the
user-facing file names of a package to the Merkle root of those files.
If the package declares subpackages, the `meta/` directory also contains:
* `meta/fuchsia.pkg/subpackages`
The subpackages file. This is a JSON file that contains the name and version
of each declared subpackage. From the perspective of the parent package, the
subpackage name is used as a relative package URL when resolving the
subpackage.
Package build tools traverse subpackage references (declared through build
dependency declarations and package manifest files that reference other
package manifest files for each subpackage) to compute the version (package
hash) of each subpackage and generate the `subpackages` file.
Additionally, the `meta/` directory can contain files such as a component manifest.
For more information on component manifests, see
[Component manifests](/docs/concepts/components/v2/component_manifests.md).
### `BLOB`s outside of `meta/` {#outside-blobs}
Most files of a package exist outside of the `meta/`directory and each are a `BLOB`.
For example, these files can be like the following:
* `bin/foo`
* `lib/libfdio.so`
* `data/mydata.db`
## Identification of a package
Every package in Fuchsia is identified by a `package-url`.
Note: For more information about [Fuchsia package URLs](/docs/concepts/packages/package_url.md).
### Absolute package URLs
An absolute Fuchsia package URL identifies a system-addressable package, without
requiring any additional context, and looks like the following:
```
fuchsia-pkg://{{ '<var>' }}repository{{ '</var>' }}/{{ '<var>' }}package-name{{ '</var>' }}?hash={{ '<var>' }}package-hash{{ '</var>' }}#{{ '<var>' }}resource-path{{ '</var>' }}
```
Fuchsia has different intereprations of `fuchsia-pkg` URL depending on which parts of the URL are
present.
* If the repository, package, and resource parts are present, then the URL
identifies the indicated resource within the package.
* If only the repository and package parts are present, then the URL identifies
the indicated package itself.
* If only the repository parts are present, then the URL identifies the
indicated repository itself.
The package parts can express varying degrees of specificity. At minimum the
package name must be present, optionally followed by the package hash.
If the package hash is missing, the package resolver fetches the resources
from the newest revision of the package variant available to the client.
### Relative package URLs
A relative Fuchsia package URL identifies a subpackage given previously loaded
package (or subpackage) as "context". The repository and parent package are
implicit, and the subpackage name is used to look up the package hash in the
parent package's `"meta/fuchsia.pkg/subpackages"` file. (The package hash
cannot be overridden). A relative package URL looks like the following:
```
{{ '<var>' }}package-name{{ '</var>' }}#{{ '<var>' }}resource-path{{ '</var>' }}
```
As with absolute package URLs, the resource path may or may not be included.
[Subpackaging components]: /docs/concepts/components/v2/subpackaging.md
[glossary.subpackage]: /docs/glossary/README.md#subpackage