Multi-Node Dispatch
This page explains how go-pve-qemu finds which node hosts a VM and decides whether to run qm locally or over SSH.
Locating a VM's Node
The service scans /etc/pve/nodes/*/qemu-server/*.conf (the Proxmox cluster filesystem, synced to every node) and derives a node-to-VMID mapping from the path:
/etc/pve/nodes/pve2/qemu-server/120.conf → VMID 120 lives on pve2
Where Commands Run
| Condition | Execution |
|---|---|
VM's node = MAIN_NODE |
Local qm <args> |
Another node with a matching NODE_<node> |
ssh root@<NODE_node> qm <args> |
MAIN_NODE unset, or no NODE_<node> |
SSH runs with an empty host and the command fails |
SSH always carries these options so no interactive prompt can block the API:
-o ConnectTimeout=10
-o StrictHostKeyChecking=no
-o UserKnownHostsFile=/dev/null
-o BatchMode=yes
Operations Using Dispatch
| Operation | qm subcommand |
|---|---|
| start | qm start |
| stop | qm stop |
| shutdown | qm shutdown |
| reboot | qm reboot |
| destroy | qm destroy |
| set/cpu | qm set --cores |
| set/memory | qm set --memory [--numa --balloon] |
| set/disk | qm disk resize scsi0 +<size> |
| set/node | qm migrate <vmid> <node> --with-local-disks |
Exceptions
- Install:
qm create,importdisk, andqm setalways run locally on the main node; withnodeset, migration happens after creation, and only start and reboot go through dispatch GET /vm/:id/status: runsqm statuslocally on the main node only, so querying a VM on another node fails- VM list: reads cluster-wide data via
pvesh get /cluster/resourcesand needs no dispatch
Migration
POST /api/vm/:id/set/node requires a stopped VM, moves local disks with --with-local-disks, and streams qm migrate output line by line over SSE.