ova2xva: migrate VMs from VMware/VirtualBox to XCP-ng with one command

Mascote do LinuxPro convertendo um pacote OVA em XVA para importar no XCP-ng

Moving a VM from VirtualBox or VMware to XCP-ng (or XenServer) usually turns into a ritual: export OVA, convert the disk manually, wrestle with xe. The ova2xva is a CLI in Go (MIT) that handles both directions in a single binary — it converts OVA or a standalone disk to XVA, validates it, imports it via XAPI and, if needed, returns a portable OVA. Without the xe binary in the process.

The code and releases are at github.com/jniltinho/ova2xva. The current version of the official binaries is v0.4.0 (August 1º, 2026).

What it does

Command Function
convert OVA or standalone disk (.vmdk, .qcow2, .vhdx…) → .xva (compression zstd by default)
to-ova The reverse: .xva or disk → .ova (OVF 1.0 + stream-optimized VMDK + SHA-256 manifest). Requires qemu-img
validate Checks the structure and SHA1 of .xva
import Uploads to XCP-ng/XenServer with HTTP PUT /import (XAPI) — without xe

VMDK, QCOW2, and VHDX decoding is native in Go. The qemu-img is used as a fallback and is required in to-ova (it generates the VMDK). Classic VHD and VDI also go exclusively through qemu-img; .raw/.img use direct copying.

In practice

# OVA do VirtualBox/VMware → XVA
ova2xva convert -o app.xva --name "App Server" app.ova

# Disco solto, sem OVA
ova2xva convert -o app.xva --name "App Server" --memory 4096 --vcpus 2 disk.vmdk

# Validar (opcional)
ova2xva validate app.xva

# Importar no XCP-ng e já ligar a VM
export OVA2XVA_HOST=xcp.example.com OVA2XVA_USER=root OVA2XVA_PASSWORD='...'
ova2xva import --start app.xva

# O caminho contrário: sair do Xen com um OVA portátil
ova2xva to-ova -o app.ova app.xva

Two details the README makes explicit that save you from surprises:

  • the output extension of convert is always .xva — -o foo.xva.zst becomes foo.xva;
  • the guest disk is expanded to raw at its virtual size in the working directory. A 5 GB OVA with a 100 GB disk needs ~100 GB of temporary space plus the final XVA.

Installing

Using the release binary (Linux amd64):

curl -LO https://github.com/jniltinho/ova2xva/releases/download/v0.4.0/ova2xva_0.4.0_linux_amd64.tar.gz
tar -xzf ova2xva_0.4.0_linux_amd64.tar.gz
sudo install -m 755 ova2xva /usr/local/bin/ova2xva
ova2xva version

Or building from source — Go 1.22+ and qemu-utils (the Debian/Ubuntu package that provides qemu-img):

sudo apt install golang-go qemu-utils
git clone https://github.com/jniltinho/ova2xva
cd ova2xva && make build    # → dist/ova2xva

When to use

  • Moving to Xen from a VirtualBox/VMware OVA or a standalone disk without building a pipeline of qemu-img + xe vm-import;
  • Moving away from Xen with to-ova for portable backups or to move the VM to another hypervisor;
  • Importing from any Linux machine with network access to the host — import speaks XAPI and does not need xe installed on the workstation.

It is not a replacement for an orchestration tool like Xen Orchestra. It is a file converter + importer. The broader history of the hypervisor is in The history of Xen and, for KVM on the desktop, in The history of Proxmox.

Bugs and PRs

The project is MIT-licensed, by Nilton Oliveira. Test it with real VMs, open an issue for an edge case and, if you find it useful, leave a star: github.com/jniltinho/ova2xva.