Convert KVM VMs to Citrix XenServer

Attach External Hard Drive or External Storage

For the purposes of this task you will want to attach some sort of removable storage. An easy way to determine what the device the storage shows as run the following before attaching the storage:


make note of the last /dev/sd# device you see. Now plugin your external storage and run the same command, you should see a new entry there that should be your path you will want to use in the next step (ex: /dev/sdd1)


Next we will mount the external storage to /mnt

mount /dev/sdd1 /mnt


List the LV Info

On the KVM host you wish to copy the VM from list the lv information


You should see a path like /dev/KVM/vmname.

Convert Raw LVM to VHD

Using the qemu-img utility you will need to run the following:

qemu-img convert -O vpc /dev/vg_name/lv_name /mnt/vmname

You can also convert to other formats as listed belelow:

Disk Format
QEMU -O Argument
Disk Format
QEMU -O Argument
qcow2 (Xen/KVM) qcow2
QED (KVM) qed
raw raw
VDI (vbox) vdi
VHD (Hyper-V/Citrix Xen) vpc
VMDK (VMWare/eSXI) vmdk

Once the disk is converted and on your external storage you will want to exit the /mnt directory and unmount

cd /
umount /mnt


Import to Citrix XenServer

Attach the external drive and mount it similarly to how you did in step 1, however you will need to check and see what device this shows up as, it will likely be /dev/sdb1. Mount this to the /mnt location.


Next we will need to identify the UUID of the storage repository in Xen we are going to use by UUID:

xe sr-list

Using the UUID from above create a global variable using the following:

RESTORE=$(xe vdi-create sr-uuid=<UUID of SR from above> name-label=<vmname> virtual-size=<size of drive +1 gb>GiB)

This will create an object named restore in your storage repository. Next we will want to import the VHD

xe vdi-import filename=/mnt/<vmanme> format=vhd --progress uuid=$RESTORE

Once the import completes you will want to create a new VM in Xen but not start it. After the VM creates you will want to remove the delete the hard drive associated with the VM on the storage tab. Once you do this click “attach disk” and select the disk you imported. Once this is attached you can start the VM and you should be good to go. Note on Windows systems and some linux systems you may need to update the network settings. Once this is done install Guest Tools, reboot and you’re all set.

Uploading Hyper-V VHDs to Azure

I recently had a project I was working on in which some inherited Azure VMs were missing the Azure agent and nobody knew the passwords for them. After a quick support call to MS it became apparent I would have to delete the VMs and preserve the disks, download disks, load into hyper-v and manually reset the password. In doing this I learned a few gotchas such as not being able to convert the VHD into a bootable Azure disk unless uploading through the Azure Powershell CLI. Here’s my quick how to upload disks guide.

Installing Azure Powershell

First we will need to install the Azure Powershell Module. This can be accomplished by running Powershell as administrator and entering the following:

Install-Module Azure

When prompted press choose A for yes to all. 

Note: If there is any conflict you may need to add the -AllowClobber to the end of the command above.


Login To Azure and Get Publish Settings File

First you will need to log into Azure by entering the following in Powershell


At this point you will be prompted to log into Azure. 


The next step will be to get an Azure Publishing Settings file. You can do this by entering the cmdlet below and then importing the file with the following cmdlet:


Import-AzurePublishSettingsFile -PublishSettingsFile “<path to file>”


Select Your Subscription and view Storage Accounts

At this step we will choose which subscription to use (if you have more than one) and list storage accounts so that we know where to upload the disks to. 

Warning: If you attempt to upload the VHD through the web GUI instead of using this method it will be created as a block blob not a page blob which prevents you from being able to convert it to a bootable disk for use in the gallery. The only way to do this correctly at the time of this writing is through the Powershell API.


Select-AzureSubscription -SubscriptionId <enter yours here>



Uploading The Azure VHD and Converting It

At this point we are setup for the part we’ve all been waiting for. Make sure your VHD is not thin provisioned and that the VM has the Azure Agent installed and has been sys prepped (if using as a template).

Add-AzureVhd -LocalFilePath “<file path to your VHD>” -Destination “<URL of storage location with your filename after the last />”

This will create an MD5 hash and upload the disk. 


To convert the disk we will want to run the following:

Add-AzureDisk -Diskname ‘<name your disk something relevant>’ -MediaLocation ‘<URL where your disk lives in azure storage>’ -Label ‘<label>’ -OS <Choose Windows or Linux>

Atlassian Bamboo Server Github Issues

As any of you who have been using Atlassian’s cloud offering of Bamboo know, it is going EOL at the end of January 2017. The migration has reasonably decent instructions to follow, but my migration ran into a big road block when linked repositories failed when choosing Github as the repository host with a 403 forbidden. The 403 forbidden is actually in relation to a javascript error and not the actual reason that this is failing. Tailing the output of the catalina.out revealed the issue was actually related to cross site request forgery issues. The reason this was happening is that I had setup nginx as an https proxy on 443 that routes traffic to 8085 on Tomcat.


I found the following link that indicates the resolution is to insert the following into your server.xml file


What was not terribly obvious in this documentation what what section this should go into. The section this should be placed in is the <Connector section within server.xml, see example below:


<Connector port="8085"

Last but not least don’t forget to restart the service for this to take effect. Hopefully this saves you hours of headache in your migration!