Citrix XEN to Linux KVM
Although I have been using KVM, (Linux Based Kernel Virtualization), on my own infrastructure for some time, it is only recently, (past 4 years), that I have comfortable enough with it to use it in production for my clients, especially when other admins would be involved with administration of the systems. A choice I often made was to use Citrix XEN, as it…
- Has a commercially supported version should my client decide to stop using me.
- Has a fully free and open version which for the most part is not cobbled, at least it has all the core functionality that my clients need.
One thing that always frustrated me about it was the fact I needed to use a Windows machine to use access its management interface, yes there is a commmunity driven linux version but never worked quite well.
Anyway one of the clients where I had used Citrix XEN, is now ready for an upgrade and I found myself in a situation where I needed to move virtual machines from XEN to KVM. It took quite a bit of digging and experimenting but this is what I came up with.
First of all you need to gather three pieces of info:
- HOST-UUID
[root@xenhost ~]# xe host-list uuid ( RO) : 181d1fa8-ef74-43ed-ac51-67c80717f6f0 name-label ( RW): uhu-xen-01 name-description ( RW): Uhurulabs XEN Server
- NETWORK-UUID
uuid ( RO) : 52ce1f9d-faeb-f1e8-7054-505ac2ace647 name-label ( RW): Pool-wide network associated with eth1 name-description ( RW): bridge ( RO): xenbr1 uuid ( RO) : 2014eeb6-6f09-d3bf-88e4-1a0978ee8df7 name-label ( RW): Host internal management network name-description ( RW): Network on which guests will be assigned a private link-local IP address which can be used to talk XenAPI bridge ( RO): xenapi uuid ( RO) : eb57b4d8-7656-c607-b1cc-93cfd8766afe name-label ( RW): Pool-wide network associated with eth0 name-description ( RW): bridge ( RO): xenbr0
- VDI-UUID
uuid ( RO) : fd6a4413-16ed-45ac-b206-c1587105ffb9 name-label ( RW): windows_srv_2008_std.iso name-description ( RW): sr-uuid ( RO): 05f8b9fd-438c-42ed-9da0-56c24c9ad13e virtual-size ( RO): 3166896128 sharable ( RO): false read-only ( RO): true uuid ( RO) : 5c9595df-f6d9-4a17-8de9-e53a611308f0 name-label ( RW): CentOS-6.0-x86_64-bin-DVD2.iso name-description ( RW): sr-uuid ( RO): 05f8b9fd-438c-42ed-9da0-56c24c9ad13e virtual-size ( RO): 1182699520 sharable ( RO): false read-only ( RO): true uuid ( RO) : 2713e717-8847-4d1c-abb8-4725a0ce1d88 name-label ( RW): THIS IS THE MACHINE WE WANT TO EXPORT name-description ( RW): Created by template provisioner sr-uuid ( RO): 4f02d7e3-67b6-3d14-9533-ebfb4fa323f8 virtual-size ( RO): 53687091200 sharable ( RO): false read-only ( RO): false
So now we know that
- HOST_UUID is 181d1fa8-ef74-43ed-ac51-67c80717f6f0
- VDI-UUID is 2713e717-8847-4d1c-abb8-4725a0ce1d88
- NETWORK-UUID is eb57b4d8-7656-c607-b1cc-93cfd8766afe
We now need to tell the XEN Server to put the machine in “transfer” mode, NOTE that this will make the machine unavailable for the duration of the export process.
xe host-call-plugin host-uuid=181d1fa8-ef74-43ed-ac51-67c80717f6f0 \ fn=expose args:vdi_uuid=2713e717-8847-4d1c-abb8-4725a0ce1d88 \ args:network_uuid=eb57b4d8-7656-c607-b1cc-93cfd8766afe \ args:transfer_mode=http plugin=transfer
As we are going to do the transfer over HTTP we need to find out the correct URL to access
xe host-call-plugin host-uuid=181d1fa8-ef74-43ed-ac51-67c80717f6f0 \ plugin=transfer fn=get_record args:record_handle=af2eed01-b162-b37a-982c-4536dd2b5bc3 ?xml version="1.0"?> <transfer_record username="47b5ebf70160c752" status="exposed" url_path="/vdi_uuid_2713e717-8847-4d1c-abb8-4725a0ce1d88" record_handle="af2eed01-b162-b37a-982c-4536dd2b5bc3" device_2713e717-8847-4d1c-abb8-4725a0ce1d88="xvdb" url_full_2713e717-8847-4d1c-abb8-4725a0ce1d88="http://47b5ebf70160c752:f2b25a5854c12b76@192.168.13.88:80/vdi_uuid_2713e717-8847-4d1c-abb8-4725a0ce1d88" ip="192.168.13.88" transfer_mode="http" url_path_2713e717-8847-4d1c-abb8-4725a0ce1d88="/vdi_uuid_2713e717-8847-4d1c-abb8-4725a0ce1d88" all_devices="xvdb" url_full="http://47b5ebf70160c752:f2b25a5854c12b76@192.168.13.88:80/vdi_uuid_2713e717-8847-4d1c-abb8-4725a0ce1d88" device="xvdb" use_ssl="false" password="f2b25a5854c12b76" port="80" vdi_uuid="2713e717-8847-4d1c-abb8-4725a0ce1d88"> </transfer_record>
Now we have the URL: http://47b5ebf70160c752:f2b25a5854c12b76@192.168.13.88:80/vdi_uuid_2713e717-8847-4d1c-abb8-4725a0ce1d88, we can now use curl to get the image
curl http://47b5ebf70160c752:f2b25a5854c12b76@192.168.13.88:80/vdi_uuid_2713e717-8847-4d1c-abb8-4725a0ce1d88 -o machine_raw_disk.raw
You can now import machine_raw_disk.raw as a new image into KVM!