As I mentioned in my last post, Vagrant is awesome, but I don’t really want to use some random disk image I found on the Internets to bootstrap my demo. I’d rather use an image that is a replica of what I’d actually be deploying in production. Wouldn’t it be awesome if there was some kind of tool that would allow us to build just such a base box? Enter VeeWee
gem install veewee
Installing VeeWee adds a new subcommand to Vagrant
$ vagrant basebox
vagrant basebox build BOXNAME # Build the box BOXNAME
vagrant basebox define BOXNAME TEMPLATE # Define a new basebox starting from a template
vagrant basebox destroy BOXNAME # Destroys the virtualmachine that was build for a basebox
vagrant basebox export [NAME] # Exports the basebox to the vagrant box format
vagrant basebox help [COMMAND] # Describe subcommands or one specific subcommand
vagrant basebox list # Lists all defined baseboxes
vagrant basebox ostypes # List the available Operating System types
vagrant basebox templates # List the currently available basebox templates
vagrant basebox undefine BOXNAME # Removes the definition of a basebox
vagrant basebox validate [NAME] # Validates a box against vagrant compliancy rules
$ vagrant basebox templates | grep CentOS
vagrant basebox define '' 'CentOS-4.8-i386'
vagrant basebox define '' 'CentOS-5.6-i386'
vagrant basebox define '' 'CentOS-5.6-i386-netboot'
vagrant basebox define '' 'CentOS-5.6-x86_64-netboot'
vagrant basebox define '' 'CentOS-6.0-i386'
vagrant basebox define '' 'CentOS-6.0-i386-netboot'
vagrant basebox define '' 'CentOS-6.0-x86_64'
vagrant basebox define '' 'CentOS-6.0-x86_64-netboot'
I use CentOS at work on x86_64, so lets create a 5.7 base box that targets that architecture. The command we’re about to run uses the pre existing Centos-5.6-i386 template as a starting point. We’ll get a chance to edit things to our liking before we actually create the base box.
$ mkdir veewee-test
$ cd veewee-test
$ vagrant basebox define CentOS-5.7-x86_64 CentOS-5.6-i386
The basebox 'CentOS-5.7-x86_64' has been successfully created from the template 'CentOS-5.6-i386'
You can now edit the definition files stored in definitions/CentOS-5.7-x86_64
or build the box with:
vagrant basebox build 'CentOS-5.7-x86_64'
$ ls -lR .
-rw-r--r-- 1 zsprackett staff 1038 Oct 4 22:57 definition.rb
-rw-r--r-- 1 zsprackett staff 1355 Oct 4 22:57 ks.cfg
-rw-r--r-- 1 zsprackett staff 1655 Oct 4 22:57 postinstall.sh
We can see that the directories definitions/CentOS-5.7-x86_64/ have been created and that there are some new contents. The definition.rb file is the config file that instructs VeeWee on how to build the new base box. The ks.cfg file is a kickstart file. You can use your preexisting kickstart here! Awesome. postinstall.sh is a script file that is run inside the installed vm. It can be used to install packages, modify files or do pretty much anything you might desire.
I made some very minimal changes to the definition.rb file to get move it to CentOS 5.7-x86_64
$ diff -ruN definition.rb.orig definition.rb
--- definition.rb.orig 2011-09-26 11:30:50.000000000 -0400
+++ definition.rb 2011-10-04 22:57:47.000000000 -0400
@@ -2,9 +2,9 @@
:cpu_count => '1', :memory_size=> '384',
:disk_size => '10140', :disk_format => 'VDI', :hostiocache => 'off', :ioapic => 'on', :pae => 'on',
:os_type_id => 'RedHat',
- :iso_file => "CentOS-5.6-i386-bin-DVD.iso", :iso_src => "", :iso_md5 => "181142a5845586579d5d4d96e43a4827", :iso_download_timeout => 1000,
+ :iso_file => "CentOS-5.7-x86_64-bin-DVD-1of2.iso", :iso_src => "", :iso_md5 => "55eadec0a6e87c5f2883f734d43fdb58", :iso_download_timeout => 1000,
:iso_download_instructions => "We can not download the ISO , you need to download it yourself and put it in the iso directory\n"+
- "- URL: http://isoredirect.centos.org/centos/5/isos/i386/ ",
+ "- URL: http://isoredirect.centos.org/centos/5/isos/x86_64/ ",
:boot_wait => "10", :boot_cmd_sequence => [
'linux text ks=http://%IP%:%PORT%/ks.cfg'
I also made a change to the postinstall.sh to add a user/group for puppet to prevent an issue later.
$ diff -ruN postinstall.sh.orig postinstall.sh
--- postinstall.sh.orig 2011-10-06 08:42:27.000000000 -0400
+++ postinstall.sh 2011-10-06 08:42:36.000000000 -0400
@@ -23,6 +23,7 @@
#Installing chef & Puppet
+useradd -u 52 puppet
/opt/ruby/bin/gem install chef –no-ri –no-rdoc
/opt/ruby/bin/gem install puppet –no-ri –no-rdoc
VeeWee will try and install from the iso file. It expects it to exist in the iso subdirectory, so lets go ahead and create it and download the CentOS iso.
$ mkdir iso
$ cd iso
$ curl -O http://ftp.usf.edu/pub/centos/5/isos/x86_64/CentOS-5.7-x86_64-bin-DVD-1of2.iso
At this point we’re pretty much ready to build our base box. Running the build command below will pop up an automated install Virtual Box window. You can observe the install progress.
$ vagrant basebox build 'CentOS-5.7-x86_64'
Verifying the isofile CentOS-5.7-x86_64-bin-DVD-1of2.iso is ok.
Setting VM Flag ioapic to on
Setting VM Flag pae to on
Creating vm CentOS-5.7-x86_64 : 384M – 1 CPU – RedHat
Creating new harddrive of size 10140
VBoxManage createhd –filename ‘/Users/zsprackett/VirtualBox VMs/CentOS-5.7-x86_64/CentOS-5.7-x86_64.vdi’ –size ‘10140’ –format vdi > /dev/null
Attaching disk: /Users/zsprackett/VirtualBox VMs/CentOS-5.7-x86_64/CentOS-5.7-x86_64.vdi
Mounting cdrom: /Users/zsprackett/vagrant/iso/CentOS-5.7-x86_64-bin-DVD-1of2.iso
Waiting for the machine to boot
Typing:: linux text ks=http://192.168.1.1:7122/ks.cfg
Starting a webserver on port 7122
Serving file /Users/zsprackett/vagrant/definitions/CentOS-5.7-x86_64/ks.cfg
Waiting for ssh login with user vagrant to sshd on port => 7222 to work
Transferring /var/folders/zt/l3266vl106j7bcb5mxq9zt8h0000gn/T/vbox.version20111004-31629-awlljg to .vbox_version
Step  was successfully – saving state
Waiting for ssh login with user vagrant to sshd on port => 7222 to work
Transferring /Users/zsprackett/vagrant/definitions/CentOS-5.7-x86_64/postinstall.sh to postinstall.sh
***echo ‘vagrant’|sudo -S sh ‘postinstall.sh’
Executing command: echo ‘vagrant’|sudo -S sh ‘postinstall.sh’
If all went well, we can now export our base box for testing.
$ vagrant basebox export CentOS-5.7-x86_64
Vagrant requires the box to be shutdown, before it can export
Sudo also needs to work for user vagrant
Performing a clean shutdown now.
Executing command: sudo /sbin/halt -h -p
Broadcast message from root (pts/0) (Wed Oct 5 13:40:47 2011):
The system is going down for system halt NOW!
Machine CentOS-5.7-x86_64 is powered off cleanly
Excuting vagrant voodoo:
vagrant package –base ‘CentOS-5.7-x86_64’ –output ‘CentOS-5.7-x86_64.box’
To import it into vagrant type:
vagrant box add ‘CentOS-5.7-x86_64’ ‘CentOS-5.7-x86_64.box’
To use it:
vagrant init ‘CentOS-5.7-x86_64’
$ vagrant box add ‘CentOS-5.7-x86_64’ ‘CentOS-5.7-x86_64.box’
[vagrant] Downloading with Vagrant::Downloaders::File…
[vagrant] Copying box to temporary location…
[vagrant] Extracting box…
[vagrant] Verifying box…
[vagrant] Cleaning up downloaded box…
Note, the post install for i386 does some other things you may or may not like. It installs ruby from source in /opt and puppet and chef from gems. You can change the postinstall.sh as you see fit. You’ll need to rebuild the base box to see your changes. Once the rebuild is done, and we’ve done the vagrant add, as the instructions say, we’re ready to pull in our shiny new base box using vagrant init! In part 3, I show you how to use puppet to bootstrap a typical tiered web application with Vagrant.