Skip to main content

Orphan VM Import

Overview

Orphan VM Import is an admin-only workflow that lets the panel adopt KVM virtual machines that already exist on a hypervisor but are not yet tracked in the database. Typical sources:

  • VMs that existed on the host before the slave agent was attached.
  • VMs created directly with the virsh command-line tool.
  • VMs migrated in from another control panel.

The import is non-destructive. Nothing on the hypervisor is moved, renamed, copied, or restarted. The VM keeps running through the import.

Concepts

  • Domain: libvirt's name for a single VM. (Libvirt is the management daemon that controls KVM on each host.)
  • qcow2: the standard disk-image file format for KVM VMs.
  • Storage row: a record in the panel that tells it which directory on the hypervisor holds disk files. The import needs every disk to either match an existing storage row or have a new one created.
  • Pending Assignment: the holding state an imported VM lives in until an admin assigns it to a real user.
  • Synthetic plan: a per-VM plan auto-created during import that mirrors the actual CPU, RAM, and disk size of the imported VM. It is hidden from customer plan listings.

Eligibility

When you scan a hypervisor, the panel inspects every libvirt domain the panel does not already track. For each domain it reads the libvirt XML, runs qemu-img info against each disk, and runs virsh domifaddr to collect any guest-reported IP addresses.

A domain is eligible only when every disk meets both:

PropertyRequired value
Disk formatqcow2
BackendRegular file on the host filesystem

Anything else (LVM, ZFS, raw block devices, Ceph RBD) is reported with a "Skipped: ..." reason. Cloud-init or config ISOs, commonly attached as sdx, ending in .iso, or with paths containing cidata or cloudinit, are auto-excluded from eligibility and listed under a separate "CDROMs (excluded)" group.

The VM's runtime state (running, paused, shut off) does not affect eligibility.

Admin: discovering orphan VMs

  1. Open Hypervisors > Hypervisor and pick the host.
  2. Scroll to the Orphan VMs card (below GPU Devices).
  3. Click Scan for Orphan VMs. A progress bar appears while libvirt domains are inspected; the panel updates in real time over WebSocket.

Each row shows:

  • Domain name (the libvirt name, for example h1631).
  • Runtime state (running, paused, shut off).
  • vCPU count and RAM size.
  • A badge per disk classifying it.
  • An Import button (eligible) or a "Skipped: ..." reason (ineligible).

Clicking a domain name opens a side panel with the full inspected payload: every disk, every NIC (network interface card) with detected guest IPs, and the libvirt VNC port (VNC is the remote-screen protocol used to view the VM's display).

Scan results are cached for one hour. Click Re-scan to refresh.

Admin: importing a single VM

Click Import on an eligible row. The import dialog opens and lists every disk:

  • Disks whose directory matches an existing storage row get a green Matched: StorageName badge. No action needed.
  • Disks whose directory does not match any storage row are tagged Needs assignment. For each:
    • Use existing: pick an existing storage row.
    • Create new: register the disk's directory as a brand new storage row. Edit the suggested name and path, then confirm.

Confirm the dialog. The VM is imported:

  • Owner is set to a system "Orphan Imports" user (suspended; never logs in).
  • Plan is a synthetic per-VM plan named imported-hypervisor-domain carrying the actual CPU, RAM, and disk size of the VM. The plan is hidden from customer plan listings.
  • Status reflects the libvirt runtime state.
  • The instance carries a Pending Assignment flag.

Admin: bulk import

If at least two rows have every disk already matched to an existing storage, an Import All Eligible (n) button appears below the table. Click it to import each eligible row in sequence. Rows that need storage assignment are skipped with a warning toast; open them one at a time to choose storage.

Admin: the Pending Assignment banner

Imported instances display a banner at the top of their admin manage page:

Pending assignment

This instance was imported and is pending user assignment. Click Assign User in the banner to open the assignment modal, then optionally pick a real plan and add IPs.

Customers never see this banner; the synthetic owner is suspended.

Admin: assigning a user (and plan)

Click Assign User on the banner.

  • User (required): pick any real user on the platform.
  • Plan (optional): defaults to the synthetic per-VM plan. Pick a real plan to replace it.

On submit:

  • The instance's owner becomes the chosen user.
  • The Pending Assignment flag clears and the banner disappears.
  • If a real plan was picked, the synthetic imported-... plan is soft-deleted (it has no other instances by construction). If you kept the synthetic plan, it stays attached.

Limitations (v1)

What is not supported yet
  • Non-qcow2 disks (LVM, ZFS, raw block, Ceph RBD) are reported but not importable. Convert to qcow2 first.
  • The panel will not run qemu-img convert for you.
  • Scan one hypervisor at a time; there is no bulk multi-hypervisor scan.
  • Only IPs already detected on the guest (via qemu-guest-agent or DHCP lease) are linked, and only when they fall inside a subnet you already have on the hypervisor. Unmatched IPs are written to the import task log; assign them by hand afterwards.
  • Existing libvirt snapshot history is not adopted. Only the current disk state is imported.
  • CDROM and floppy devices are listed informationally and excluded from the imported disk list.
Missing a domain you expected

Check that the slave on that hypervisor is online and that the domain's libvirt UUID and name do not already match an instance the panel manages.

Re-importing after hard delete

If you destroy an imported instance and then want to re-adopt the same domain, the destroy flow cleans up the panel's records but leaves the actual qcow2 disks and the libvirt domain in place. Run Scan for Orphan VMs again. The domain reappears in the list and can be re-imported. There is a guard that refuses to re-adopt a domain currently tracked as a non-trashed instance on the same hypervisor.

Troubleshooting

Discovery completes but the table is empty

The panel already tracks every domain on this hypervisor. Confirm by listing instances on the hypervisor manage page.

A specific domain shows "Skipped: ..." but should be importable

Click the domain name to open the side panel and read the per-disk classification. The skip reason is shown next to each unsupported disk. Most common cause: one disk on a non-qcow2 backend (LVM volume, raw block). Convert to a qcow2 file before re-scanning.

Import dialog says "No existing storages, switch to Create new"

The hypervisor has no storage rows that cover the disk's directory. Either register a new one from the dialog (recommended) or add a storage row first under Hypervisors > Hypervisor > Storage.

A detected IP is not linked

Either qemu-guest-agent or the DHCP lease did not report it, or no subnet on the hypervisor contains it. Check the import task log for entries like Found 192.0.2.10 on MAC 52:54:00:aa:bb:01 but no matching subnet on this hypervisor, then assign the IP by hand after the import finishes.

Imported instance fails on power actions, network suspend, or destroy

Update the slave agent. Older slaves expect interface names of the form vir<instance-name> (the literal vir prefix), but imported VMs have libvirt-assigned names like vnet0 that older code paths do not recognize. Update from Hypervisors > Hypervisor > Update Agent.