Just over a month ago I “blogged”:http://yergler.net/blog/2006/11/07/deploying-python-applications/ about my first experience with “zc.buildout”:http://cheeseshop.python.org/pypi/zc.buildout/. For those that don’t remember (shame on you!), zc.buildout is a Python tool developed by Jim Fulton of Zope fame for constructing software installations. “Buildouts”, if you will. The attraction to this over, say, just “distutils”:http://www.python.org/doc/lib/module-distutils.html or just “setuptools”:http://peak.telecommunity.com/DevCenter/setuptools is that you can go from a bare-bones “Python”:http://python.org installation and source code checkout (or tar-ball) to a fully functional application, with dependencies and the trimmings, in a predictable, sane way. The fact that dependencies are installed in a local folder makes this especially appealing for deploying code on hosts where you don’t have write access to site-packages. But enough re-hashing my last zc.buildout post.
As I mentioned in my previous post, I’ve been using zc.buildout mostly to deploy the web applications that power “Creative Commons’”:http://creativecommons.org “web services”:http://api.creativecommons.org These are written using CherryPy, and were previously invoked as simple CGI scripts. However, as usage grew, we needed to move them to independent processes, which Apache proxied to using mod_rewrite. zc.buildout provided a great way to generate the wrapper script for running that process, but early this week we ran into a problem: we didn’t have a good way to detect if the process died for some reason and needed to be restarted.
I decided that a simple approach was best for the initial go-round, and wrote a small shell script that looks at the pid file, checks if it’s still running and if not starts the process. Put this in a cron job that runs every 10 minutes or so, and you have a poor man’s watchdog[1]. After writing two of these, I realized that this is something that should really be automated as part of my software installation: I always want to have a “am I up?” check script available, and so my first custom zc.buildout recipe, build_script, is born.
“build_script”:http://cheeseshop.python.org/pypi/buildout_script is a recipe that takes a template file, fills in values using Python “string formatting”:http://www.python.org/doc/lib/typesseq-strings.html and marks it as executable. It has one template included, paster-check that we’re using to check on a “paster”:http://pythonpaste.org/script process, and you can use templates that are part of the egg itself or are part of your codebase (via the template_dir setting).
You can find the code for **build_script** itself in Creative Commons’ “subversion repository”:http://sourceforge.net/svn/?group_id=80503 (“web view”:http://cctools.svn.sourceforge.net/viewvc/cctools/buildout_script/), and an example of how we’re using it for our web services is “here”:http://cctools.svn.sourceforge.net/viewvc/cctools/api/trunk/buildout.cfg?revision=HEAD.
Suggestions, comments, questions all welcome, as are additional templates that might be useful to include in the egg itself.
fn1. I’m sure there’s a better, more robust way to do this, but this is where we’re comfortable on the down time v. implementation time continuum. That said, if someone knows of an easy, more robust way, of course I’d like to hear about it.