Linode is, in my opinion, the best webhost out there. I recently switched this site from Wordpress to Drupal. In preparation for this switch, I wanted to be able to start with a clean slate - wipe the O/S and all, and install Drupal on top of that. Since I'm a sysadmin, I hate downtime! Read on to learn how I made my Linode portable. Linode is a provider of Xen-based vm's. The intelligent way that they have provisioned their machines gives you a way to clone your VM. Using this idea, I was able to take an image of a Linode-ized CentOS installation, and run it as a VM under Xen on a spare workstation at home. I configured this Xen VM at home, but with every change I made to the image I updated a shell script to do the same. When I had my VM at home ready to go, I sufferred only 5 minutes of downtime while my Linode was being reconfigured! Here's the specifics on how to do this yourself.
Setup Finnix on your Linode
Follow the instructions for "Setting It Up" from the Linode Wiki article.
Setup the base OS
In your Linode dashboard, click "Deploy a Linux Distribution", and select settings like the ones in this screenshot: Now, after creating the partition, rename it to something like "Virgin CentOS Image", and resize it as small as it can go - I used 600M for mine. After resizing the partition, create a new raw partition of 10GB or so - I use this as an LVM partition and it's where I install all of my custom applications. Now, we need to make these new partitions available to your existing VM (or Finnix if this is your first). From the dashboard, click on the Finnix profile (or your custom profile) to edit it. Under the drive setup area, set /dev/xvdg to be the "Virgin CentOS Image" from above, and set /dev/xvdh to be the raw partition from above. If you changed settings to a profile that was already running, you need to reboot for the settings to take effect.
Setup your Xen server at home
For me, I just popped in a Centos 5.2 CD, and installed the base OS plus the virtualization package. Do not partition all the drive space, leave enough unpartitioned space to equal that of what you're using for your raw partion on your Linode. Once you've booted, we need to setup our raw partition space to use as swap and applications to the domU. Depending on your hard drive size and partition layout, there's no copy and paste solution for this. If you're geek enough to want to do this, you know how to use fdisk, don't you? For the sake of this article, /dev/hda3 is a 512M swap partition(type 82), and /dev/hda5 is a LVM partition of 10GB (type 8e).
Make the base image
Now, we need to make a file-backed image of the CentOS installation on our Linode. At the same time, we will create a gzipped backup so we have something local to restore from if we hose something up or want to test our provisioning script. On your Xen server at home, run the following as root:
mkdir -p /var/vms/linode-clone/ cd /var/vms/linode-clone/ ssh email@example.com "dd if=/dev/xvdg bs=102400" | gzip -dc | dd of=root.img bs=102400 gzip -c root.img > virgin.img.gz dd if=/dev/zero bs=1048576 count=2000 >> root.img e2fsck -f root.img resize2fs -p root.img Phew! What did that do? The ssh + dd command made a bit for bit copy of the virgin partition on your Linode, and created a file on the local host with it's contents. The gzip command made a compressed copy of the image to restore from later. The dd using /dev/zero padded the end of that file by 2GB, giving us 2GB at the end of the partition to work with. The e2fsck and resize2fs updated the filesystem contained within that file to the new size. Now, on to setting up our kernel.
We need to grab a copy of the kernel source from Linode, and build it for our Xen domU. You can browse the Linode kernels at http://www.linode.com/src. I recommend 220.127.116.11-linode10.tar.bz2. From your Xen server, run the following:
yum install gcc gcc-c++ kernel-devel mkdir -p /usr/src/ cd /usr/src/ wget http://www.linode.com/src/18.104.22.168-linode10.tar.bz2 tar -xjvf 22.214.171.124-linode10.tar.bz2 cd 126.96.36.199-linode10 ssh firstname.lastname@example.org "cat /proc/config.gz" | gzip -dc > .config make oldconfig make cp arch/i386/boot/vmlinuz /var/vms/linode-clone/kernel-188.8.131.52-linode10.gz This creates a kernel identical to the one that your Linode host is running. Next up, setting up our Xen config.
Change to /etc/xen, and create a file named linode-clone. Paste the following into it:
name = "linode-clone" uuid = "a6864d4d-1c6f-ea12-3e08-b6b89015bb77" maxmem = 540 memory = 540 vcpus = 1 kernel = "/var/vms/linode-clone/kernel-184.108.40.206-linode10.gz" root = "/dev/xvda ro" on_poweroff = "destroy" on_reboot = "restart" on_crash = "restart" vfb = [ ] disk = [ "file:/var/vms/linode-clone/root.img,xvda,w", "phy:/dev/hda3,xvdb,w", "phy:/dev/hda5,xvdc,w" ] vif = [ "mac=00:16:3e:57:53:3f,bridge=xenbr0" ] extra = "xencons=tty"
At this point, you should have a Xen domU ready-to-run. To boot your Xen VM and attach a console, run this:
xm create -c linode-clone
It should boot for you, and drop you into a login prompt. Feel free to login as root (using the password specified during the linode setup phase). Make some changes to the filesystem. CTRL+] will disconnect you from the domU console, 'xm console linode-clone' will re-attach. Now, power off your domU by doing a 'shutdown -h now' from within the domU. You can restore back to a virgin install by doing a "gzip -dc /var/vms/linode-clone/linode-virgin-centos.img.gz > /var/vms/linode-clone/root.img" -- make sure the domU is shut down first! When you boot back in by doing a 'xm create -c linode-clone', you'll see that your filesystem changes are gone. Stay tuned for part two, where I'll show you the basics of creating a provisioning script for your domU. Part three will then cover how to push your local images back up to your Linode.
Scattered throughout this post are links to Linode. If you're not a customer and would like to be, please consider clicking on one of those links to sign up. It will cost you nothing, but will give me a $20 credit on my account if you sign up and stay a customer for 90 days.