Environments

Environments provide a way to configure certain choices the framework makes for components in a realm. Component manifests may define environments and assign them to child realms. An environment applies to a component instance's entire realm, unless some sub-realm overrides it (see Propagation).

Properties

Environments let you configure the following behavior of a realm:

Runners

The component framework is runtime-agnostic and can support new runtime environments and programming languages without requiring changes to component manager or to other components. Runners provide the extension point for components to interact with component manager and add runtime support to Fuchsia. Some example runners are:

  • The ELF runner runs binaries compiled to the ELF file format.
  • The Dart AOT runner provides a runtime for Dart programs, such as a VM.
  • The Chromium web runner provides a runtime for components implemented as web pages.

Component manager identifies what to execute and delegates how execution works to the runner. Runner implementations are free to choose an appropriate strategy for executing their components, including:

  • Start a new process for the component.
  • Isolate the component within a virtual machine.
  • Run the component in the same process as the runner.
  • Execute the component as a job on a remote computer.

For more details on using and implementing runners, see runner capabilities.

Resolvers

Component resolvers interact with component manager on behalf of a component to resolve its children from a given component URL. Resolvers are registered with a particular URL scheme (http, fuchsia-pkg, etc.) and provide an implementation to fetch the component from the desired URL and return a component declaration.

If the component being resolved has an associated package, the resolver also returns a fuchsia.io.Directory handle representing the package directory.

For more details on using and implementing resolvers, see resolver capabilities.

Declaring

Define a new environment by adding an environments declaration to a component manifest.

For an environment to be used, you must assign it to a child or collection. See Propagation.

Environments support two modes of extension, REALM or NONE:

  • REALM: The environment inherits its properties from the environment that was assigned to this component (the “parent environment”). Any new properties will be added on top of those inherited from the parent environment. Any properties that overlap with the parent environment will override the parent.
  • NONE: The environment starts empty, with no initial properties.

Propagation

A component instance is assigned an environment in one of two ways:

  • Its child or collection does not have environment set. In this case, it will receive its parent's environment. This is the most common case.
  • Its child or collection sets environment, which refers to one of the environments defined by this component.

The root component is assigned an environment by component manager. This includes a bootstrap resolver, the ELF runner, and default configuration options.

Environments vs. capability routing

The semantics of environments contrast with capability routing. With capability routing, a capability must be explicitly exposed or offered by every component in the path from the provider to the consumer. The explicit nature of capability routing makes it easy to guarantee that components don‘t receive access to capabilities they shouldn’t have, thus maintaining the principle of least privilege.

However, there are some configuration choices that don‘t make sense to configure on a per-component basis. For example, consider runners. Almost every component needs to use a runner, but defining a new runner is not very common -- certainly less common than defining a protocol capability, for instance. Furthermore, access to a runner doesn’t inherently grant a component much privilege, for the component framework mediates access to the runner‘s protocol and the component can’t use that protocol directly. Therefore, runner capabilities are registered in an environment, which makes them available to any component in the realm to which that environment was assigned (unless some sub-realm decides to set a new environment with the runner absent).