Tonλ's blog May the λ be with you

Vagrant tools

by @ardumont on

In this post, I will describe how to install/setup the vagrant stack I use in my every day work to ease my developments. For some hints as to why i use vagrant :D.

As usual, my environment is a debian-based environment.

Pre-requisites

I detail the versions for which I know the combo works!

No details

sudo aptitude install -y ruby1.9.3 rubygems virtualbox && \
sudo gem install vagrant vagrant-snap virtualbox

Details

ruby (1.9)

sudo aptitude install ruby1.9.3 rubygems

virtualbox (4.1)

sudo aptitude install virtualbox

vagrant (1.0.5)

Vagrant permits to ease the use of virtualbox vm from the command line interface.

sudo gem install vagrant

vagrant-snap (0.10)

Vagrant-snap permits to ease the hot snapshoting of your vm.

sudo gem install vagrant-snap virtualbox

Note You need to add the virtualbox gem dependency because of a vagrant/vagrant-snap dependency issue.

Your first virtual machine (vm)

Setup

Default

cd /your/vm/folder && vagrant init

This will generate a template Vagrantfile with a minimal default content (i removed comments):

Vagrant::Config.run do |config|
  config.vm.box = "base"
end

Specific setup

Now edit it to suit your need.

For example, I frequently use something along those lines :

  • call the vm lucid64
  • the iso is based on the template box http://files.vagrantup.com/lucid64.box
  • the vm has 512Mo of RAM
  • assign one ip 192.168.33.2
  • assign a hostname to be ubuntu.local.com
  • as soon as the vm is up, i want it to run the script ./scripts/bootstrap.sh
  • and i want to make a mount point on some folder, here ~vagrant/bin/ will be mounted on the host's folder ./scripts
Vagrant::Config.run do |config|
    config.vm.box = "lucid64"
    config.vm.box_url = "http://files.vagrantup.com/lucid64.box"
    config.vm.customize ["modifyvm", :id,  "--natdnshostresolver1", "on", "--memory", 512]
    config.vm.network :hostonly, "192.168.33.2"
    config.vm.host_name = "ubuntu.local.com"
    config.vm.provision :shell, :path => "./scripts/bootstrap.sh"
    config.vm.share_folder "v-data-1", "/home/vagrant/bin", "./scripts"
end

Note

Boot

Run this command:

vagrant up

Note The first time around, if you do not have locally the lucid64 vm, this will download it for you.

Then, this will boot the vm respecting the setup you provided in the Vagrantfile.

Possible output:

tony@dagobah(0.36,) 23:03:09 ~/repo/perso/puppet-sync (master) $ v up vm1
[vm1] VM already created. Booting if it's not already running...
[vm1] Clearing any previously set forwarded ports...
[vm1] Forwarding ports...
[vm1] -- 22 => 2222 (adapter 1)
[vm1] Creating shared folders metadata...
[vm1] Clearing any previously set network interfaces...
[vm1] Preparing network interfaces based on configuration...
[vm1] Running any VM customizations...
[vm1] Booting VM...
[vm1] Waiting for VM to boot. This can take a few minutes.
[vm1] VM booted and ready for use!
[vm1] Configuring and enabling network interfaces...
[vm1] Setting host name...
[vm1] Mounting shared folders...
[vm1] -- v-root: /vagrant
[vm1] -- v-data-2: /root/bin
[vm1] -- v-data-3: /home/vagrant/bin
[vm1] -- v-data-1: /etc/puppet-mount/
[vm1] -- v-data-4: /usr/local/bin/enc
[vm1] Running provisioner: Vagrant::Provisioners::Shell...
stdin: is not a tty
+ whoami
root
+ '[' '!' -f ./puppetlabs-release-precise.deb ']'
+ grep 'export TERM' /root/.bashrc
export TERM=xterm
+ '[' '!' 0 = 0 ']'

Note

  • v stands for vagrant (it's a personal alias)

Connect

As soon as the vm is up, you get back the prompt. It is now time to connect to it:

vagrant ssh

Possible output:

tony@dagobah(1.09,) 23:04:38 (7) ~/repo/perso/puppet-sync (master) $ v ssh vm1
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/
Welcome to your Vagrant-built virtual machine.
Last login: Sun Dec 16 13:22:45 2012 from 10.0.2.2
vagrant@puppet:~$

Action

Once you're connected, you can do whatever you want with your vm (even crash it!).

Imagine:

  • one vm with your puppet master (to serve the install of your agent)
  • another vm with a puppet agent (to check that the modules you develop are ok)
  • one vm with the application you're developing (plugged with the source code on your host machine…)
  • another one with your back end
  • etc…

To sum up, the sky is the limit (at least, the limit is with your host machine's ram)

Status

You can check at any time the status of your vms.

vagrant status

Possible output:

tony@dagobah(1.13,) 23:07:47 ~/repo/perso/puppet-sync (master) $ v status
Current VM states:

vm1                      running
vm2                      poweroff

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

Halt

Once you want to halt the vm because you're done doing what you want. First, disconnect from the vm (C-d in an empty bash prompt or exit or logout).

vagrant@puppet:~$ logout
Connection to 127.0.0.1 closed.
tony@dagobah(1.23,) 23:06:07 ~/repo/perso/puppet-sync (master) $

Now, you can stop the vm:

vagrant halt

Possible output:

tony@dagobah(1.15,) 23:08:50 (130) ~/repo/perso/puppet-sync (master) $ v halt vm1
[vm1] Attempting graceful shutdown of VM...
tony@dagobah(1.34,) 23:09:03 ~/repo/perso/puppet-sync (master) $

A cool functionality: Snapshot

The utility of the snapshot must not be under-estimated. This can save you plenty of time (of course, you need to take the time to make some at first). You can see this as an equivalent to git for your vms.

This permits you to go back at a precise snapshot. For example, to redo a failed step by short-circuiting successful steps that you want to skip.

For this, we will use vagrant-snap.

take

To take one snapshot for the vm1:

vagrant snap take vm1 -n $TAG_YOU_WANT -d $DESCRIPTION_YOU_WANT

Note

  • if no name is provided for the vm, all the vms will be snapshoted
  • the description (-d) is optional but recommended.
  • Did I mention that the snapshot can be taken when the vm is running?! Fun, ain't it!!!

Example:

tony@dagobah(1.44,) 23:15:51 ~/repo/perso/puppet-sync (master) $ v snap take -n master-ready-for-test -d "master up and ready for testing"
[vm1]
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
[vm2]
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

list

List all your snapshots for your vms.

vagrant snap list

Here is a possible output with 2 vms:

tony@dagobah(1.07,) 23:16:29 ~/repo/perso/puppet-sync (master) $ v snap list
[vm1]
 master-ready [ 8 days ] puppet master up and ready
    `-- master-ready-for-test [ 43 seconds ] master up and ready for testing
[vm2]
 agent-ready [ 8 days ] puppet agent up and ready
    `-- master-ready-for-test [ 41 seconds ] master up and ready for testing

back to the future past

If you take snapshots, you will have eventually want to restore some:

Suspend (optional)

First, you may need to suspend the vm(s) $VM_NAME:

vagrant $VM_NAME suspend

Possible output:

tony@dagobah(0.98,) 23:11:05 ~/repo/perso/puppet-sync (master) $ v suspend vm1
[vm1] Saving VM state and suspending execution...
tony@dagobah(0.76,) 23:11:50 (130) ~/repo/perso/puppet-sync (master) $ v status
Current VM states:

vm1                      saved
vm2                      poweroff

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

Go back

Then you can go back to the $TAG_YOU_WANT:

vagrant snap go $TAG_YOU_WANT $VM_NAME

Note

  • $VM_NAME is optional.
  • If you do not give any name, all your vms will be wired up to the tag $TAG_YOU_WANT.

For example:

tony@dagobah(0.35,) 23:20:05 ~/repo/perso/puppet-sync (master) $ v snap go master-ready-for-test vm1
[vm1]
VBoxManage: error: Cannot power down a saved virtual machine
VBoxManage: error: Details: code VBOX_E_INVALID_VM_STATE (0x80bb0002), component Console, interface IConsole, callee nsISupports
Context: "PowerDown(progress.asOutParam())" at line 168 of file VBoxManageControlVM.cpp
Restoring snapshot 9e8f5514-5745-4abb-925f-a2e38bbf9200
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Waiting for VM "aa8c95dc-571e-4cb2-ae4a-3c57f4c2db8c" to power on...
VM "aa8c95dc-571e-4cb2-ae4a-3c57f4c2db8c" has been successfully started.

Note The error messages are normals and may vary according to the state of your vm(s).

Cleaning Snapshot

You can delete snapshots once you do not need them anymore.

vagrant snap delete $VM_SNAPSHOT

This may take some time. You can check this via the status call:

tony@dagobah(2.82,) 23:27:44 ~/repo/perso/puppet-sync (master) $ v status
Current VM states:

vm1                      deletingsnapshotlive
vm2                      poweroff

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

Possible output:

tony@dagobah(0.47,) 23:23:19 ~/repo/perso/puppet-sync (master) $ v snap delete master-ready-for-test
[vm1]
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
[vm2]
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

Conclusion

With minor effort from your part, the Vagrant stack is a great way to empower you for your every day use. Use it, you won't regret it!

Latest posts