rk device pool
The rk device pool command inspects the currently configured device pool. You can use it for triage, dashboards, and operator runbooks.
Synopsis
The following syntax shows how to run the command:
rk device pool status [options]The command accepts the following options:
--pool <kind>: Sets the provider kind to inspect. Defaults to$RK_DEVICE_POOL, then tolocal.--json: Emits machine-readable JSON on stdout.
The pool status subcommand does not accept --profile or --lease-dir. Passing either option returns the error Unknown option: --….
The inventory comes from the registered provider, which typically validates it against the public DeviceInventorySchema from @roku-sdk/tooling. The command does not consult the lease directory because the status snapshot reflects live device state, not the lease ledger.
The status subcommand of the local pool reports configured devices from .roku/roku-dev-config.json. Ephemeral raw-IP leases (acquired with --target <ipv4> without rk device add) do not appear in the output because they are per-call only.
status
The status subcommand takes a snapshot of every inventory entry that the provider can see, plus its live state:
rk device pool status [--pool <kind>] [--json]Output (text)
The text output is a table with one row per inventory entry:
$ rk device pool status --pool shelf
[device-pool] kind=shelf
ID IP STATE FW
shelf-uhd-01 192.0.2.197 free 15.2.0
shelf-uhd-02 192.0.2.198 busy 15.2.0
shelf-uhd-03 192.0.2.199 unreachable 15.2.0In this example, shelf is a provider registered with registerDeviceProvider. The rk tool includes only the local provider; therefore, asking for a kind that you have not registered fails with PROVIDER_NOT_REGISTERED. See Extending the device pool for more information.
The STATE column has the following values:
| Value | Meaning |
|---|---|
free | Either a Layer-2 probe completed and the device is idle on Home with the installer port open, or the provider does not probe at all and treats every registered device as free (local). |
busy | A Layer-2 probe completed, and a non-Home channel is running. Probing providers emit this state; the local provider never does. |
leased | A lease file exists for this device, cross-checked against <lease-dir>. Providers that perform live lease reconciliation emit this state; the local provider does not emit it, because it intentionally skips lease reconciliation and reports every registered device as free. To see whether local has held leases, run rk device lease reap --dry-run --json (or list <lease-dir>/*.json directly). |
unreachable | A Layer-2 probe failed because of an ECP timeout, a non-2xx response, or inventory disabled: true. Only probing providers emit this state. |
Output (--json)
--json)The JSON output conforms to the public ProviderStatus interface:
{
"kind": "shelf",
"devices": [
{ "id": "shelf-uhd-01", "ip": "192.0.2.197", "state": "free", "fw": "15.2.0" },
{ "id": "shelf-uhd-02", "ip": "192.0.2.198", "state": "busy", "fw": "15.2.0" },
{ "id": "shelf-uhd-03", "ip": "192.0.2.199", "state": "unreachable", "fw": "15.2.0" }
]
}You should treat devices[].state as an open set of strings. Providers may add provider-specific states (for example, a cloud provider's provisioning). You should render unknown states exactly as the provider returns them instead of reporting an error.
Interpreting state transitions
The following list describes what each state transition means:
free → busy: Someone sideloaded a non-Home channel. This is expected during active development and test runs. A transient busy state that lasts more than 5 minutes on a CI device indicates a stuck pipeline or a missedrelease.free / busy → unreachable: The network dropped, the device is rebooting, or someone unplugged the device. Persistentunreachable(multiple consecutive runs) is the operator's cue to investigate.unreachable → free: The device recovered, and no operator action is required.
Examples
The following examples show common ways to run the command.
The following command checks how many devices are free before a long run:
$ rk device pool status --pool shelf --json | jq '.devices | map(select(.state == "free")) | length'
2The following commands stop a continuous integration (CI) job when no device is free:
$ FREE=$(rk device pool status --pool shelf --json | jq '.devices | map(select(.state == "free")) | length')
$ [ "$FREE" -eq 0 ] && { echo "No free devices; aborting"; exit 1; }The default local pool does not need --pool:
$ rk device pool status --jsonRelated documentation
rk device lease: Describes theacquire,release, andreapsubcommands.- Extending the device pool: Describes how to register a custom
DeviceProviderwhosestatus()returns the shape that this command consumes.
Updated about 6 hours ago