cloud.records can also keep small records
in the operator’s cloud account. Pick the right one for the data; do not
pile everything into one.
The layers
Ephemeral state
Normal Python module state. The host runs one process per plugin (per drone, for per-drone plugins), so adict or a list is your ephemeral
store.
Per-plugin disk
Every plugin gets a writable data directory. The runner hands the path to your plugin on the context:ctx.config_dir
(/var/ados/plugin-data/<id>/config/) and ctx.temp_dir, which is
/tmp/<id> inside the unit’s private /tmp and is gone when the process
exits. When the plugin is bound to a specific drone, ctx.data_dir is
scoped per drone (/var/ados/plugin-data/<id>/drones/<agent-id>/), while
ctx.config_dir stays shared and ctx.agent_id carries the drone’s id.
The unit can write only its own /var/ados/plugin-data/<id>/, the shared
plugin log directory and its private /tmp. Another plugin’s data
directory and /run/ados are not writable, and writes elsewhere fail.
filesystem.host adds /srv, /mnt, /media and /boot. The full
sandbox is on
Agent runtime and sandbox.
Atomicity
There is no transaction primitive. For a safe single-file write, write to a<name>.tmp, fsync, and rename over the target. For anything needing ACID,
use a single JSON file you rewrite atomically or SQLite (sqlite3 is in
the Python standard library).
There is only one plugin process, so the only concurrency is your own
asyncio tasks. Add a lock if you fan out writes.
Format guidance
- Configuration: JSON or YAML, typed keys.
- Time-series: append-only
.jsonl(one JSON object per line). - Binary: plain files. Many small files beat one large blob for the page cache.
- Database: SQLite is fine for non-trivial state.
Configuration
The agent context exposes config two ways.ctx.config is the static
config dict the host delivered at start. ctx.config_kv is the live
key-value facade. Its read order is drone scope when bound, then global,
then your default:
set defaults to scope="drone"; pass scope="global" to write the
fleet-wide value. On the GCS half, subscribe to changes with
ctx.config.onChange.
Per-drone plugins
Setper_drone_config: true in the agent: block of manifest.yaml and
the host runs one process instance per connected drone, each with its own
ctx.agent_id and its own scoped ctx.data_dir. Read each drone’s live
settings through ctx.config_kv and fall back to the static dict for unset
keys:
scope="drone"
updates only the bound drone; scope="global" updates the fleet-wide
default the other instances fall back to.
Cloud records
Request thecloud.records capability to keep small JSON records in the
signed-in operator’s cloud account. Records are namespaced to your plugin
by the host, so no other plugin can read them. A record body is at most
64 KiB of JSON, and a plugin holds at most 5000 records.
The GCS half uses ctx.records:
[a-z0-9_.-]. Pass deviceId to
tie a record to one node, and filter list by it. A refused call rejects
with a HostError whose message is unavailable (signed out or offline),
invalid_args, too_large, limit_reached, not_permitted or failed.
The agent half writes with the cloud.records.put host method under the
same grant. Each record carries writtenBy (gcs or agent) and
updatedAt, so either half can tell who wrote last.
Cleanup on remove
ados plugin remove <id>:
- Disables the plugin if it is running or enabled, which stops its units.
- Deletes the main unit and any declared service units.
- Removes the install directory
/var/ados/plugins/<id>/and the install entry from the state file. - Unless
--keep-datais passed, deletes/var/ados/plugin-data/<id>/(including per-drone subdirectories andconfig/files), the plugin’s logs, and its system user.
--keep-data to keep both the data directory and the logs, so a later
install of the same plugin id picks up its prior data.
Migration between versions
Plugins own their own data migrations. There is no SDK migration helper, so carry a small version marker in your data directory and migrate forward on start:What not to put on disk
- Secrets you did not generate yourself. The host manages pairing keys, MAVLink session keys and signer keys.
- Large media. Anything over a gigabyte belongs in a recording, not the data directory.
- Operator personal data without consent. The data directory is not encrypted at rest.
Next steps
Versioning and updates
Semver, compatibility ranges, automatic updates and rollback.