Exclusive Access · Invitation Only

Consoles

Every virtual machine has two consoles, as a physical server would: a **serial console** (text, what the guest prints on its first serial port) and a graphical console (its screen, keyboard and mouse). Both work whatever state the guest's network is in — they are how you rescue a machine that has locked itself out.

Part of Compute, in early access. In the browser, the node's web console opens both consoles for you; this page covers the node's command line and the local API underneath.

The serial console on the node

sudo cenvero-str-ctl vm console vm-3f9a1c2e

Your terminal becomes the machine's serial console. Everything you type goes to the guest, Ctrl+C included; Ctrl+] disconnects. Press Enter if the screen stays empty — the guest prints its login prompt again.

  • One serial session per machine at a time. --force takes it over from another Stratum session (that one is closed, and told why); --force=false is the same as leaving it out.
  • If another program on the node has the machine's serial console open, the console is refused until that program lets go — and while you are connected, that program is refused. Neither ever silently takes the other's keystrokes.
  • The machine must be running.
  • Input from a pipe or a file instead of your keyboard (echo … | … vm console) ends the session at the end of that input.
  • A terminal that stops reading (a suspended job, say) is disconnected once it has left the machine's output unread for 30 seconds, so it cannot hold the serial console.
  • Closing the command with a signal (kill, including kill -INT) ends the session and puts your terminal back as it was.

Consoles over the API

The local API serves both consoles as WebSockets. A browser cannot put a token on a WebSocket, so you first ask for a ticket — single use, valid for 60 seconds, for one console of one machine:

curl -k -X POST "$NODE/api/v1/vms/vm-3f9a1c2e/console" -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" -d '{"type":"vnc"}'
{
  "ticket": "q3J0…",
  "expires_in": 60,
  "path": "/api/v1/vms/vm-3f9a1c2e/console/vnc?ticket=q3J0…",
  "type": "vnc"
}

Then open wss://<node>:7070 + path as a WebSocket:

typePathWhat flows
vnc…/console/vncThe graphical console, as VNC (RFB) in binary frames. A standard noVNC client connects to it unchanged; the binary subprotocol is accepted
serial…/console/serialThe serial console's bytes. Text or binary frames from you; binary frames back

Scripts may skip the ticket and send the operator token on the upgrade itself (Authorization: Bearer …), for example with websocat. "force": true in the ticket request (or ?force=true with a token) takes the serial console over, as --force does above; force takes true or false.

A ticket is used up only by the WebSocket connection it was made for. A plain GET of the path (a browser prefetching a link, a check with curl), a request that is not a valid WebSocket handshake, or a page on another site is refused without touching the ticket, so the real viewer can still use it.

Who may open one. An operator token or operator API key. A tenant-scoped key opens the consoles of its own tenant's machines with a ticket from POST /api/v1/tenant/{id}/vms/{vmid}/console (the tenant portal, see API Reference); it is not accepted on the WebSocket itself, and not while its tenant is suspended. A browser page on another site cannot open a console: the WebSocket's origin must be the node itself or one you listed in api_allowed_origins. Failed attempts count towards the API's lock-out, like any other.

The local API must be enabled on the node (it is off by default — see Installation). The serial console on the node's command line works without it.

A machine on another member of a cluster

In a cluster (agent 1.0.0-rc.81 or later), any member opens the consoles of every member's machines. Ask the member you are connected to for the ticket, with /api/v1/nodes/<node id> in front of the path, where <node id> is the member the machine runs on:

curl -k -X POST "$NODE/api/v1/nodes/7c9e6679-7425-40de-944b-e07fc1f90ae7/vms/vm-3f9a1c2e/console" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"type":"vnc"}'

The answer's path is then /api/v1/nodes/7c9e6679-7425-40de-944b-e07fc1f90ae7/vms/vm-3f9a1c2e/console/vnc?ticket=…. Open it on the same member you asked, which passes the console on to the machine's node. A console on another member always needs a ticket from that same member, asked for with the same key; a token sent on the WebSocket alone is not enough. The member you call needs clustering in its licence, and tenant keys open consoles only on the node that issued them. The machine's node applies its own address allowlist (api_allowed_ips) to your address: if it does not accept it, the ticket and the console are refused with 403 forbidden: source address not allowed. The same limits apply, and the session also closes when either node leaves the cluster.

Limits and timeouts

Sessions per machineUp to 4 graphical sessions (they share the screen) and 1 serial session
IdleA session closes after 30 minutes without input from you. On the graphical console only keyboard, mouse and clipboard count as input — an open, forgotten tab does not keep it alive
TicketSingle use, 60 seconds
Machine stops or is deletedIts sessions close, with the reason
The key is revokedA session lasts only as long as the key or token that opened it (the one that asked for the ticket, or the one sent on the WebSocket). Revoking it — or a tenant key expiring — closes the session within a few seconds, and an unused ticket it asked for is refused
Web console sign-outA session opened from the web console closes when you sign out or that sign-in ends (idle, 12 hours)
Tenant suspendedA session opened with a tenant's ticket closes within a few seconds of the tenant being suspended or closed, or of the machine no longer being the tenant's
Agent restarts or updatesSessions close ("the agent is stopping"); the machine keeps running. Reconnect once the agent is back

A session ends with a normal close whose reason says why, in plain words. A console that cannot be opened is refused with a plain reason; the details are in the agent's log.

The licence

Opening a console changes nothing on the node, so it is treated like looking at a machine: it works while the licence is frozen, and on a plan without Compute, as long as the machine exists (and runs). Getting a ticket works the same way. Starting, stopping and changing machines still need an active licence that includes Compute.

Every session is recorded

Opening, closing and every refusal are recorded in the node's audit log (who, from where, which machine and console, how long it was open — see Monitoring), written to the agent's log as audit entries (audit=true, with the bytes each way) and published as compute.console_opened and compute.console_closed events, so the event stream and webhooks carry them.

See also

↓ This page as JSON ↓ All documentation as JSON