In this post, I’m going to talk about the fission gem:

I primarily use this to manage the VMware Fusion virtual machines I use for testing Opscode’s Chef Cookbooks.

This post is rather light on specific details about things that are either “common” knowledge or documented elsewhere. Particularly, I won’t tell you how to set up the virtual machines, other than a few notes that I think make it easier to manage virtual machines in this way. In other words, you’re smart and can figure them out.

Install and Configure

The first step to use the fission RubyGem is to install it. If you don’t like RubyGems, then create a package or grab the source from the GitHub link, above.

gem install fission

Test that it is detecting your VMware Fusion VMs:

fission status

Fission has a configuration file, ~/.fissionrc, which is yaml format. If the status command fails, you may need to configure fission to find the vmrun command. Here’s the example from my system:

---
vmrun_bin: /Applications/VMware Fusion.app/Contents/Library/vmrun

Install an OS on a VM

If you’re reading this, I presume you know how to install an OS in a VMware virtual machine. I do a number of tasks during the installation to make it easy and consistent to work with all my test VMs.

  • Use bridged networking with DHCP

This usually results in the least amount of hassle for connecting to the VM without any tunneling or port forwarding tomfoolery.

  • Give it a simple VM name with alphanumeric characters only.
  • Use the same hostname during installation as the VM name

In the examples below, I use my “guineapig” system. I also have other systems like “ubuntu1110”, “freebsd82” and “centos6”. This is the name you’ll use to refer to the VM with fission, so it should be short, easy to type and clearly identifiable.

  • Set the root password, even if the OS doesn’t use the root account
  • Make sure SSH as root is enabled

Some Linux distributions such as Ubuntu do not enable the root login. This is for testing, so I really don’t care, and I can always write a Chef recipe to lock things down (as I would in production) if required.

I also set a simple password that I can use with -P to knife bootstrap without the shell doing anything with special characters.

  • Use NTP

Install the NTP package for your operating system. The workflow here (and the whole point really) is to make heavy use of VMware Fusion snapshots and rollback, so it is important that the system time is correct. I customized the bootstrap templates I use to add ntpdate.

Using Fission

And now the moment you’ve been waiting for. First, see the fission README for full detail on the commands available. I’m going to focus here on how I use it.

After the install and post install tasks are done, I create a new snapshot for the VM.

% fission status
guineapig        [running]
% fission snapshot create guineapig base

The name is “base” because thats a good name for a baseline. It can be useful to create specifically named snapshots for particular purposes.

I use Opscode Hosted Chef as my server and I already have my local workstation set up with the validation key, a Chef repository and have uploaded the cookbook(s) I use for testing. I’ll use “knife bootstrap” to kick off a run on my VM:

% knife bootstrap 10.1.1.129 -x root -Pvanilla -r 'recipe[apache2]'
...
INFO: service[apache2] restarted
INFO: Chef Run complete in 44.324473 seconds

Sweet, it worked. However, if the Chef run fails, I can log in as root, fix the bug and rerun, or whatever else may need to be done. Then once I’m ready to reset the VM, fission comes back to play.

% fission snapshot revert guineapig base
Reverting to snapshot 'base'
Reverted to snapshot 'base'

Note that fission will poweroff the VM when reverting the snapshot. Turn it on again with the start command.

% fission status
guineapig        [not running]

% fission start guineapig
Starting 'guineapig'
VM 'guineapig' started

% fission status
guineapig        [running]

And after logging in, we can see that apache2 is not installed as it should not be after the snapshot is restored.

% ssh root@guineapig
root@guineapig's password:
root@guineapig:~# dpkg -l apache2
No packages found matching apache2.

The VM is now ready to do my bidding once again.

Cleanup

Note that reverting the snapshot doesn’t delete the Chef node or client objects. Since fission is a Ruby library, a simple knife plugin can wrap up all the fission revert, restart and Chef cleanup, though. I called mine nukular.

% knife nukular guineapig base guineapig.int.example.com

And here’s the plugin I’m using:

require 'chef/knife'

  module KnifePlugins
    class Nukular < Chef::Knife
      deps do
        require 'fission'
        require 'chef/node'
        require 'chef/api_client'
      end

      banner "knife nukular VM SNAPSHOT [NODE]"

      def run
        vm, snapshot = @name_args
        node = @name_args[2].nil? ? vm : @name_args[2]
        Fission::Command::SnapshotRevert.new(args=[vm, snapshot]).execute
        Fission::Command::Start.new(args=[vm]).execute
        Chef::Node.load(node).destroy
        Chef::ApiClient.load(node).destroy
      end
    end
  end

The command-line usage takes 2 or 3 arguments. The first two must be the VM name and the snapshot name, e.g. guineapig and base. If the node name is different than the VM name, then specify it.

% knife nukular guineapig base guineapig.int.example.com

Note that the plugin has zero error handling or any other sensible things. You may want to modify it before you use it. Or not, these are just test systems after all.

Full example

Minus the output from the commands, here is the full output of testing the Opscode apache2 cookbook on my guinea pig. Assume that all the required things from my Chef Repository have been uploaded to the Chef Server and the knife configuration is correct. Also, the chef-full bootstrap template specified here is a customized version of the template in the Chef source master branch template that has ntpdate -u pool.ntp.org in it.

% fission status
% fission snapshot create guineapig testing-apache2
% knife bootstrap 10.1.1.129 -x root -P vanilla \
  -r 'recipe[apache2]' -d chef-full
% knife nukular guineapig testing-apache2 guineapig.int.housepub.org

That’s it. I hope you find this helpful!