01 October 2013

Creating Vagrant boxes for VMWare Fusion

I've wanted to create my own Vagrant box for a while, but made do with the available VMWare Ubuntu ones on www.vagrantbox.es. Until now.

The app we use to do this wizardry is called veewee, and essentially it uses the VMWare/VirtualBox tools to create a new VM and then connects via VNC to run through the installation process.

Ruby on OSX

Before we can do anything we need a functional Ruby environment on OSX. I work with Python atm, so I had nothing setup; we're going to install RVM1 (which solves similar problems to Virtualenv) first:

$ curl -L https://get.rvm.io | bash -s stable

As the installer informs you, next you must run the following command to activate RVM in the current shell:

$ source /Users/null/.rvm/scripts/rvm

Now install Ruby 1.9.2, and Bundler. Bear in mind that Ruby has to compile and will take some time:

$ rvm install ruby-1.9.2-p320
$ sudo gem update --system
$ sudo gem install bundler


Veewee is the app that does the magic; so get that next:

$ git clone https://github.com/jedi4ever/veewee.git
$ cd veewee
$ source .rvmrc

At this point you might get a big warning spat out:

RVM is not a function, selecting rubies with 'rvm use ...' will not work.

You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for a example.

I had to add this line into my .zshrc2 and start a new shell:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"

Next time you enter the directory with veewee in it, you'll see a different warning:

You are using '.rvmrc', it requires trusting, it is slower and it is not compatible with other ruby managers,
you can switch to '.ruby-version' using 'rvm rvmrc to [.]ruby-version'
or ignore this warning with 'rvm rvmrc warning ignore /Users/mafro/Development/vagrantboxes/.rvmrc',
'.rvmrc' will continue to be the default project file in RVM 1 and RVM 2,
to ignore the warning for all files run 'rvm rvmrc warning ignore all.rvmrcs'.

Presumably this means that the .rvmrc file is outdated now, and should be upgraded like so:

$ rvm rvmrc to .ruby-version

Finally we'll install the veewee bundle:

$ bundle install

Build a Vagrant box

With that nonsense out of the way, we can see what box templates Veewee has for the fusion provider3:

$ veewee fusion templates

Lots of 'em. I'm building a Debian Wheezy 64-bit box, so let's init a veewee distribution. The name you choose here will end up as the hostname of the finished Vagrant box.

$ veewee fusion define 'wheezy64' 'Debian-7.1.0-amd64-netboot'
The basebox 'wheezy64' has been successfully created from the template 'Debian-7.1.0-amd64-netboot'
You can now edit the definition files stored in /Users/mafro/Development/veewee/definitions/wheezy64 or build the box with:
veewee fusion build 'wheezy64' --workdir=/Users/mafro/Development/veewee

That command has copied the template templates/Debian-7.1.0-amd64-netboot into the directory definitions/wheezy64:

$ ls -l definitions/wheezy64
total 120
-rw-r--r--  1 mafro  staff   717B 22 Sep 07:57 base.sh
-rw-r--r--  1 mafro  staff   1.1K 22 Sep 07:57 chef.sh
-rw-r--r--  1 mafro  staff   114B 22 Sep 07:57 cleanup-virtualbox.sh
-rw-r--r--  1 mafro  staff   576B 22 Sep 07:57 cleanup.sh
-rw-r--r--  1 mafro  staff   1.5K 22 Sep 07:57 definition.rb
-rw-r--r--  1 mafro  staff    13K 22 Sep 07:57 preseed.cfg
-rw-r--r--  1 mafro  staff   198B 22 Sep 07:57 puppet.sh
-rw-r--r--  1 mafro  staff   417B 22 Sep 07:57 ruby.sh
-rw-r--r--  1 mafro  staff   617B 22 Sep 07:57 vagrant.sh
-rw-r--r--  1 mafro  staff   965B 22 Sep 07:57 virtualbox.sh
-rw-r--r--  1 mafro  staff   219B 22 Sep 07:57 vmfusion.sh
-rw-r--r--  1 mafro  staff   105B 22 Sep 07:57 zerodisk.sh

I made a few modifications to this baseline - mostly to change from a VM setup for the US, to a GB locale VM using apt servers in Australia. You can see the changes I made in this diff on GitHub.

Now we'll build the Vagrant box4. If you already have an ISO downloaded, put it into a directory called iso in the project folder - otherwise Veewee will download the ISO during the build:

$ mkdir iso
$ cp ~/Downloads/debian-7.1.0-amd64-netinst.iso iso
$ veewee fusion build --nogui --auto 'wheezy64'

The --nogui flag means VMWare won't open and show you the Debian installation process, and --auto will prevent a prompt asking if you want to download an ISO.

Finally, we need to convert the new VMWare file into box format and add it to vagrant:

$ veewee fusion export 'wheezy64'
$ vagrant box add wheezy64 wheezy64.box
$ rm wheezy64.box

You'll probably also want to clean up the VMWare VM that served as an intermediary for our new Vagrant box image. The directory yours is stored in may vary:

$ rm -rf ~/Documents/Virtual\ Machines.localized/wheezy64.vmwarevm

Thanks to bitterpeace.net for his original post.


  1. http://rvm.io/rvm/basics 

  2. http://stackoverflow.com/a/4755696/425050 

  3. https://github.com/jedi4ever/veewee/blob/master/doc/vagrant.md 

  4. https://github.com/jedi4ever/veewee/blob/master/doc/basics.md#build-a-new-vm-image 

Tagged in devops tekkers