blob: e9763b99e8ea3381fd64d0ac8208be0e09e31c7d [file] [log] [blame] [view]
# Run components
This document demonstrates how to add components directly to the component
instance tree during development and interact with them at runtime.
Fuchsia provides a few abstractions on top of
[component framework][glossary.component-framework] for specific
use cases. If you are building components using one of the following frameworks,
refer to the corresponding guides instead:
* **Session components:** [Building and running a session][run-session]
* **Test components:** [Run Fuchsia tests][run-test]
Note: For more details on the commands described in this guide, see the
[`ffx component` reference][ffx-reference].
## Concepts {#concepts}
You should understand the following concepts before running a component:
* At runtime,
the [component instance tree][glossary.component-instance-tree]
connects individual [component instances][glossary.component-instance]
together in a hierarchy of parent and child relationships.
* Component instances progress through four major lifecycle states:
create, start, stop, and destroy.
* A [component moniker][glossary.moniker] identifies component instances
within the tree using their topological path.
* Component instances are declared **statically** as a
[child][manifest-children] of another component in their
[component manifest][glossary.component-manifest] or created **dynamically**
at runtime in a [component collection][manifest-collections].
Each instance consists of a component `name` and `url`.
* A [component URL][glossary.component-url] identifies a component.
Component URLs are resolved by the component framework, often to a resource
inside a package.
For more details on component execution, see [Component lifecycle][lifecycle-doc].
## Component instances {#instances}
The first step to running a component is adding a new component instance to the
tree. The position of the component instance within the tree determines its
available [capabilities][glossary.capability].
### Discover static components
Static components are *declared* as children of another component instance in
the tree. You can use `ffx component show` to determine the moniker and
component URL of a static component instance:
```posix-terminal
ffx component show {{ '<var label="component">COMPONENT_NAME</var>' }}
```
Replace `COMPONENT_NAME` with the name of a component.
The following example shows the command output for the `pkg-resolver` component:
```none {:.devsite-disable-click-to-copy}
$ ffx component show pkg-resolver
{{ '<strong>' }}Moniker: /core/pkg-resolver{{ '</strong>' }}
{{ '<strong>' }}URL: fuchsia-pkg://fuchsia.com/pkg-resolver#meta/pkg-resolver.cm{{ '</strong>' }}
Type: CML static component
Component State: Resolved
Execution State: Running
...
```
Static component instances cannot be created or destroyed at runtime.
### Manage dynamic components
Dynamic components are *created* at runtime inside of a collection.
You can use `ffx component create` to create a new component instance, providing
a target moniker within an existing collection and a component URL for resolving
the component:
```posix-terminal
ffx component create {{ '<var label="moniker">TARGET_MONIKER</var>' }} {{ '<var label="url">COMPONENT_URL</var>' }}
```
Replace `TARGET_MONIKER` with the destination moniker of the new component
inside an existing collection and `COMPONENT_URL` with the location where the
component is being served.
For example, the following command creates a new component instance inside the
`ffx-laboratory` collection named `hello-world`:
```none {:.devsite-disable-click-to-copy}
$ ffx component create /core/ffx-laboratory:hello-world fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world-rust.cm
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world-rust.cm
Moniker: /core/ffx-laboratory:hello-world
Creating component instance...
```
Similarly, use `ffx component destroy` to destroy a dynamic component instance
by providing its moniker:
```posix-terminal
ffx component destroy {{ '<var label="moniker">TARGET_MONIKER</var>' }}
```
Replace `TARGET_MONIKER` with the moniker of the component to destroy.
The following example destroys the `hello-world` component created above:
```none {:.devsite-disable-click-to-copy}
$ ffx component destroy /core/ffx-laboratory:hello-world
Moniker: /core/ffx-laboratory:hello-world
Destroying component instance...
```
## Component execution {#execute}
Once a component instance exists in the tree, you can start and stop the target
instance using `ffx component`.
### Start the instance
Use `ffx component start` to explicitly start a component instance:
```posix-terminal
ffx component start {{ '<var label="moniker">TARGET_MONIKER</var>' }}
```
Replace `TARGET_MONIKER` with the moniker of the component to start.
The following example starts the `hello-world` component created previously:
```none {:.devsite-disable-click-to-copy}
$ ffx component start /core/ffx-laboratory:hello-world
Moniker: /core/ffx-laboratory:hello-world
Starting component instance...
```
### Stop the instance
Use `ffx component stop` to terminate execution of a running component instance
using its moniker:
```posix-terminal
ffx component stop {{ '<var label="moniker">TARGET_MONIKER</var>' }}
```
Replace `TARGET_MONIKER` with the moniker of the component to stop.
The following example stops to the `hello-world` component started above:
```none {:.devsite-disable-click-to-copy}
$ ffx component stop /core/ffx-laboratory:hello-world
Moniker: /core/ffx-laboratory:hello-world
Stopping component instance...
```
Note: You can add the `--recursive` flag to stop all child components.
For more details, see the [`ffx component` reference][ffx-reference].
## Run a component {#run}
The `ffx component run` command provides a quickstart to run basic components
during development:
```posix-terminal
ffx component run {{ '<var label="url">COMPONENT_URL</var>' }}
```
Replace `COMPONENT_URL` with the location where the component is being served.
The following example creates a component instance using the `hello-world-rust`
component:
```none {:.devsite-disable-click-to-copy}
$ ffx component run fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world-rust.cm
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world-rust.cm
Moniker: /core/ffx-laboratory:hello-world-rust
Creating component instance...
Starting component instance...
```
The `ffx component run` command automates the following steps:
1. Create a new component instance in the [`ffx-laboratory`](#ffx-laboratory)
collection, using the component name as the target moniker.
1. Start the new instance to begin execution.
The example above is equivalent to running the following individual `ffx` commands:
```none {:.devsite-disable-click-to-copy}
$ ffx component create /core/ffx-laboratory:hello-world-rust fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world-rust.cm
$ ffx component start /core/ffx-laboratory:hello-world-rust
```
### `ffx-laboratory` {#ffx-laboratory}
The `ffx-laboratory` is a component collection that provides a restricted set of
capabilities for development. The following capabilities are offered to
components in this collection:
* [Protocol capabilities][capability-protocol]
* [`fuchsia.logger.LogSink`][fidl-logger]: Record log messages
* [`fuchsia.process.Launcher`][fidl-launcher]: Create new processes
* [Storage capabilities][capability-storage]
* `tmp`: Temporary storage (non-persistent)
* `data`: Emulated persistent storage backed by `/tmp`
* `cache`: Emulated cache storage backed by `/tmp`
* [Directory capabilities][capability-directory]
* `/dev`: Device driver `devfs` provided by Driver Manager
* `/boot`: Read-only `bootfs` provided by Component Manager
The `ffx-laboratory` is a [`transient`][manifest-collections] collection.
Component instances in this collection will persist even after they stop.
To destroy a component instance in this collection, use the `ffx component destroy` command.
## Troubleshooting
This section contains common issues you may encounter while running your
components during development.
### Unable to resolve the component
When using `ffx component start` or `ffx component run` you may encounter the
following error if component framework cannot resolve the component instance:
```none {:.devsite-disable-click-to-copy}
$ ffx component run fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
Moniker: /core/ffx-laboratory:hello-world
Creating component instance...
Starting component instance...
Lifecycle protocol could not bind to component instance: InstanceCannotResolve
```
This occurs when the component URL does not resolve to a valid component
manifest.
To address this issue, verify the following:
* The [component URL][component-url] is formatted correctly.
* You have a [package server running][package-server].
* Your package server is registered with the target.
* Your [component is published][package-updates] to the package server.
### Component instance already exists
When using `ffx component create` or `ffx component run` you may encounter the
following error if the component instance already exists:
```none {:.devsite-disable-click-to-copy}
$ ffx component run fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
Moniker: /core/ffx-laboratory:hello-world
Creating component instance...
Component instance already exists. Use --recreate to destroy and recreate a new instance, or --name to create a new instance with a different name.
```
This occurs when the target moniker is already in use by another component
instance.
To address this issue, manually destroy the instance using the `ffx component destroy` command:
```none {:.devsite-disable-click-to-copy}
$ ffx component destroy /core/ffx-laboratory:hello-world
Moniker: /core/ffx-laboratory:hello-world
Destroying component instance...
```
If you are using `ffx component run`, add the `--recreate` flag to destroy the instance and
recreate it:
```none {:.devsite-disable-click-to-copy}
$ ffx component run fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm --recreate
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
Moniker: /core/ffx-laboratory:hello-world
Creating component instance...
Component instance already exists. Destroying...
Recreating component instance...
Starting component instance...
```
Alternatively, add the `--name` flag to create a new instance with a different name:
```none {:.devsite-disable-click-to-copy}
$ ffx component run fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm --name hello-world-2
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
Moniker: /core/ffx-laboratory:hello-world-2
Creating component instance...
Starting component instance...
```
[capability-directory]: /docs/concepts/components/v2/capabilities/directory.md
[capability-protocol]: /docs/concepts/components/v2/capabilities/protocol.md
[capability-storage]: /docs/concepts/components/v2/capabilities/storage.md
[component-select]: /docs/development/tools/ffx/commands/component-select.md
[component-url]: /docs/reference/components/url.md
[fidl-launcher]: https://fuchsia.dev/reference/fidl/fuchsia.process#Launcher
[fidl-logger]: https://fuchsia.dev/reference/fidl/fuchsia.logger#LogSink
[ffx-reference]: https://fuchsia.dev/reference/tools/sdk/ffx.md#component
[glossary.capability]: /docs/glossary/README.md#capability
[glossary.component-instance]: /docs/glossary/README.md#component-instance
[glossary.component-instance-tree]: /docs/glossary/README.md#component-instance-tree
[glossary.component-manifest]: /docs/glossary/README.md#component-manifest
[glossary.component-url]: /docs/glossary/README.md#component-url
[glossary.moniker]: /docs/glossary/README.md#moniker
[lifecycle-doc]: /docs/concepts/components/v2/lifecycle.md
[manifest-children]: https://fuchsia.dev/reference/cml#children
[manifest-collections]: https://fuchsia.dev/reference/cml#collections
[package-server]: /docs/concepts/packages/package_update.md#connecting_host_and_target
[package-updates]: /docs/concepts/packages/package_update.md#triggering_package_updates
[run-session]: /docs/development/sessions/building-and-running-a-session.md
[run-test]: /docs/development/testing/run_fuchsia_tests.md