Converting a virtual disk image: VDI or VMDK to an ISO you can distribute

Why would anyone in their right mind want to convert a VM into an ISO?

Good question, the answer for Conor Fox (who was the inspiration for this post - thanks Conor!) was to distribute his customized TurnKey PostgreSQL image so others could use it.

Distributing an ISO as opposed to a VM image allows it to be installed on any virtualization platform, as well as on bare metal, with the added bonus of running live.

I suppose that's a good enough reason, so lets get to it.


Convert VM disk to raw image and mount it

First we need to get qemu-img, a tool bundled with qemu (KVM's virtualization backend) to convert the VM disk to a raw image, and TKLPatch, the TurnKey customization mechanism to package the ISO.

If you are not using a TurnKey installation, see the TKLPatch installation notes.

apt-get install qemu
apt-get install tklpatch

I'll show how to convert a VMWare VMDK image into raw disk format. If you are using a different virtualization platform such as Virtualbox, see this post on converting a VDI to a raw image.

qemu-img convert -f vmdk turnkey-core.vmdk -O raw turnkey-core.raw

Next, mount the raw disk as a loopback device.

mkdir turnkey-core.mount
mount -o loop turnkey-core.raw turnkey-core.mount

GOTCHA 1: If your VM has partitions, it's a little tricker. You'll need to setup the loop device, partition mappings and finally mount the rootfs partition. You will need kpartx to setup the mappings.

loopdev=$(losetup -s -f turnkey-core.raw)

apt-get install kpartx
kpartx -a $loopdev

# p1 refers to the first partition (rootfs)
mkdir turnkey-core.mount
mount /dev/mapper/$(basename $loopdev)p1 turnkey-core.mount


Extract root filesystem and tweak for ISO configuration

Now, make a copy of the root filesystem and unmount the loopback.

mkdir turnkey-core.rootfs
rsync -a -t -r -S -I turnkey-core.mount/ turnkey-core.rootfs

umount -d turnkey-core.mount

# If your VM had partitions (GOTCHA 1):
kpartx -d $loopdev
losetup -d $loopdev

Because the VM is an installed system as opposed to the ISO, the file system table needs to be updated.

cat>turnkey-core.rootfs/etc/fstab<<EOF
aufs / aufs rw 0 0
tmpfs /tmp tmpfs nosuid,nodev 0 0
EOF

GOTCHA 2: If your VM uses a kernel optimized for virtualization (like the one included in the TurnKey VM builds), you need to replace it with a generic kernel, and also remove vmware-tools if installed.

tklpatch-chroot turnkey-core.rootfs

# inside the chroot
apt-get update
apt-get install linux-image-generic
dpkg --purge $(dpkg-query --showformat='${Package}\n' -W 'vmware-tools*')
dpkg --purge $(dpkg-query --showformat='${Package}\n' -W '*-virtual')

exit


Generate the ISO

Finally, prepare the cdroot and generate the ISO.

tklpatch-prepare-cdroot turnkey-core.rootfs/
tklpatch-geniso turnkey-core.cdroot/

Thats it!

Bonus: By default the ISO will boot automatically. If you want to include the TurnKey bootsplash and bootmenu, extract the cdroot from a TurnKey ISO and tell tklpatch-prepare-cdroot to use it as a template.

tklpatch-extractiso turnkey-core.iso
tklpatch-prepare-cdroot turnkey-core.rootfs/ turnkey-core.cdroot/
tklpatch-geniso turnkey-core.cdroot/

Ever needed to package a VM as a distributable ISO? Post a comment!


Enjoyed this post? Click to get future posts delivered by email or get the RSS feed.
You can follow me on twitter here.

Comments

Guest's picture

Thanks!

Thats excellent Alon, thanks a million!  It wasn't easy was it?!  I'm snowed under right now but I'm really looking forward to trying this out once I'm back in "iso mode".

TKL just keeps on impressing me more all the time.

alon's picture

Every once in a while...

Every once in a while it's fun to tackle an issue like this, so thanks for the inspiration. The gotcha's got me, so I assume they got others as well, which makes this post that much more interesting and useful.

Looking forward to your feedback once you emerge from the snow...
Guest's picture

I'm in the midst of trying

I'm in the midst of trying this and I just now slavishly followed the "GOTCHA 2" suggestion of replacing the VM-optimal kernel with a standard kernel.  However if the ISO is going to be used exclusively for VMs, would it make sense to skip this step?

alon's picture

Virtual kernel does not include squashfs

The virtual kernel does not include squashfs support, so the resulting ISO won't be able to unpack the root filesystem, and the boot will fail.

Also, an ISO can be installed to bare-metal, so it doesn't make much sense to include the optimized virtual kernel even if it was possible (to be complete, it is possible with a couple of workarounds but not worth the effort, and possible side-effects).
Guest's picture

Another scenario

Hi,

Thanks so much for such interesting articles!

I propose another tipical scenario:

- You install a GNU/linux OS at secondary (non bootable) partition on your windows box.

- After try and setup a lot of things you decide to move your Linux instalation to a virtual machine....

The question is:

¿How to convert your secondary nonbootable linux partition to a virtual machine bootable disk???

Cheers,

 

Paco

alon's picture

Process should be very similar

I suppose (without thinking about it too much) that the process should be very similar, minus the VM conversion.

In general it should go something like this:

  • Mount the secondary drive/partition, and copy out the root filesystem
  • Tweak as needed for ISO configuration
  • Generate the ISO

I would be interested to know if you try this, and what the outcome is. Keep us updated.
Guest's picture

I had partial success with

I had partial success with this -- I was able to create an ISO that worked perfectly as a "Live CD".  I was able to run my appliance directly off the ISO.  The configuration console magically included a new "Install to Disk" option.  However when I tried this it got pretty far into the installation -- including seemingly copying the rootfs to the disk -- but then failed while trying to set up grub.

But I'll leave that to another post -- I think even the creation of the "Live ISO" was a good start!

 

Heres another couple of "gotchas" I experienced:

(1) Alon mentioned that you may find you have multiple partitions on your source VMDK.  In fact its probable that you will -- I certainly did on the Turnkey/Postgres-based VM I started with.  However I was using another TKL-based VM as the "working machine" to run the commands on and I had trouble installing kpartx here.  I switched to a Fedora host and was able to install kpartx ("yum install kpartx" iirc) and complete the rest of the procedure here.

(2) When I chrooted to apply the generic kernel to the rootfs, I found that I had no DNS (so apt-get couldn't find repositories).  The same might happen to you depending on how your network is set up.  Assuming the machine you're working on has working DNS, doing the following before you chroot should fix this:

cp /etc/resolv.conf turnkey-core.rootfs/var/run

 (the desired destination of resolv.conf is likely different on a non-TKL-based rootfs).

Hope that helps!  Heres the script I'm running to get as far as the chroot (its more-or-less as per Alon's directions except I've hardcoded the name of the partition in the loop device):

#!/bin/bash

echo Setting up loop device...
losetup /dev/loop0 turnkey-core.raw 

echo Adding a partition device for each partition in the loop device...
kpartx -av /dev/loop0

echo Mounting the first partition \(ie the rootfs\)
mount /dev/mapper/loop0p1 turnkey-core.mount/

echo Copying the rootfs from the mounted partition to the new \(development\) copy of the rootfs
rm -fr turnkey-core.rootfs/
mkdir turnkey-core.rootfs/
rsync -a -t -r -S -I turnkey-core.mount/ turnkey-core.rootfs

echo Cleaning up the mounts and loopback device...
umount -d turnkey-core.mount/
kpartx -d /dev/loop0
losetup -d /dev/loop0

#echo Setting up name resolution on new rootfs \(need this during chroot\)
#cp /etc/resolv.conf turnkey-core.rootfs/var/run

 

 

Guest's picture

mount -o loop

mount -o loop turnkey-core.raw turnkey-core.mount

=

mount: you must specify the filesystem type
 

:-(

 

alon's picture

Raw image has partitions?

Is it possible you were hit by GOTCHA 1, VM has partitions?
Guest's picture

bootspash menu

This is the correct way to install the bootspash menu 

tklpatch-extract-iso turnkey-core-2009.10-hardy-x86.iso
tklpatch-prepare-cdroot turnkey-core.rootfs/ turnkey-core-2009.10-hardy-x86.cdroot/
tklpatch-geniso turnkey-core-2009.10-hardy-x86.cdroot/

Guest's picture

Remastersys?

Just throwing this out there.  I used it on a server to create an ISO with all of the goodies I put on there.  Never tried it on a virtual machine.  Will try soon though. 

Guest's picture

I have never thought of it

This is a great idea, this way it much easier to be hypervisor independent. If you wanna go for VMware, Citrix XenServer, Hyper V, it doesn't matter. Thanks for sharing.

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <p> <span> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td> <em> <b> <u> <i> <strong> <font> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <strike> <caption>

More information about formatting options