Creating Customized Images

One of the steps when preparing an OpenNebula installation is the creation of Virtual Machine images for base Operating Systems or appliances. Some of these images can be downloaded from the marketplace but you may need an OS that is not in the marketplace or the images must be customized in some other way.

I’m going to describe an automated way to customize the base images provided by the Linux distributions using the software libguestfs.

The software libguestfs comes with tools to create and modify Virtual Machine images in a number of formats that qemu understands. Some of these utilities let us add or delete files inside the images or execute scripts using the image filesystem as root.

The first step is getting an image from the distribution web page. I usually get these images as they are very small and don’t have extra software. For this example we will use CentOS 7. Head to http://cloud.centos.org/centos/7/images/ and download the image CentOS-7-x86_64-GenericCloud.qcow2c.

One of the customizations we have to do to this image is uninstall the cloud-init package that comes by default with that image and install OpenNebula context package. The easiest way to install extra packages that are not in a repository is to add them into a CDROM that will provided to the customization tool. So head to https://github.com/OpenNebula/addon-context-linux/releases and download the latest context package.

To create the CDROM image we can use genisoimage. Remember to add a label so it’s easier to mount. Here we are going to use the label PACKAGES:

  • Copy the packages to a directory, for example packages
  • Execute genisoimage to create the iso that contains those files:
$ genisoimage -o packages.iso -R -J -V PACKAGES packages/

Now we need to prepare a script with the customizations to be done in the image. For example:

mount LABEL=PACKAGES /mnt

# Install opennebula context package
rpm -Uvh /mnt/one-context*rpm

# Remove cloud-init and NetworkManager
yum remove -y NetworkManager cloud-init

# Install growpart and upgrade util-linux, used for filesystem resizing
yum install -y epel-release --nogpgcheck
yum install -y cloud-utils-growpart --nogpgcheck
yum upgrade -y util-linux --nogpgcheck

# Install ruby for onegate tool
yum install -y ruby

Instead of modifying the original image downloaded we can use a feature of qcow2 image that is creating a new image that is based on another one. This way we keep the original image in case we are not happy with the modifications or we want to create another image with different customizations.

$ qemu-img create -f qcow2 -b CentOS-7-x86_64-GenericCloud.qcow2c centos.qcow2

Now all is prepared to customize the image. The command we are going to use is virt-customize. It can do a lot of modifications to the image but we are only going to do two. Execute the previous script and disable root password, just in case. The command is this one:

$ virt-customize -v --attach packages.iso --format qcow2 ---attach centos.qcow2 ---run script.sh -root-password disabled

It attaches two images, the iso image with the packages and the OS hard disk, executes script.sh that we previously created and disables root password.

After the command is run the image centos.qcow2 contains the modifications we did to the original image. Now we can convert it to any other format we need (for example vmdk) or to a full qcow2 image, that it, does not depend on any other one. Here are the commands to convert it to qcow2 (compatible with old qemu versions) and vmdk:

$ qemu-img convert -f qcow2 -O qcow2 -o compat=0.10 centos.qcow2 centos-final.qcow2
$ qemu-img convert -f qcow2 -O vmdk centos.qcow2 centos-final.vmdk

There are other customizations you can do, for example set a fixed password with --root-password password:r00tp4ssw0rd. You can also use virt-sparsify to discard the blocks that are not used by the filesystem. Check the libguestfs web page to learn about all the possibilities.

You can also take a look at the presentation I gave about this topic in the CentOS dojo held in Barcelona this year:

https://speakerdeck.com/jfontan/customizing-virtual-machine-images

3 replies
  1. Thomas Alrin
    Thomas Alrin says:

    Hi Javier,
    Really nice, it reduces the workload of creating new images by taking snapshots.
    How can i do the same for ubuntu?

    I’m using ubuntu14.04, and i’m having ubuntu14.04 image with packagename-v1.
    I want to update the image with new package packagename-v2

  2. Mike
    Mike says:

    Isn’t it kind of useless to create vmdk’s for opennebula since the disk has to be persistent to use it with vcenter and then you can only have one vm for every image?

  3. Javier Fontan
    Javier Fontan says:

    You can create more than one. What you have to do is create a template in vCenter with that VMDK and then import it in OpenNebula. After that when you create a new VM from that template it will use a clone of the original image.

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *