Skip to content

CLI reference

Reference for the otherix operator CLI - the command-line client for the Otherix control plane.

Hand-maintained

This page is written by hand against the cobra command tree. An autogenerated reference (make docs-cli from the cobra command tree) is planned; until then, treat the binary's own otherix <command> --help as the final authority if anything here drifts.

Global flags

These persistent flags are registered on the root command and inherited by every subcommand.

Flag Default Meaning
--endpoint http://localhost:8080 (only when neither config nor env supply one) Control-plane base URL.
--token (none) API token; overrides $OTHERIX_API_TOKEN and any stored cluster token.
--cluster (none) Named cluster from the config file; overrides current-cluster.
--config $OTHERIX_CONFIG, then ~/.otherix/config Config file path.

Most resource subcommands also accept an output flag, -o / --output, whose allowed values vary by command:

  • Mutating / detail commands: text (default), json.
  • get / list commands: add table and yaml (the YAML form projects an otherix/v1 manifest you can feed back to otherix create -f).
  • node commands: text / table / json (no yaml).

Auth resolution precedence

Endpoint and token are resolved independently, each through its own chain. The first layer that supplies a value wins:

  • Endpoint: --endpoint flag -> $OTHERIX_SERVER -> --cluster entry -> current-cluster entry -> error.
  • Token: --token flag -> $OTHERIX_API_TOKEN -> --cluster entry -> current-cluster entry -> error.

When --cluster is set, only that named cluster is consulted on the config layer (it does not fall back to current-cluster), mirroring kubectl --context.

Config file location

Resolved in order: --config flag -> $OTHERIX_CONFIG -> ~/.otherix/config. The file is a kubectl-style YAML credential store managed by otherix config; see that group to populate it.


otherix vm

Manage virtual machines (CP /v1/vms surface). VM positionals are names; UUID literals are rejected by the server.

vm create

Create a VM from an image source (async; returns a task id). <name> is the sole positional.

Flag Default Meaning
--image-url (required) Source image URL to download and boot from.
--image-sha256 (none) Expected sha256, verified after download.
--arch (required) amd64 or arm64.
--firmware (none) Firmware name (mutually exclusive with --firmware-id).
--firmware-id (none) Firmware uuid (mutually exclusive with --firmware).
--format (server default) Disk format, e.g. qcow2 or raw.
--disk-gib image virtual size Root disk size in GiB.
--pool cluster default pool Storage pool name or uuid.
--node (scheduler picks) Placement hint: node name or uuid.
--network (none, SLIRP fallback) Bridge network name or uuid to attach one NIC.
--vcpus 2 vCPU count (1..128).
--memory-mb 2048 Memory in MiB (128..524288).
--user-data (none) Path to a #cloud-config user-data YAML, or - for stdin. Mutually exclusive with --no-cloud-init.
--network-config (none) Path to a cloud-init network-config YAML (netplan v2), or - for stdin. Mutually exclusive with --no-cloud-init.
--no-cloud-init false Explicitly disable cloud-init. Mutually exclusive with --user-data and --network-config.
--wait false Block until the task reaches terminal status.
--wait-timeout 5m Max wait when --wait is set.
otherix vm create web-1 --image-url https://example.com/ubuntu.qcow2 \
  --arch arm64 --vcpus 2 --memory-mb 2048 --wait

vm get

Show a VM's projection. -o text|json|yaml (default text).

otherix vm get web-1 -o yaml

vm list

Cursor-paginated list of visible VMs.

Flag Default Meaning
--pool (none) Filter by pool name or uuid.
--node (none) Filter by current-location node name or uuid.
--status (none) Filter by status.
--limit 20 Page size (1..200).
--cursor (none) Opaque cursor from a previous page.
-o, --output table table|json|yaml.
--show-ids false Include VM UUIDs in the table.
otherix vm list --status running --limit 50

vm delete

Delete a VM (async). Prompts when stdin is a TTY unless --force.

Flag Default Meaning
--force false Skip the confirmation prompt.
--wait false Block until terminal status.
--wait-timeout 5m Max wait when --wait is set.
otherix vm delete web-1 --force --wait

vm lifecycle (sync)

pause, resume, and reset are synchronous (single QMP call) and take a VM positional plus -o text|json (default text).

  • vm pause <vm> - QMP stop (vCPUs freeze).
  • vm resume <vm> - QMP cont.
  • vm reset <vm> - QMP system_reset (hard reset, runtime identity preserved).
otherix vm pause web-1

vm lifecycle (async)

start, stop, poweroff, and reboot are asynchronous; each takes a VM positional plus --wait / --wait-timeout (5m).

  • vm start <vm> - boot the QEMU process; sets desired_phase=running.
  • vm stop <vm> - graceful ACPI shutdown. --force short-circuits to the poweroff endpoint (hard shutdown) instead.
  • vm poweroff <vm> - hard power-off (QMP quit, then SIGKILL).
  • vm reboot <vm> - graceful stop+start cycle (PID changes).
otherix vm stop web-1 --force --wait   # hard poweroff via --force

vm console

Attach to a VM's serial console interactively (the VM must be running). Press Ctrl+] to bring up a local close prompt. No flags beyond the globals.

otherix vm console web-1

vm logs

Stream a VM's serial console output (kubectl-style).

Flag Default Meaning
--tail -1 (all) Trailing lines from history (0 = none).
-f, --follow false Keep streaming live output after the history flush.
otherix vm logs web-1 --tail 100 --follow

otherix pool

Manage storage pools (CP /v1/storage-pools surface). Multi-instance: one pool name may live on many nodes. create / delete are admin-only.

pool list

Cursor-paginated list of pool instances (one row per node).

Flag Default Meaning
--node (none) Filter by owning node name or uuid.
--type (none) Filter by pool type (local_dir).
--limit 20 Page size (1..200).
--cursor (none) Opaque cursor.
-o, --output table table|json|yaml.
--show-ids false Include instance UUIDs in the table.
otherix pool list --node node-dev

pool get

Dual-shape: a name positional returns the aggregated PoolConceptView; a UUID positional returns the flat per-node instance. -o text|json|yaml (default text).

otherix pool get default        # aggregated by name
otherix pool get <pool-uuid>    # flat per-instance

pool create

Register one (name, node) pool instance. Admin-only. Not idempotent: a duplicate (name, node) is an error.

Flag Default Meaning
--node (required) Owning node name.
--path (required) Filesystem path on the owning node.
--type local_dir Pool type.
--wait false Poll until reconciliation reaches ready/failed (60s timeout).
-o, --output text text|json.
--show-ids false Include the pool UUID in text output.
otherix pool create pool-dev --node node-dev --path /var/lib/otherix/pools/default --wait

pool delete

Delete a pool by name or UUID. Admin-only. Refuses with 409 conflict when vm_disks still reference the pool (no force-delete by design). Prompts when stdin is a TTY unless --force.

Flag Default Meaning
--force false Skip the confirmation prompt.
--node (none) Delete the instance on this node (disambiguates a multi-instance name).
-o, --output text text|json.
otherix pool delete default --node node-1

otherix network

Manage networks (CP /v1/networks surface). Names are globally unique; every authenticated role can read, admin alone may create / delete.

network create

Create one cluster-wide network. Admin-only.

Flag Default Meaning
--type bridge bridge or overlay.
--bridge-name (required for bridge) Host bridge interface name.
--managed false Control plane manages the bridge lifecycle.
--egress none Managed egress mode: none or nat.
--subnet (none) Egress subnet in CIDR form (required for --egress nat and for --type overlay).
--gateway (derived) Gateway IP inside --subnet.
--mtu server 1500 Link MTU (68..9216).
--vlan (untagged) VLAN tag (1..4094).
-o, --output text text|json.
--show-ids false Include the network UUID in text output.

--type overlay requires --subnet and forbids the bridge-only flags (--bridge-name, --mtu, --vlan, --egress, --managed, --gateway).

otherix network create net-dev --bridge-name br0
otherix network create net-nat --bridge-name br-nat --managed --egress nat --subnet 10.10.0.0/24

network list

Cursor-paginated list.

Flag Default Meaning
--type (none) Filter by type (bridge).
--limit 20 Page size (1..200).
--cursor (none) Opaque cursor.
-o, --output table table|json|yaml.
--show-ids false Include network UUIDs in the table.
otherix network list

network get

Show a network and its per-node materialisation status. Positional accepts a name or UUID (a name is resolved client-side). -o text|json|yaml (default text).

otherix network get net-dev

network delete

Delete a network by name or UUID. Admin-only. Refuses with 409 conflict when vm_nics still reference it (no force-delete). Prompts when stdin is a TTY unless --force.

Flag Default Meaning
--force false Skip the confirmation prompt.
-o, --output text text|json.
otherix network delete net-dev --force

otherix node

Browse cluster nodes (CP /v1/nodes surface, read-only) plus join-token management. admin / operator callers see the full Node projection; other roles see the reduced summary.

node list

Cursor-paginated list.

Flag Default Meaning
--architecture (none) Filter by amd64 / arm64.
--status (none) Filter by status.
--limit 20 Page size (1..200).
--cursor (none) Opaque cursor.
--output table table|json.
--show-ids false Include node UUIDs in the table.
otherix node list --architecture arm64

node get

Show a node's projection. <node> is a name. --output text|json (default text), --show-ids includes the UUID.

otherix node get node-dev

node join-token

Mint, list, and revoke node-agent bootstrap tokens (admin only).

join-token create

Mint a fresh token bundle (plaintext token + cluster CA fingerprint), printed exactly once.

Flag Default Meaning
--ttl 1h Token validity (1m..24h).
--max-uses 0 (unlimited within TTL) Consumption cap.
--node-name (none) Bind token to a node identity (forces single-use).
--output text text|json.
otherix node join-token create --node-name node-dev --ttl 10m

join-token list

Flag Default Meaning
--include-expired false Surface expired tokens.
--limit 20 Page size (1..200).
--cursor (none) Opaque cursor.
--output table table|json.
otherix node join-token list --include-expired

join-token revoke

Revoke an unconsumed token by id (UUID positional). No flags beyond the globals.

otherix node join-token revoke <token-id>

join-token consumptions

List the consumption audit trail for a token (UUID positional).

Flag Default Meaning
--limit 20 Page size (1..200).
--cursor (none) Opaque cursor.
--output table table|json.
otherix node join-token consumptions <token-id>

otherix cluster

Manage cluster-wide settings (CP /v1/cluster surface). Mutating commands require admin (cluster:manage).

cluster get-default-pool

Show the cluster default pool reference. --output text|json (default text). Prints an informational line and exits 0 when unset.

otherix cluster get-default-pool

cluster set-default-pool

Set the cluster default pool by NAME (<name> positional). UUIDs are rejected. --output text|json.

otherix cluster set-default-pool default

cluster unset-default-pool

Clear the default pool reference. Prompts when stdin is a TTY; non-interactive use requires --force.

otherix cluster unset-default-pool --force

cluster member list

List etcd cluster members (id, name, learner flag, peer URLs). --output text|json (default text).

otherix cluster member list

cluster member remove

Remove an etcd member by hex id (<id> positional). Prompts when stdin is a TTY; non-interactive use requires --force.

otherix cluster member remove <hex-id> --force

otherix config

Manage CLI cluster credentials in the kubectl-style YAML store at $OTHERIX_CONFIG / ~/.otherix/config.

config add cluster

Log in to a CP, mint a long-lived otx_* API token, and persist it as a named cluster.

Flag Default Meaning
--name (required) Cluster name.
--server $OTHERIX_SERVER CP base URL.
--login $OTHERIX_LOGIN Operator email.
--password $OTHERIX_PASSWORD Operator password.
--set-current true Make this the current cluster.
--force false Overwrite an existing entry (revokes the old token server-side).

Missing required values are prompted interactively when stdin is a TTY.

otherix config add cluster --name dev --server https://cp.dev:8080 --login admin@example.com

config list

List configured clusters (NAME / SERVER / CURRENT). No flags beyond the globals.

otherix config list

config use

Set the current cluster (<name> positional).

otherix config use dev

config remove

Remove a cluster from the config (<name> positional). Prompts when stdin is a TTY; non-interactive use requires --force.

Flag Default Meaning
--force false Skip the confirmation prompt.
otherix config remove dev --force

config show

Print a cluster's details (token masked). [name] is optional and defaults to the current cluster.

Flag Default Meaning
--show-token false Reveal the plaintext API token.
otherix config show dev --show-token

Manifest commands

Top-level create / delete apply multi-document otherix/v1 YAML manifests (Network, StoragePool, VM). Documents are separated by ---.

otherix create -f

Create resources from manifests, ordered Network -> StoragePool -> VM so name references resolve. Best-effort: a failed document does not stop the rest, and a non-zero exit signals any failure.

Flag Default Meaning
-f, --filename (required) Manifest file path, or - for stdin (repeatable).
--dry-run false Print the plan without creating anything.
--wait false Block until every async resource (VM tasks, pool reconciliation) is ready.
--wait-timeout 5m Max wait when --wait is set.
otherix create -f cluster.yaml --wait

otherix delete -f

Delete the resources named by manifests, in reverse create order (VM -> StoragePool -> Network). Existing delete blockers are reported and skipped, never forced.

Flag Default Meaning
-f, --filename (required) Manifest file path, or - for stdin (repeatable).
--force false Skip the confirmation prompt.
--dry-run false Print the plan without deleting anything.
otherix delete -f cluster.yaml --force

See also