
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
convertis always.xva—-o foo.xva.zstbecomesfoo.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-ovafor portable backups or to move the VM to another hypervisor; - Importing from any Linux machine with network access to the host —
importspeaks XAPI and does not needxeinstalled 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.