echo "hey, it works" > /dev/null

just enough to be dangerous

What's the status of my vagrants?

I've been writing puppet manifests for a few different projects lately, and I've found it useful to test them using virtual machines managed by vagrant. However, as I've been swapping back and forth between the various projects, and because I'm forgetful, I've also been accidentally leaving VMs running. Not so great for the performance of my ageing laptop.

Vagrant manages boxes on a per-VM basis; it doesn't have a host-wide view of what VMs are running. I decided to write a zsh function that told me the status of my VMs, and learnt a few things along the way.

vagrants () { setopt LOCALOPTIONS unsetopt AUTOPUSHD pwd_orig=$PWD # This is mine, yours is likely different base=$HOME/Boxes vagrants=(${base}/**/.vagrant) for vagrant in $vagrants do cd $vagrant:h print $PWD vagrant status | awk '/^$/ {stat = !stat;next}; stat == 1 {print "\t",$0}' done cd $pwd_orig }

There were two things that I found tricky.

First, I like to automatically push onto the directory stack when I change directories, so that I can change back to previous directories using cd -<TAB>, and I didn't want to dirty the directory stack while moving to my vagrant directories. I tried to store the state of the directory stack and then restore it at the end using the dirs command, but I couldn't work out how to stop the directories being added as a single (broken) entry. Eventually I found that using setopt LOCALOPTIONS in a function will cause previous options to be restored on exit, meaning I could simply turn off AUTOPUSHD.

Second, the vagrant status command doesn't have script-friendly output, though there is an open ticket to provide friendlier output.

Current VM states: default saved To resume this VM, simply run `vagrant up`.

Running vagrant status on half a dozen vagrant directories that might have multiple environments produces pretty unattractive output. Luckily, the output is at least in a predictable format; three paragraphs, with the actual states in the middle paragraph. My awk is pretty rusty, but I was happy to come up with a solution that works for me.

vagrant status | awk '/^$/ {stat = !stat;next}; stat == 1 {print "\t",$0}'

When a blank line is encountered, the stat flag is toggled, and when it's set we print the whole lines. This means the blank line between the first two paragraphs turns the flag on and the blank line after the statuses turns it off again. If someone has a more reliable way of grabbing the second paragraph with less predictable input, I'd love to hear it.

A bonus discovery was zsh's ability to substitute portions of the current path when using cd, allowing you to visit the same subdirectory in a variety of projects.

Boxes/metropolis/manifests % cd metropolis cantoflash Boxes/cantoflash/manifests %

devops for the little guy

Like most web developers, I managed a bunch of domains, applications, and services. Some of these are projects for myself, some are for family and friends, some are for clients. And it's a mess, stuff on one shared hosting, stuff on some other shared hosting, stuff on the VPS I use to muck around. This makes it all difficult and time consuming to manage, not to mention fraught with risk.

I've decided it's time to get my house in order, bring everything I can together onto a quality VPS and manage things properly.

Whenever I've managed servers, I've quickly forgotten how I've installed stuff and how the thing is configured, and everything gets messy and out of control, so the idea of managed and versioned configurations is very attractive. There are two main options around, puppet and chef. A very much surface assessment suggests that puppet seems to be more popular and have more documentation, and I had more luck getting it up and running than I did with chef, so that's what I'm going to explore.

In the end, I want a VPS with:

  • SSH with SSH keys set up
  • a web server, probably Apache at this stage
  • several virtual hosts
  • PHP and Ruby
  • MySQL and Sqlite
  • git and subversion
  • vim
  • zsh
  • utilities such as ack, find, and curl
  • projects cloned from github
  • monitoring and alerting (I don't know anything about this stuff yet, but I'm guessing that's Nagios)
  • appropriate backup
  • and of course, versioned configuration

I'd also like to be able to:

  • easily spin up local VMs with the same base configuration as the VPS

Unfortunately, I haven't been able to find much to support such a small endeavour, most information seems to be about large teams and large projects. If you know of good resources, please let me know. I'll update this post as I work out more of what I want to achieve and how to do it (I may even split this into multiple posts).