Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI & TUI (raptorctl)

raptorctl is a separate binary (crate raptor-cli) that drives a running raptor server over the same Management API the web console uses. It is a pure HTTP client — install it anywhere that can reach raptor serve, no server-side changes required.

Install

Each GitHub Release attaches raptorctl-<tag>-<target>.tar.gz (plus a .sha256) for aarch64-apple-darwin, x86_64-unknown-linux-gnu and aarch64-unknown-linux-gnu. With mise, pin it like any other tool:

[tools]
"github:rosterloh/raptor" = { version = "1.3.2", bin = "raptorctl" }

The server’s .deb also ships /usr/bin/raptorctl. Elsewhere, build it from source with cargo build --release -p raptor-cli.

Login

$ raptorctl login --url http://localhost:8088 --user admin
password for admin: 
logged in as admin

This verifies the credentials with a request against the server, then saves them to ~/.config/raptor/cli.toml (mode 0600). Every later command reuses that file, so --url/--user are only needed again to switch servers.

raptorctl logout deletes the saved file.

Scripting / CI

Skip the config file entirely with environment variables — useful in CI where there’s no interactive prompt for login to read a password from:

$ RAPTOR_URL=http://localhost:8088 RAPTOR_USER=admin RAPTOR_PASS=secret \
    raptorctl target list

Precedence is flags > environment > the saved config file.

Commands

Every command accepts --json to print the server’s raw response instead of a table — pipe it into jq:

$ raptorctl target list --json | jq '.content[].controllerId'
CommandDoes
target list/get/create/set/deletetarget CRUD
target attributes <cid>reported device attributes
target tag add|rm <cid> <tag>tag/untag a target
target type list/set/cleartarget types, and a target’s constraint
tag list/create/delete [--ds]tag CRUD (target tags, or --ds for set tags)
target assign <cid> --ds <id> [--force ...]assign a distribution set
target actions <cid>a target’s action history
module list/create/deletesoftware module CRUD (delete is refused while a set references it)
artifact upload/list/delete <moduleId>artifact management
ds list/get/createdistribution set CRUD
ds invalidate <id>withdraw a set so it can no longer be deployed
ds tag add|rm <id> <tag>tag/untag a distribution set
publish <file> --version <v>module + artifact + distribution set in one call
action list/status/cancel/forcedeployment action control
rollout list/getlist rollouts, show one with its targets counted by outcome
rollout create <name> --ds <id> --filter <fiql> --groups <n> --success <pct>create a rollout (flags for every RolloutCreate field)
rollout start/pause/resume/stop <id>drive a rollout’s lifecycle; stop confirms unless -y
rollout approve/deny <id>decide rollouts awaiting approval
statusfleet-wide statistics

Run raptorctl <command> --help for full flag lists.

publish and the two type vocabularies

publish creates a software module, uploads the file to it, and wraps it in a distribution set. Those are typed from two different hawkBit vocabularies:

FlagVocabularySeeded values
--module-type (alias --type)software-module typesos, firmware, runtime, application
--ds-typedistribution-set typesos, os_app, app

--ds-type is optional: raptorctl reads /rest/v1/softwaremoduletypes and /rest/v1/distributionsettypes and derives it — an exact key match wins (os → os), otherwise the one set type that requires exactly that module type (application → app). When neither applies (e.g. --module-type firmware, which no seeded set type requires) it errors and asks for --ds-type rather than guessing, because a wrong guess builds an incomplete distribution set that only fails later, at assign time.

Both types, and the file itself, are checked before anything is written. That ordering matters: the sequence is create-module → upload → create-set, so a failure at a later step would otherwise leave an orphaned module behind. If the upload or the set creation still fails (the network, the server), publish deletes the module it created; if even that fails, the error names the module to remove with raptorctl module delete <id>.

Withdrawing a release

ds invalidate is the inverse of publish: the set can no longer be assigned or rolled out, and any target filter auto-assigning it is detached. There is no undo.

$ raptorctl ds invalidate 7
invalidate distribution set 7 (fw:1.4.1)? this cannot be undone. [y/N] y
invalidated distribution set 7 (fw:1.4.1)

The bare command is the safe one, because it is the one that gets run in a hurry: in-flight actions and rollouts are left alone, so a device that has already installed the set still reports its result. The destructive parts are opt-in:

FlagEffect
--cancel-rolloutsalso stop rollouts deploying this set
--cancel-actions softask devices to stop; the action ends when the device confirms
--cancel-actions forcecancel server-side at once, without waiting for the device
--yes (-y)skip the confirmation prompt

The prompt only appears when stdin is a TTY, so scripts and CI need no --yes. ds get reports the result as valid false.

Tags

tag manages the tag itself; target tag/ds tag only assign an existing one to something. --ds switches every tag subcommand from target tags to distribution-set tags.

$ raptorctl tag create zephyr --description 'Zephyr firmware fleet' --colour '#4caf50'
created target tag 3 (zephyr)
$ raptorctl tag list
ID  NAME    DESCRIPTION            ASSIGNED
3   zephyr  Zephyr firmware fleet  0
$ raptorctl target tag add dev-042 zephyr
tagged dev-042 with zephyr

Assigning a tag that doesn’t exist names the ones that do, so a typo and a never-created tag are distinguishable:

$ raptorctl target tag add dev-042 zephry
error: no target tag named 'zephry' — existing: zephyr, prod. Create it with 'raptorctl tag create zephry'.

Target types

A target type constrains which distribution-set types the target will accept, so it is a correctness setting rather than an organisational one — an incompatible assignment is rejected at assign time.

$ raptorctl target type list
ID  NAME     DESCRIPTION  ACCEPTS_DS_TYPES
1   gateway  -            os
$ raptorctl target type set dev-042 gateway
dev-042 is now target type gateway (1)
$ raptorctl target get dev-042 | grep targetType
targetType    gateway
$ raptorctl target assign dev-042 --ds 7
error: distribution set type 'app' is not compatible with target type 'gateway', which accepts: os (HTTP 400)

raptorctl target type clear <cid> removes the constraint. Creating target types themselves is not in the CLI yet — use the console or POST /rest/v1/targettypes.

Rollouts

rollout create takes the POST /rest/v1/rollouts body as flags, with the nested conditions flattened: --success/--error are percentages, and --dynamic-suffix/--dynamic-count build the dynamicGroupTemplate. A template flag without --dynamic is rejected before anything is sent.

A dynamic rollout never finishes on its own (see the Rollouts guide), so its full lifecycle is create, start, and eventually stop:

$ raptorctl rollout create fleet-1.1 --ds 16 --filter 'tag==rpi5' \
    --groups 1 --success 50 --dynamic --dynamic-suffix -dynamic --dynamic-count 20
created rollout 2 (fleet-1.1) — 4 targets, now ready

$ raptorctl rollout start 2
rollout 2 is now running

$ raptorctl rollout get 2        # watch it absorb newly-matching targets
...
targets      4
  notstarted 0  scheduled 2  running 2  finished 0  error 0  cancelled 0

$ raptorctl rollout stop 2
stop rollout 2 (fleet-1.1) and cancel its in-flight updates? this cannot be undone. [y/N] y
rollout 2 is now stopping

stop soft-cancels the rollout’s in-flight actions and is terminal, so it asks first on a TTY; pass -y to skip the prompt. It reports stopping until those devices acknowledge the cancel. pause and resume hold and release group progression without cancelling anything.

Rollout approval

When the server runs with rollout_approval_enabled = true, a new rollout waits in waiting_for_approval until an operator decides on it:

$ raptorctl rollout list
ID  NAME       STATUS                FINISHED  DECIDED BY
7   fw-1.4.2   waiting_for_approval  0/240

$ raptorctl rollout approve 7 --remark "checked with ops"
rollout 7 is now ready

deny is the other half, and is terminal — a denied rollout can only be deleted, so create a fresh one to try again. Both take an optional --remark recorded against the decision. See the Rollouts guide.

End-to-end example

$ raptorctl module create --name fw --version 1.4.1 --type os
$ raptorctl artifact upload 1 ./firmware.bin
$ raptorctl ds create --name fw --version 1.4.1 --type os --module 1
$ raptorctl target create dev-042
$ raptorctl target assign dev-042 --ds 1 --force forced
$ raptorctl target get dev-042

TUI

raptorctl tui opens an interactive dashboard: the fleet on the left, the selected target’s status, assigned/installed set, and action history on the right, and running rollouts underneath the target list.

$ raptorctl tui [--refresh <seconds>]   # default 5, 0 disables auto-refresh
KeyDoes
↑↓ / j/k, g/Gmove selection
/filter targets (sent server-side as a FIQL q=)
aassign a distribution set to the selected target
ttag the selected target
c / fcancel / force the target’s active action (y to confirm, n/Esc to back out)
rrefresh now
?help
qquit

It respects NO_COLOR, works over SSH and inside tmux, and requires at least an 80x24 terminal. An active filter shows in the targets panel title; a failed or timed-out refresh (15 s) leaves ⚠ stale in the header until that fetch succeeds again.