Tag Archives: XenServer

Import disk image into XCP-ng/XenServer

Importing a disk image into XCP-ng/XenServer is rather easy, you just need to find the correct VDI and import it using the appropriate `xe vdi-import`. In my case I wanted to test the current OpenWRT release, so:

# xe vdi-list
uuid ( RO)                : <vdi-uuid>
          name-label ( RW): OpenWRT
    name-description ( RW):
             sr-uuid ( RO): <sr-uuid>
        virtual-size ( RO): <size>
            sharable ( RO): false
           read-only ( RO): false

# xe vdi-import uuid=<vdi-uuid> filename=openwrt-combined-ext4.img

That’s it: OpenWRT is installed on Xen and already bootable. At this point you can even mount the OpenWRT drive and resize its partition to fully use the remainder of the space you allocated.

XenServer GrubConf.py fix script

In a previous article (Fixing XenServer error “Unable to find partition containing kernel”) I described how to fix a recurring problem after patching XenServer 6.2 installations. While the fix is known from years it’s never been adopted, and different distros (such as Ubuntu LTS 14.04) fail to boot properly when the GrubConf.py (on dom0) gets reset to its default state.

Being the lazy person that I am I decided to set up a script to do the work for me, after all we’re admins, not monkeys.

#!/bin/bash
GRUBCONF="/usr/lib/python2.4/site-packages/grub/GrubConf.py"
PATCHED=$(grep "_entry" $GRUBCONF | wc -l)
if [ $PATCHED -eq 2 ]; then
  echo "GrubConf.py is already patched"
else
  echo "Patching GrubConf.py to fix boot..."
  sed -i 's/_entry}":/_entry}":\n                        arg = "0"\n                    elif arg.strip() == "${next_entry}":/' $GRUBCONF
  PATCHED=$(grep "_entry" $GRUBCONF | wc -l)
  if [ $PATCHED -eq 2 ]; then
    echo "- Patch was applied successfully."
  else
    echo "- There was a problem while applying the patch."
  fi;
fi;
echo

This does just what I/we used to do manually: detects if GrubConf.py has been reverted and, if not, patches it up. Supplementary tests added for paranoia 🙂

Solution to XenServer VM landing on initramfs

In my journey through XenServer lands, I once experienced a change in the UUID of the root partition, which resulted in a failed boot and being dropped into initramfs. Although this solution should have worked just fine, I either didn’t know of it at the time or it wouldn’t work for some reason.

While inside the VM initramfs I also had the pleasure of not having any text editor of sorts: no vi, no vim, no nano. Nothing at all. Even though I found the new UUID through the use of ls -al /dev/disk/by-uuid/ (and some guesswork), I had no way to edit the grub configuration. So, after some trial and error, I came up with the following:

(initramfs) mount /dev/xvda1 /mnt; cd /mnt
(initramfs) cp grub.cfg grub2.cfg
(initramfs) cat grub2.cfg | sed s///g > grub.cfg

After the proper root partition UUID was set in place, a reboot was all it took to set the machine back up and running.

Fixing XenServer error “Unable to find partition containing kernel”

Edit: I provided a scripted solution in this article. To know why the error happens and its fixes just keep reading.

Error: Starting VM ” – The bootloader for this VM returned an error — did the VM installation succeed? Unable to find partition containing kernel

This has been the major nightmare I had so far with XenServer machines. When upgrading distros it might just so happen they will refused to boot forever after, in my case it affects Ubuntu 14.04.x, not officially supported. Let’s look at the solutions.

Modifying GrubConf.py

Although the fix is in Citrix’s repository since 2012, give or take, it has not been streamed to the executables yet for some uncertain reasons. If you open /usr/lib/python2.4/site-packages/grub/GrubConf.py at line 428 you see:

if arg.strip() == "${saved_entry}":
    arg = "0"

This causes a problem during the parsing and two lines should be added:

if arg.strip() == "${saved_entry}":
    arg = "0"
elif arg.strip() == "${next_entry}":
    arg = "0"

After the file has been modified and saved you will be able to properly start the virtual machines. This holds currently true for Ubuntu 14.04 & 14.04.1 LTS server installations, but might also work for other distributions. Also take in consideration that applying some patches to the host might revert this change, so you might need to do it again at some point in the future.

Modifying grub.cfg

This might not be enough if the problem does not relate to PyGrub but rather to the configuration file itself. While on the host machine, you can run the following command:

# EDITOR=vi xe-edit-bootloader -n  -p 1

This command will prepare and mount the drives assigned to the virtual machine, edit the boot loader configuration in vi and after quitting from vi will unmount and cleanup. If you installed Grub2 or you made mistakes in its configuration, this will allow you to edit it from inside the host machine, after which you will be able to properly boot it up.

Mass XenServer updates with batch script

I was looking for a way to optimize (read: not doing repetitive tasks by hand) the patches upload on my XenServer machine. I based it off a script, shown in this article, that I modified slightly for my lesser needs and built it around a Win7 XenCenter installation.

@echo off
set XE="C:\Program Files (x86)\Citrix\XenCenter\xe.exe"
set Patch=<\\FILESERVER\PathToUpdates\|DRIVE:\LocalPathToUpdates\>
set Server=-s  -u  -pw 
set HostID=

if not "%1"=="" goto :Patch

del "%Patch%*.bz2" >nul 2>&1
for %%f in ("%Patch%*.zip") do %XE% %Server% patch-upload file-name="%Patch%%%~nf.xsupdate"
echo -- Run the command again passing the IDs as parameters
goto :End

:Patch
echo -- Now installing: %1
%XE% %Server% patch-apply host-uuid=%HostID% uuid=%1
shift
if not "%1"=="" goto :Patch

:End

The first four parameters are shortcuts to the xe.exe, the path to the patches location, the remote server data and finally the UUID of the XS host. I download the packages in the directory and unzipped its content. When the script is ran without parameters it will remove any sources package I might have mistakenly extracted, it scans the path for any and all ZIP packages and, based on their names, uploads the extracted XSUPDATE to the XenServer host, returning a list of patch UUIDs. After that I can launch the script again passing a parameter list with the returned patch UUIDs, and it will cycle through them all and apply them. After they have been applied correctly I can reboot the XenServer host and delete the ZIP packages.

This is a bit rough around the edges, but it works when you only have a handful machines to upgrade. There is a lot of room for improvement though, and I might get back to it at a later date.