blob: 2a3288e561619aa1f6e8aa80fa9ba7d6920f5625 [file] [log] [blame] [view]
# Component Structured Configuration Reference
This page provides detailed information about Structured Configuration's behavior
and implementation. For guides on using Structured Configuration, see:
* [Structured Configuration introductory guide][sc-guide]
* [Assembling Structured Configuration from product configuration][assembling-sc]
* [Evolving Structured Configuration schemas][evolving-sc]
* [Verifying configuration values][verifying-sc]
[sc-guide]: /docs/development/components/configuration/structured_config.md
[assembling-sc]: /docs/development/components/configuration/assembling_structured_config.md
[evolving-sc]: /docs/development/components/configuration/evolving_structured_config.md
[verifying-sc]: /docs/development/verification/build_integration.md#verifying-structured-configuration-files
## Lifecycle
Configuration values are resolved when a component is
[created][component-create].
[component-create]: /docs/concepts/components/v2/introduction.md#lifecycle
## Resolution precedence
[Component configuration][component-config] "tailors the behavior of a component
instance to the context it's running in," which implies that the most
authoritative configuration values should be those which encode the most
knowledge of the component instance's context.
Component Manager will resolve a value for each configuration field, preferring
each source in this order:
1. values from a developer override service ([WIP](https://fxbug.dev/42178358))
2. values from a component's parent
3. values from the component's own package
A component developer working on an engineering build can have knowledge about
everything running on the system, which makes those overrides the most
authoritative. A parent can understand the context it provides to its children.
Finally, because the values in the component's own package can only encode an
understanding of how the component was packaged, all other information must be
provided from an outside source.
[component-config]: /docs/concepts/components/configuration.md
## Generated client libraries
Component authors are expected to access their configuration values using
client libraries generated by the `configc` tool. These libraries consume
the [resolved VMO] through an API provided by the component's runner (like
procargs for the ELF runner), verify that the [checksum] is correct, and return
the parsed configuration values to the caller.
Client libraries return local, non-static values with the configuration
to give users the option of either passing values down their stack as arguments
or explicitly placing configuration values in a globally-accessible location.
Because Component Manager will only start a component if it has valid
configuration values, client libraries appear to the caller to be infallible
and crash the component instance if they are unable to retrieve or
parse configuration values.
[checksum]: #checksum-validation
## Configuration value files
Component resolvers that return a component manifest that includes a `config`
schema must also return a configuration value file.
A configuration value files is a [persisted FIDL message][fidl-persistence] of the
type [`fuchsia.component.decl/ConfigValuesData`][fidl-reference-cvf].
Where compiled component manifests are conventionally stored in a package as
`meta/*.cm`, configuration value files are conventionally stored in a package
as `meta/*.cvf`.
[fidl-persistence]: /docs/contribute/governance/rfcs/0120_standalone_use_of_fidl_wire_format.md
[fidl-reference-cvf]: https://fuchsia.dev/reference/fidl/fuchsia.component.decl#ConfigValuesData
## Resolved VMO
Once component manager has resolved a component's configuration values from the
combination of values from the component resolver and any runtime overrides,
it encodes the configuration into a VMO which is provided to the runner in
[`fuchsia.component.runner/ComponentStartInfo.encoded_config`][runner-vmo].
The first 2 bytes of the VMO should be interpreted as an unsigned 16-bit
little-endian integer which denotes the number of bytes following it that
contain the configuration checksum. After the checksum, all the remaining bytes
are a persistent FIDL message of a top-level struct, matching the layout
used by the [generated client library][client-lib]. The struct's fields match
the configuration fields of the component's compiled manifest in the same order.
[runner-vmo]: https://fuchsia.dev/reference/fidl/fuchsia.component.runner#ComponentStartInfo.encoded_config
## Checksum validation
As a guard rail against accidental misconfiguration from errors in packaging
configured components, `cmc` computes a hash of a component's `config` schema
when compiling its CML and includes that as a checksum in the compiled manifest
(`*.cm`). This checksum is also included in the [configuration value file]
(`*.cvf`), the [generated client library][client-lib] and the [resolved VMO].
At build-time and component-creation-time, the compiled manifest's checksum is
validated to match the checksum in the configuration value file. Component
Manager then places the checksum in the [resolved VMO] when starting the
component. The [generated client libraries][client-lib] check that the value in
the [resolved VMO] matches at runtime before parsing the actual configuration
values.
Note: There is currently no mechanism to verify the version of the
[generated client library][client-lib] against the compiled manifest. Please star
https://fxbug.dev/42079281 for updates.
[configuration value file]: #configuration-value-files
[resolved VMO]: #resolved-vmo
[client-lib]: #generated-client-libraries