The component configuration page introduces how components can be configured on Fuchsia, and describes different situations that require component configuration .
This page introduces the different configuration mechanisms that Fuchsia provides, talks about their strengths and weaknesses and provides guidance on which mechanism to use in which situation.
Structured configuration
Structured configuration is a modern, ergonomic, and flexible configuration system provided by the Component Framework. Structured configuration is integrated with many Fuchsia tools including ffx, inspect, and product assembly and it should be your first choice in most cases.
A component developer uses structured configuration by defining configuration keys in the component's manifest, each with a name and datatype. The system guarantees that values will be provided for all of these configuration keys when the component is started. Libraries are auto-generated to easily read configuration values at runtime. Components need not care what part of the system supplied a structured configuration value and need not handle missing configuration.
Structured configuration values can be provided through a range of different paths, such as:
- Package build rules. Configuration values set by build rule are included in the same package as the component. The configuration is fixed at build time so can be verified during release signing.
- Realm builder. Realm builder integration lets tests easily set configuration values. The two main use cases are to verify configurable behavior and to change configuration to aid testability.
- Product assembly. Product assembly lets the platform define configuration keys whose values are supplied by the product. Product integrators supply values in their product configuration and these are built into the component package where they can be verified during release signing.
- Development overrides. This ffx tool lets developers change configuration at runtime on engineering builds, for example to use pre-release features.
RFC-0127 described several other ways to specify structured configuration values, but these have not yet been built pending near-term use cases. If your use case requires any of these features, please comment on the tracking bug linked below for the feature:
- Vbmeta (https://fxbug.dev/42178359). This would let signed configuration be modified for a release without building a new image.
- Parent component (https://fxbug.dev/42178351). This would let a component specify configuration for children in a dynamic collection as it creates those children. This requires a consistent definition of the configuration between the two components so may only be supported between components in the same image or package.
- Fleet and enterprise management (https://fxbug.dev/42055769). This would let structured configuration be used for incremental rollouts, running A/B experiments and enterprise policy enforcement, similar to the experiment systems in other large platforms.
Structured configuration definition for a component is local to that component. There is no global "configuration version" and the system does not provide guarantees on forwards or backwards compatibility across versions of a component — compatibility is left to the component developer. Therefore, structured configuration is not currently suitable as a means of communication between components that may have been built against different configuration versions.
Structured configuration is very flexible and works in most situations, however there are configuration problems for which structured configuration is not the best solution:
- Configuration values must be consistent across a large number of different components. Structured configuration keys are defined locally in a component's manifest. Product assembly may be used to set consistent configuration values across a few different components but this brings maintainability challenges and does not scale well. If configuration values must be consistent across a large number of different components, package-based configuration or service-based configuration are better solutions.
- Large configuration. When configuration gets very large, say over several kilobytes, the tools that structured configuration provides to set and view configuration values become inconvenient. The implementation of structured configuration does not prioritize efficient handling of large values. Package-based configuration is a better solution for large configuration data.
- Configuration that changes frequently at runtime. A component receives its structured configuration values as it launches, meaning a component instance must be restarted to pick up new configuration. Service-based configuration is a better solution for configuration that must change frequently at runtime.
- Configuration that is set by end users. Unlike developers, end users need a user interface to control configuration. This user interface means that the UI component, the component being configured, and the localization database all need to agree on the definition of the configuration and therefore the configuration must be defined centrally in some versioned artifact. Service-based configuration configuration is a better solution for configuration that is controlled by end users.
Package-based configuration
Package-based configuration supports configuration data that is fixed at release time by building data files into a package and letting the component read those files. The same package can be routed to several different components and the configuration files can be arbitrarily large.
Package based configuration is generally less ergonomic than structured configuration; the files must be manually opened and parsed, the component may need to handle missing or malformed configuration, and there is no integration with standard tooling to test, debug, or introspect configuration.
Package based configuration does not work well for the following problems:
- Configuration needs to be altered at runtime. Comment on the tracking bugs above for dynamic configuration support in structured configuration and/or use service-based configuration instead.
There are three different variants of package-based configuration based on which package is used to store the configuration:
Global (aka "config_data") package configuration
A single global config_data
package contains configuration data
for many different components. With the data for each component being added
using the "config_data" build rule. This global package was the only way to use
packaged-based configuration in CFv1 but it is inflexible and cumbersome in CFv2
since the config-data directory must be manually routed through the component
topology.
Users of config_data should migrate to either structured configuration or domain/in-package configuration, both of which provide better ergonomics and more flexibility.
Domain package configuration
The developers of the components in a domain can define their own configuration data package and route its directories to the components they control. Unlike global package configuration, this mechanism can be used across different build systems and petals.
In-package configuration
Configuration files may also be placed in the same package as the component they configure. This ensures that the configuration will be distributed with the component and does not require complex and brittle routing. However, it also means that the configuration cannot be changed without repackaging the component. More details are provided in the guide on providing data files to components.
Packages contents are stored in blobfs, a content addressed file system which de-duplicates blobs. This means if multiple packages include an identical configuration blob, only one copy will be stored.
Service-based configuration
Fuchsia components may be written to collect, maintain, and distribute
configuration data for a domain over FIDL. A good example is the Fuchsia
platform’s settings service that maintains various user
settings such as the locale: the settings service maintains the state of these
user settings across power cycles and exposes fuchsia.settings
FIDL protocols
that other components may use to read the current configuration data or request
a change in configuration data.
Service-based configuration can be very flexible and powerful but introducing a server component is generally more work than the other options and incurs a higher runtime cost. Service-based configuration should only be used when this additional cost adds value.
The component can potentially use several different inputs to determine the correct configuration. For example: business logic to validate and combine client requests, settings collected from some server, or default configuration values provided through some other mechanism such as structured configuration. Service-based configuration works well when configuration must be shared across a wide range of clients because the configuration is formally defined and versioned by the FIDL interface used to deliver it. Service-based configuration also works well when configuration potentially changes frequently.
Service-based configuration does not work well for the following problems:
- Large Configuration. Configuration is delivered by FIDL messages which are limited by the size of a zircon channel write. Although a FIDL protocol could work around this by splitting configuration into chunks or sending a VMO this would harm the client simplicity and explicit definition that are service-based configuration's strength. Packaged-based configuration is a better solution when working with large configuration.