in Developer Experience

libvirt Vagrant boxes with vagrant-mutate

Today I will like to put some light on using the vagrant-mutate plugin for Vagrant to convert (especially) VirtualBox images to libvirt. Why? Because if you start looking for an interesting box on the internet you will find out that most of them are based on VirtualBox images since that is the upstream default provider.

If you don’t know where to look for some boxes to start playing with Vagrant, go to offical VagrantCloud or to a popular Vagrantbox.es site.

Note: If you don’t have Vagrant installed yet, read on how to install it on Fedora.

The next step is to install the plugin. On Fedora that would mean:

# yum install qemu-img
$ vagrant plugin install vagrant-mutate

That should work both for upstream and mine package from Copr.

If you haven’t done so, now it’s the time to download some box. I have chosen to go with CentOS 7 VirtualBox image:

$ ls
centos7.box

Once we have a box it’s pretty straightforward to convert it:

$ vagrant mutate ./centos7.box libvirt
You have qemu 1.6.2 installed. This version cannot read some virtualbox boxes. If conversion fails, see below for recommendations. https://github.com/sciurus/vagrant-mutate/wiki/QEMU-Version-Compatibility
Extracting box file to a temporary directory.
Converting centos7 from virtualbox to libvirt.
qemu-img: 'image' uses a vmdk feature which is not supported by this qemu version: VMDK version 3
qemu-img: Could not open '/home/strzibny/.vagrant.d/tmp/d20141016-21536-1dashbd/box-disk1.vmdk': Wrong medium type
Getting information about the disk image via qemu-info failed

This process either ended up with a success or a similar error. In my case qemu-img convertor complains about VMDK version. Chances are you can still convert such image with this setup, but you need to trick qemu-img to think you are still using the old version of the format. Look at Carlos Spitzer’s post on how to do so using dd.

If you followed his steps you should now have a little script that will fix our image lying around. But this script can’t fix a Vagrant .box file for you so you need to unpack it (it’s just tar) and repack it. Since the failed command above already unpacked it for me I am gonna continue from there:

$ ls /home/strzibny/.vagrant.d/tmp/d20141016-21536-1dashbd/
box-disk1.vmdk  box.ovf  Vagrantfile

The file we are interested in is box-disk1.vmdk. That’s the base image.

$ ~/scripts/vmdk3.sh box-disk1.vmdk
box-disk1.vmdk is VMDK3.n Patching to VMDK2.n Run this script again when you're done to patch it back.

If everything went well we are ready to repackage the .box, but before that we need to create a metadata.json file that will tell Vagrant basic information about our image:

$ cat /home/strzibny/.vagrant.d/tmp/d20141016-21536-1dashbd/metadata.json
{
"provider" : "virtualbox",
"format" : "qcow2",
"virtual_size" : 40
}
$ tar cvzf final.box ./metadata.json ./Vagrantfile ./box-disk1.vmdk ./box.ovf
./metadata.json
./Vagrantfile
./box-disk1.vmdk
./box.ovf

And finally I can proceed with the vagrant mutate command:

$ vagrant mutate final.box libvirt
You have qemu 1.6.2 installed. This version cannot read some virtualbox boxes. If conversion fails, see below for recommendations. https://github.com/sciurus/vagrant-mutate/wiki/QEMU-Version-Compatibility
Extracting box file to a temporary directory.
Converting final from virtualbox to libvirt.
(100.00/100%)
Cleaning up temporary files.
The box final (libvirt) is now ready to use.

To see that all went well let’s run Vagrant to find out:

$ vagrant box list
final (libvirt, 0)
$ vagrant init

vagrant init will create a basic Vagrantfile for us and the only thing we need to do it to tell Vagrant the name of our box:

$ cat Vagrantfile
...
config.vm.box = "final"
...
$ vagrant up
$ vagrant ssh
[vagrant@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.0.1406 (Core)

And that is it. With vagrant mutate you can reuse many already made Vagrant boxes!

Note: If you are running upstream Vagrant you need to always specify a Vagrant libvirt provider (vagrant up --provider=libvirt).

Write a Comment

Comment