Intro
This document explains how to setup xen-tools to generate Xen domU images for Debian lenny that will boot with pygrub.
I assume you have your dom0 running on lenny and that you have xen-tools (and other essentials) installed. If you don't, follow Dom0 part of this guide and then come back.
Step1: pygrub location fix
You should have pygrub by now, as part of xen-utils-3.2-1 package. Unfortunately it's in wrong place. This:
ln -s /usr/lib/xen-3.2-1/bin/pygrub /usr/bin/
will fix that.
Step2: xen-tools configuration
In order to boot with pygrub, you gotta have specific setup.
Your /etc/xen-tools/xen-tools.conf should look like this:
lvm = VOLUME_GROUP install-method = debootstrap size = 100Gb # Disk image size. memory = 2Gb # Memory size swap = 4Gb # Swap size fs = ext3 # use the EXT3 filesystem for the disk image. dist = lenny # Default distribution to install. image = sparse # Specify sparse vs. full disk images. gateway = GATEWAY_IP netmask = 255.255.255.0 broadcast = BROADCAST_IP arch=amd64 mirror = http://ftp.cz.debian.org/debian/ ext3_options = noatime,nodiratime,errors=remount-ro ext2_options = noatime,nodiratime,errors=remount-ro xfs_options = defaults reiser_options = defaults serial_device = hvc0 disk_device = xvda
Absolutely crucial is the fact "kernel" and "initrd" are undefined.
In addition to that you have to have following script named /etc/xen-tools/role.d/pygrub:
#!/bin/sh
#
# Configure the new image to be suitable for booting via pygrub
#
# Wejn
# --
# http://wejn.org/
#
prefix=$1
#
# Source our common functions - this will let us install a Debian package.
#
if [ -e /usr/lib/xen-tools/common.sh ]; then
. /usr/lib/xen-tools/common.sh
else
echo "Installation problem"
fi
#
# Update APT lists.
#
chroot ${prefix} /usr/bin/apt-get update
#
# Install the packages
#
set -e
installDebianPackage ${prefix} perl
installDebianPackage ${prefix} libklibc
installDebianPackage ${prefix} klibc-utils
installDebianPackage ${prefix} initramfs-tools
installDebianPackage ${prefix} linux-image-2.6-xen-amd64
# Force initrd if none exists
echo ${prefix}/boot/initrd* | grep -q 2\\.6
if [ $? -ne 0 ]; then
chroot ${prefix} update-initramfs -c -k `ls -1 ${prefix}/lib/modules/ | head -n 1`
fi
# Generate grub menu.lst
LNZ=`basename \`ls -1 ${prefix}/boot/vmlinuz*|tail -n 1\``
RD=`basename \`ls -1 ${prefix}/boot/initrd*|tail -n 1\``
mkdir -p ${prefix}/boot/grub
cat - <<-EOF > ${prefix}/boot/grub/menu.lst
default 0
timeout 5
title Debian
root (hd0,0)
kernel /boot/$LNZ root=/dev/xvda2 ro
initrd /boot/$RD
EOF
with executable permissions.
You can install it via:
curl -s http://wejn.org/stuff/pygrub-role > /etc/xen-tools/role.d/pygrub chmod a+x /etc/xen-tools/role.d/pygrub
or just download and install it yourself.
This role script will setup the pygrub boot environment within newly created guest.
Step3: new guest creation
To create pygrub-bootable guest, just create new image using pygrub and udev roles:
xen-create-image --hostname=HOSTNAME --ip=IP_ADDRESS --role=udev,pygrub
After guest creation finishes, you have to do one small change to the resulting config -- the root block device has to be listed first. By default xen-tools set swap first which breaks pygrub.
To automate you can use following script:
sed -i '/phy:.*swap/{h;d};/phy:.*root/G' /etc/xen/CONFIGNAME.cfg
Step4: launch
Now do a:
xm create hostname -c
and it should boot up just fine; using the kernel within guest's partition.
Conclusion
It wasn't that hard, was it?
Update: How to do the same on Ubuntu 10.04
Adarsh Carter sent me following how-to explaining steps to achieve the same result (and more) on Ubuntu 10.04.