List hypervisor nodes (operator-only).
curl --request GET \ --url 'https://stratum.example.com/v1/compute/nodes?state=ready&role=hybrid' \ --header 'Authorization: Bearer <token>'Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Responses
Section titled “Responses”Hypervisor nodes.
Complete: returns every hypervisor node in the cluster.
This list is bounded by the install’s own configuration rather than by
tenant activity, so it is not paginated and carries no nextPageToken. A client has the whole set in one response.
object
Operator-facing inventory record Appendix A.
widened the role enum from the original VM-hosting
subset (hybrid, hypervisor) to all four master-plan D5
roles. Control-plane and storage nodes self-register so they
appear in the Nodes page + capacity dashboards; the scheduler
filters by role and never places instances on them.
object
operator-friendly per-node display label (e.g.
“stratum-01”). Independent of id: id is the canonical
n-node_name metric label.
Settable via PATCH /v1/compute/nodes/{nodeId}; sticky
across redeploys.
/ D5 node role. hybrid and hypervisor run VMs;
control-plane and storage appear here for inventory +
capacity visibility but never accept placement.
VCPUs the node keeps for itself (kernel, control plane, substrate),
taken off the total before the overcommit ratio. On a single-node
install computed as max(2, 6% of the threads) unless an operator set
it; see reservationSource.
Memory the node keeps for itself, taken off the total before the overcommit ratio. On a single-node install computed as max(6 GiB, 10% of RAM) unless an operator set it, and enforced there: system.slice gets MemoryMin/MemoryLow equal to it.
Who wrote the reservation. reported: the heartbeat, on
every heartbeat (every clustered node). computed: the single-node
default, kept in step with the node’s size. operator: set through
PATCH /v1/compute/nodes/{nodeId}, or chosen at install (node.yaml
host_reservation,, written when the node first registers);
nothing else changes it.
VCPUs the node can have committed: floor((total - reserved) x overcommit), the scheduler’s own formula. Derived, never stored.
Memory the node can have committed: floor((total - reserved) x overcommit), the scheduler’s own formula. Derived, never stored.
The node’s label map, all string-valued. Two key namespaces are reserved and defined by the platform; any other key is the operator’s own and is never interpreted here.
topology.* — where the machine physically sits. topology.az is
published from the node’s declared availability zone; topology.rack and
topology.power are declared by the operator in the cluster topology.
An undeclared level simply does not exist for that cluster.
capability.* — what the hardware can do, detected by the node on every
heartbeat so a hot-installed device is picked up without restarting it:
capability.cpu.model, capability.cpu.sockets, capability.gpu.present,
capability.mem.ecc, capability.sec.tpm, capability.virt.nested, and
the rest of the detected set.
Each key has a kind, declared by the platform and never inferred from
the value. Descriptive keys are matched by equality and
consumed by nothing. Boolean keys are true or false. Countable
keys carry a whole number and are consumed on placement:
capability.net.sriov_vfs (virtual functions, each attaching to a single
guest) and capability.mem.hugepages_1g. The accelerator namespaces
capability.gpu.<vendor-model> and capability.accel.<vendor-model> are
countable and open — a new model is data, not a schema change — and are
declared by an operator until device enumeration ships.
capability.cpu.cores and capability.cpu.threads are descriptive, not
countable: vCPU is accounted separately and with an overcommit ratio, so
counting them here would account the same resource twice under two
different rules.
A countable key that is absent is not zero. Absent means the node did not report it — the control plane runs in a container that often cannot read host sysfs — while zero means the node genuinely has none.
These keys are operational rather than physical:
capability.migration.transport—listeningordown; whether this node can RECEIVE a live migration.capability.host.binaries_commit— the git commit the node’s/usr/local/binbinaries were built from,mixedwhen they disagree with each other, orunknownwhen they are too old to report it.capability.host.binaries_stale—truewhen those binaries are not the build the node should run: on a mutable node the deployed control plane’s (a control-plane deploy replaces a container image and does NOT touch host binaries, so they drift from the day a node is built), on an image-mode node the host binaries of the release the cluster runs, as theHostBinariesStalereadiness finding judges them.capability.host.binaries_unknownnames the ones that could not report at all — those are the binaries most likely to be missing a subcommand a runbook names.capability.host.binaries_source— what fixes a stale node.control-plane-imageon a mutable node: the host-helper installs the control plane’s copies on its next pass.os-imageon an image-mode (bootc) node: the binaries are part of the read-only stratum-os image and nothing on the node changes them, so stale there lasts until an upgrade changes them.overlayon an image-mode node whose binaries were switched in live from a release: the next upgrade switches them again.capability.host.dev_mode—truewhen the node’s control plane runs in dev mode (node.yamldev_mode,): the substrate’s web UIs on loopback, the OpenBao UI, and credentials inline in the admin substrate-tools response. Reported by the control plane’s own heartbeat, so a node without a control plane has no key. Readiness lists each such node asDevModeOn.
Where a declared label and detection disagree the declared value wins and the override is logged.
Absent keys mean “not reported”, never “false” — a node whose host-helper
has not run a pass publishes no capability.host.binaries_* keys at all.
renamed every key under these prefixes; the previous unprefixed
names (hasGpu, cpuModel, migrationTransport,…) are no longer
published.
object
How many units of each countable capability are currently allocated
on this node — capability.net.sriov_vfs,
capability.mem.hugepages_1g, capability.gpu.<vendor-model> and the
rest of the countable set.
Deliberately separate from capabilities: that map is what the node
SAYS about itself, this is what the platform has handed out. Mixing them
would make a node’s self-report depend on scheduling decisions it never
made.
Free units are capabilities[key] - committedCapabilities[key]. An
absent key means none are allocated, and a node holding nothing omits
the object entirely.
A count here can exceed the declared total if an operator shrinks a declared capability below what is already allocated. That is a supported state, not a corruption: existing guests keep what they hold and nothing new is placed until reality catches up. Clamp at zero when computing free rather than rendering negative capacity.
object
The node’s latest shutdown or reboot through the API, absent
when it never had one. In progress while state is shutting-down,
rebooting or off.
object
shutting-down— recorded; the node powers off atnotBefore.rebooting— recorded; the node reboots atnotBefore, and staysrebootinguntil it has booted again.off— a shutdown whose node stopped heartbeating. It staysoffuntil someone powers it on (seepowerOn).done— the node booted again after the action.failed— the host did not power off or reboot;messagesays why.
Bumped by every new action on the node.
When the host acts: a short delay after the request, so the 202 is answered before the node (and, on a single node, the API) goes down.
When a shutdown’s node was seen gone.
What the action is doing or waiting for, or why it failed.
True when this node is the only control-plane node up (a single-node install, or the last node of a cluster): the console and the API go down with it, and nothing answers until it is back.
How the node comes back after a shutdown: its power button, and Wake-on-LAN to its out-of-band NIC’s MAC when the node reported one.
Example
{ "items": [ { "role": "hybrid", "architecture": "amd64", "state": "ready", "reservationSource": "reported", "powerAction": { "action": "shutdown", "state": "shutting-down" } } ]}