States
The host records one status per installed plugin in/var/ados/state/plugin-state.json. The record describes the agent
half; the GCS half has no recorded state of its own.
Grants are recorded per permission and are independent of enable and
disable.
failed and incompatible are reserved states the current
host does not assign. Removal deletes the install record rather than
moving it to a state.
Parse before install
The install flow is two-stage:- Parse: the agent opens the archive in memory, validates the manifest, verifies the Ed25519 signature, and returns a summary. Nothing is written to disk.
- Install: only after the operator approves does the agent commit.
It checks compatibility (
ados_version, board, tier,target_profilesagainst the node’s profile, and a binary for the host architecture), downloads and verifies anypayloads, then unpacks the archive into/var/ados/plugins/<id>/.
Enable and disable
Enable is the first time the plugin runs. For an agent half the host writes a service unit and starts it. On Linux that is a systemd unit namedados-plugin-<id>-<hash8>.service (dots in the id as hyphens,
<hash8> the first 8 hex digits of the SHA-256 of the id), plus one
ados-plugin-<id>-<hash8>-<service>.service per declared service, in
the shared ados-plugins.slice. On macOS it is a per-user LaunchAgent
named co.ados.plugin.<id>-<hash8>; because launchd provides no
sandbox, only first-party plugins install there.
Mission Control mounts the GCS half in each slot it contributes to: in
an iframe, or inline for a first-party gcs.isolation: inline module.
Disable stops the unit. Data on disk persists, and re-enable resumes
from where it left off.
Restarts
A plugin unit restarts on failure every 2 s with no start limit (Restart=on-failure, RestartSec=2s, StartLimitIntervalSec=0). A
crash-looping plugin stays running in the record; check
systemctl status and the plugin log (see
Troubleshooting).
Lifecycle hooks (agent half)
Every hook is optional. The runner looks each one up on your plugin instance and awaits it if it returns a coroutine; a hook you do not define is skipped. The runner is one process per plugin (one per drone withper_drone_config: true). Each time the unit starts, the runner calls
the startup hooks in a fixed order, waits for the stop signal, then
calls the teardown hooks. It keeps no marker across restarts, so the
full sequence runs on every process start.
Most plugins only need
on_start and on_stop.
An agent plugin is a plain class with no base class to subclass, named
by a module:Class entrypoint; a file-path entrypoint loads a class
named Plugin. The ctx argument is the plugin context; see the
Python SDK.
Plugin trait; see the
Rust SDK.
Lifecycle hooks (GCS half)
The GCS half exposesmount and unmount through definePlugin:
mount runs once the bundle loads. When the operator closes the
surface, switches drone, disables or removes the plugin, Mission Control
asks the frame to unmount, waits up to 500 ms, and then destroys the
iframe. Keep unmount short and do not rely on it to persist state;
write state as it changes. For your own teardown, call the unmount()
of the instance definePlugin returns; it runs your unmount.
Remove
ados plugin remove <id> (or Uninstall on the Extensions tab)
tears the plugin out:
- Stop the unit if running.
- Delete the unit file and any declared service units, then reload the service manager.
- Remove the install directory
/var/ados/plugins/<id>/. - Drop the install record from the state file.
--keep-data, remove also deletes the plugin’s log, its data
directory /var/ados/plugin-data/<id>/ and its system user.
--keep-data keeps all three, so a reinstall picks up where it left off.
Configuration changes
On the agent side,ctx.config is the static dict loaded when the
process starts and passed to on_configure. To pick up a later edit
without a restart, read live values with
await ctx.config_kv.get(key, default) at the point of use rather than
caching the dict.
On the GCS side, ctx.config.onChange delivers the plugin’s config on
mount and after every accepted write. See
GCS bridge methods.
State observability
ados plugin info <id> prints the record, and ados plugin logs <id>
prints the agent half’s log. In Mission Control the Extensions tab
shows each plugin’s status.
Next steps
Plugin CLI reference
Drive the lifecycle from a shell.
Troubleshooting
When a plugin will not install or will not stay up.