OxDEAD Unicornz

Have you ever seen so many?

Tracking Changes in Git Repository and Deploy Chef + Bash + Cron

I like Chef very much. Opensource version, of course, lacks some features of Enterprise Chef, for example there are no push-jobs.

Imagine you’re using opensource Chef to deploy some web application using deploy_revision resource. It tracks some branch in git repository and if there are changes it deploys. The problem is that chef-client runs hourly by default and I don’t know a person who is patient enough to wait for deploy for an hour. You can, of course, run chef-client manually, but this would kill the idea of using Chef, won’t it?

Maybe not the best solution for this issue, but working (please read/modify script before using, it’s actually an erb template, which should be populated with git repository):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash

if kill -0 $(cat /var/chef/cache/chef-client-running.pid) > /dev/null 2>&1; then 
    echo "$(date) Chef-client is already running, skip this run" >> /var/log/chef/client.log
    exit 0
fi

git ls-remote --heads <%= @your_repo_goes_here %> > /tmp/git_heads.txt.tmp  # populate template using Chef recipe attributes, also you may need to run git via sudo on behalf of some user who has needed keys

if ! cmp /tmp/git_heads.txt.tmp /tmp/git_heads.txt >/dev/null 2>&1  # compare results of previous run and current one
then

  echo "$(date) There are some changes in repositories, running chef-client" >> /var/log/chef/client.log
  chef-client >> /var/log/chef/client.log 2>&1
  mv /tmp/git_heads.txt.tmp /tmp/git_heads.txt
  exit 0

else

  echo "Updating /tmp/git_heads.txt"
  mv /tmp/git_heads.txt.tmp /tmp/git_heads.txt
  exit 0
fi

The idea is that cron is runninng this script frequently, and compares hashes of branch HEADs in given repo. If there are changes script runs chef-client and it performs deploy.