Warning: This post is only loosely Python related and not at all Plone related, but I thought folks might enjoy hearing about Vagrant and Puppet because these tools may help you do your Plone and Python jobs better.
For the past couple weeks I’ve been working on creating a virtual machine to bootstrap a kitsune environment. Kitsune is the Django site that powers support.mozilla.com. I’ve now reached what I call the 2nd milestone.
The milestones are as follows:
Now about the technologies.
I had heard of Vagrant before, but never tried it. I am now sorry I waited so long because the “cool factor” is very high. It requires that Virtualbox be installed, which I also danced around for too long before committing (being a former Parallels user).
On OS X Lion, installing Vagrant is simply a matter of:
$ gem install vagrant
Once you have `vagrant` installed you can do:
$ vagrant init
inside some revision-controlled directory and you have the beginnings of a virtual machine you can share with the masses. This is how kitsune-vagrant was born. Hopefully this shared virtual machine will eventually make some new developer’s life much easier.
We now arrive at a fork in the road; though Vagrant makes it easy to follow both paths: Chef or Puppet (it supports both). I don’t recall what made me choose Puppet over Chef, but it might have been that the Socorro folks were using it already.
Once you decide on Puppet (and assuming you do), it’s pretty easy to figure out that your next move is to create a manifest file for Puppet to apply.
My knowledge of Puppet is currently quite limited. Specifically, I only know how to create a manifest file. (Vagrant does the rest!) I imagine there is much more to Puppet, especially with regard to doing actual configuration management on production servers. But I have not explored any of that yet.
However, I did learn quite a bit about Puppet just from writing the manifest. The first most important thing I learned is this: Puppet is in charge. It does things the way it wants to and you need to follow its rules. The first and biggest challenge is to achieve a linear execution of tasks.
You cannot write rules in order and hope for the best. This will fail spectacularly when something executes before something else was supposed to. The way around this is via `require =>` statements.
A grep through kitsune.pp reveals:
require => Exec['git_clone'], require => Exec['db_sync'], require => Exec['packages_upgrade'], require => Exec['packages_update'], require => Package[$packages_native], require => Exec['git_clone'], require => Exec['chown_kitsune'], require => Exec['packages_compiled'], require => Exec['packages_vendor'], require => Exec['db_create'], require => Exec['db_import'], require => file['/etc/supervisor/supervisord.conf'], require => Exec['supervisor_stop'],
This roughly translates to the following workflow logic:
There is a bit more to it, but with that knowledge you should be able to read and understand kitsune.pp in full. I learned most of the remaining required puppeteering from this site:http://www.puppetcookbook.com/.
Oh my! This Mozilla work is a ton of fun; I attribute this in part due to the structure of their organization: I was invited immediately to collaborate in IRC with the kitsune team and as a result, we all have something to show for it. Next I will be working on the 3rd milestone! Hope to finish by the end of this week.
 This did not work on Snow Leopard, because `gem` is too old. However if you `brew install ruby` and try again, it should work.
 I didn’t bother to investigate Chef, but I am curious about it.
 And I hope this is only the beginning.
 I hope to get a Mozilla gig but even if I don’t, being able to do this type of work is very rewarding (which is why you will often hear people in open source say that to get paid for the type of work they do is a dream come true :-)).