Hooked on Git (Hooks)

A few years ago, I made the switch from older source code control systems, to git. Yes, yes, I know. I used CVS for far too long. In truth, I'd been using git for quite a while on a variety of projects, but my own code was all still buried in a CVS archive. I found a tool to convert the repositories, while maintaining the history, and made the switch.

I still miss inline $Log$ and $Id$ but I'm over that. Since switching to git, I've had a few occasions to use githooks to capture a git push to the server. Mostly this has been about doing simple updates or sending emails. However, I now maintain all of my DNS configuration as a git repo. I also have a collection of Ruby scripts which process the data (either a zone file or a JSON file with basic zone data) and produce the master and slave Bind configurations.

Initially, these steps were decoupled, but eventually I decided to join the two so that a push to the master branch would also force the DNS infrastructure to be rebuilt and automatically deployed to the various name servers.

This has worked quite well, but it's not without it's difficulties. For some of the git-hooks, I have dumped a file in a certain directory and allowed for a cron task to notice the new file and do the appropriate legwork. This avoids trying to run complex processes as the git user and also avoids delaying the git push for too long. However, it's not particularly synchronous. I run the cron tasks about every fifteen minutes, which means there is a lag of fifteen minutes (worst case) from the git push until the data is deployed, and also it means I'm running the check script 96 times a day whereas changes are quite infrequent.

I've been thinking of either creating a Resque system and Redis interface, so that the git-hook just submits something to the Resque job queue via a Redis submission, or else I will code up some sort of job submission mechanism, to do something similar.

What I'd like to be able to do in the git-hook would be to run a command such as:

$ job-submit update-dns

This would either add an "update-dns" job to a generic queue or else it would add some sort of timestamp or equivalent to the "update-dns" queue. The idea would be to have something which consumed from that queue and ran the appropriate script. Perhaps looking for update-dns.rb or update-dns.sh in a specific directory, and executing it. I'm not sure I need something as advanced and complex as Resque but it seems silly to reinvent the wheel.

I'd also like to be able to do something which was multi-host as there are times when I'd like to do more advanced jobs other than just things called from a git hook. I think for now, however, I'll code something up to use Redis and limit the scope to local jobs only.