| # sysmgr configuration |
| |
| sysmgr is one of the two major pieces of Components v1 (appmgr being the other). |
| It is responsible for hosting the 'sys' [realm](/docs/glossary.md#realm) that |
| contains 'global' system services. (The term 'realm' is used throughout this, |
| but note that in v1 it is a synonym for 'environment'.) |
| |
| Most v1 components on Fuchsia today still run directly in the 'sys' realm, |
| especially those responsible for system-wide and non-user-facing functionality. |
| (Eventually, these will be migrated to the newer Components v2 runtime.) There |
| also exist many (often user-facing) components in child realms under 'sys', such |
| as components launched and managed by the Modular framework, that sysmgr is not |
| involved in launching or managing. |
| |
| The services available in the 'sys' realm and the components that sysmgr |
| launches to provide those services are determined based on a set of sysmgr |
| configuration files. This doc describes how to add to sysmgr's |
| configuration, the different configration options sysmgr supports, and the |
| configuration format. |
| |
| ## Adding to sysmgr's configuration |
| |
| At runtime, sysmgr loads all files present under /config/data in its namespace |
| and parses them using the format described below. This directory is provided to |
| sysmgr because it uses the 'config-data' feature in its component manifest, |
| sysmgr.cmx. For more details, see the docs on [the config-data |
| feature](/docs/development/components/config_data.md). |
| |
| You can make a new service available in the 'sys' realm by adding to sysmgr's |
| configuration. There are two supported ways to do so: |
| |
| 1. Unless there is a specific reason to do otherwise, [the centralized |
| services.config file](config/services.config) that is included in the [core |
| product config (core.gni)](/products/core.gni) and all derivative products |
| can be updated. |
| |
| 2. Alternatively, a new GN `config_data` target can be defined and included in |
| [product configurations](/products/README.md) to include an extra file in |
| sysmgr's /config/data directory. |
| |
| A common reason to do this is to change the component that provides a given |
| service depending on the product config, e.g. to use |
| `fuchsia-pkg://fuchsia.com/foo#meta/foo.cmx` in product1.gni and |
| `fuchsia-pkg://fuchsia.com/bar#meta/bar.cmx` in product2.gni to provide |
| service `fuchsia.some.Service`. A similar reason is to change the command |
| line arguments passed to the component depending on the product config in |
| order to modify its behavior. |
| |
| TODO(fxb/48215): There are recognized deficiencies with the centralized |
| services.config file, such as the fact that it is difficult to understand which |
| services are actually available on a given build since it depends on whether the |
| relevant package is available. We plan to address this during the migration to |
| the newer v2 Component Runtime, but in the meantime using services.config is |
| still the recommended default. |
| |
| > Note: With either option, you must take care to ensure that there are no |
| > conflicts in the `services` configuration. For this reason, the best practice |
| > is to only include sysmgr `config_data` targets directly in product |
| > configuration files like core.gni, not in other GN group targets. For example, |
| > it is not recommended to depend on the sysmgr `config_data` target in your |
| > `package` target as this makes it impossible to override the configuration in |
| > a later derived product . |
| > |
| > If there are conflicts present, they will be caught at build time and you will |
| > see an error similar to this: |
| > |
| > ``` |
| > Error: conflicts detected in sysmgr configuration |
| > Duplicate configuration for service fuchsia.my.Service in files: ../../some/path/default.config, ../../some/path/alternative.config |
| > ``` |
| > |
| > TODO(fxb/48223): As a **TEMPORARY** workaround for build errors like this, you |
| > can set the `dangerous_allow_sysmgr_config_conflicts` GN variable to true. This |
| > variable will be removed shortly and should only be used locally by developers, |
| > not in product configs, as it results in non-deterministic behavior (sysmgr may |
| > pick any of the conflicting configs to use). |
| |
| ### Option #2 Example |
| |
| In your `BUILD.gn`: |
| |
| ```gn |
| config_data("my_service_config") { |
| for_pkg = "sysmgr" |
| sources = "my_service.config" |
| } |
| ``` |
| |
| And then in the appropriate `product.gni`: |
| |
| ```gn |
| base_package_labels += [ |
| ... |
| "//path/to:my_service_config", |
| ... |
| ] |
| ``` |
| |
| ## sysmgr configuration format |
| |
| sysmgr's configuration files are in JSON format. Each config file should have a |
| single top-level JSON object, and the following keys are supported: |
| |
| * `services` |
| * `startup_services` |
| * `apps` |
| * `optional_services` |
| * `update_dependencies` |
| * `diagnostics` |
| |
| The contents of all sysmgr config files are read from sysmgr's /config/data |
| directory and merged at runtime to form sysmgr's overall configuration. |
| |
| ### `services` |
| |
| This is the most common configuration key and where most of sysmgr's |
| configuration comes from. Each entry in the `services` map consists of a service |
| name and the component URL which provides it. Optionally, command line arguments |
| can be provided to the component by using an array instead of a string value. |
| |
| ```json |
| { |
| "services": { |
| "fuchsia.foo.Service": "fuchsia-pkg://fuchsia.com/foo#meta/foo.cmx", |
| "fuchsia.bar.Service": [ |
| "fuchsia-pkg://fuchsia.com/bar#meta/bar.cmx", "arg1", "arg2", "arg3" |
| ] |
| } |
| } |
| ``` |
| |
| The combined `services` map across all config files defines the list of services |
| that are available in the `sys` realm and that are available for other |
| components running in the `sys` realm to request in their component manifests. |
| It is not possible to add services to the `sys` realm in any other way; the list |
| of services is fixed at realm creation time. |
| |
| Components in the `services` map are started lazily as the services they provide |
| are connected to. In other words, in the example above `foo.cmx` will not be |
| started until another component attempts to connect to `fuchsia.foo.Service`. If |
| your component needs to be stared eagerly, see `startup_services` or `apps` |
| below. |
| |
| ### `startup_services` and `apps` |
| |
| Both of these keys perform similar functions; they cause sysmgr to eagerly |
| launch components right after it creates the `sys` realm. The key difference is |
| that `startup_services` should be used to eagerly launch a component which is |
| providing services to the `sys` realm (i.e. there is an entry in the `services` |
| map that uses the component), whereas `apps` should be used to eagerly launch a |
| component which does not provide any services to `sys`. |
| |
| For example, the following configuration would cause sysmgr to eagerly launch |
| the component that provides `fuchsia.foo.Service` (the same as if another |
| component attempted to connect to the service) as well as an instance of |
| `bar.cmx` and `baz.cmx` with the given arguments: |
| |
| ```json |
| { |
| "services": { |
| "fuchsia.foo.Service": "fuchsia-pkg://fuchsia.com/foo#meta/foo.cmx" |
| }, |
| "startup_services": [ |
| "fuchsia.foo.Service" |
| ], |
| "apps": [ |
| "fuchsia-pkg://fuchsia.com/bar#meta/bar.cmx", |
| [ "fuchsia-pkg://fuchsia.com/baz#meta/baz.cmx", "arg1", "arg2", "arg3" ] |
| ] |
| } |
| ``` |
| |
| It is important to not mix up usage of `startup_services` and `apps`. Using |
| `apps` instead of `startup_services` can result in sysmgr starting two separate |
| instances of your component, which is likely unintended. For example, the |
| example below would result in two instances of foo.cmx, one started eagerly and |
| the other started lazily when another component connects to |
| `fuchsia.foo.Service`: |
| |
| ```json |
| // WARNING: This is an example of what NOT to do. |
| { |
| "services": { |
| "fuchsia.foo.Service": "fuchsia-pkg://fuchsia.com/foo#meta/foo.cmx" |
| } |
| "apps": [ |
| "fuchsia-pkg://fuchsia.com/foo#meta/foo.cmx" |
| ] |
| } |
| ``` |
| |
| ### `optional_services` |
| |
| `optional_services` causes sysmgr to treat the corresponding `services` entry as |
| optional. In concrete terms all this means is that sysmgr will skip printing |
| error logs if the launching the component that provides the service fails |
| because it was not present or if the component crashes or exits. |
| |
| ```json |
| // WARNING: This is an example of what NOT to do. |
| { |
| "services": { |
| "fuchsia.foo.Service": "fuchsia-pkg://fuchsia.com/foo#meta/foo.cmx" |
| }, |
| "optional_services: [ |
| "fuchsia.foo.Service" |
| ] |
| } |
| ``` |
| |
| ### `update_dependencies` |
| |
| Warning: Here be dragons. You should not modify this configuration unless you |
| are working on the Software Delivery stack. |
| |
| `update_dependencies` is a list of services that the package resolver depends |
| on. sysmgr implements the link between component resolution (through |
| fuchsia.sys.Loader) and the package resolver and needs this information to break |
| dependency cycles, e.g. so that starting the resolver does not first attempt to |
| resolve or update the resolver. |
| |
| ```json |
| { |
| "services": { |
| "fuchsia.pkg.PackageResolver": "...", |
| "fuchsia.needed.for.Resolver": "..." |
| }, |
| "update_dependencies: [ |
| "fuchsia.pkg.PackageResolver", |
| "fuchsia.needed.for.Resolver" |
| ] |
| } |
| ``` |
| |
| The implementation details are subject to change, but as of 2020-04-29 |
| `update_dependencies` currently does two things: |
| |
| 1. All services listed in `update_dependencies` must be present somewhere in the |
| combined `services` map. If any service is missing, ephemeral package updates |
| will be disabled. |
| |
| 2. The `fuchsia.sys.Loader` implementation which sysmgr provides to ephemerally |
| update packages in the `sys` realm - `PackageUpdatingLoader` - is configured |
| to not use the package resolver (to avoid attempting to update) any package |
| which provides a service listed in `update_dependencies`. |
| |
| This avoids cycles, since the `fuchsia.pkg.PackageResolver` service that |
| `PackageUpdatingLoader` uses to ephemerally resolve packages is itself part |
| of the `sys` realm. |
| |
| If the `auto_update_packages` GN arg is set to false, `update_dependencies` has |
| no effect. It is only relevant for ephemeral package updates. |
| |
| ### `diagnostics` |
| |
| Warning: Here be dragons. You should not modify this configuration unless you |
| are working on the Component Diagnostics stack. |
| |
| The `diagnostics` key accepts a single component URL for the component that |
| provides Component Diagnostics. This component is started before |
| `startup_services` or `apps` entries to ensure that diagnostics are available |
| before other components are started in the `sys` realm. |
| |
| ```json |
| { |
| "diagnostics: "fuchsia-pkg://fuchsia.com/archivist#meta/archivist.cmx" |
| } |
| ``` |
| |