Templatize your buildout.cfg files
topp.recipes.cfgtemplate is a simple zc.buildout recipe that will allow you to templatize your buildout.cfg file to more effectively manage minor variations between builds.
I recently wrote a buildout recipe that some Plone folks might find useful. One of my current OpenPlans-related tasks is improving our caching and load-balancing setup. After a bit of research I decided to start serious testing with Varnish for caching and nginx for load-balancing. Since both of these have decent buildout recipes from which to start, buildout was a natural choice for a build and deployment management tool.
One of buildout's strengths is that, ultimately, all you need is a single buildout.cfg file to define your entire deployment. You can then check this file into a VCS repo somewhere, and you (or anyone else) can replicate the entire software stack with one checkout from the repository and one command.
When using buildout, however, I frequently found myself checking out the same buildout.cfg file and then tweaking it slightly, to change such values as port numbers, host names, and passwords, from deployment to deployment. This was annoying to do, and left me with uncommitted local changes that I had to take care not to commit back. Neither was I excited about the prospect of managing the versioning for each of these buildout.cfg files separately, when the only thing that varied between them was minutiae.
topp.recipes.cfgtemplate eases this process by allowing you to specify variable substitutions in your buildout.cfg file. Here's how the plone.recipe.plone recipe (echo?) config file might look:
[buildout]
parts = cfgtemplate plone zope2 instance
eggs =
develop =
[cfgtemplate]
recipe = topp.recipes.cfgtemplate
[plone]
recipe = plone.recipe.plone
[zope2]
recipe = plone.recipe.zope2install
url = ${plone:zope2-url}
[instance]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
user = {{admin-userid}}:{{admin-password}}
http-port = {{http-port}}
debug-mode = {{debug-mode}}
verbose-security = {{verbose-security}}
eggs =
${buildout:eggs}
${plone:eggs}
zcml =
products =
${plone:products}
${buildout:directory}/product
Note the use of {{double curly-braces}} around variable names in the [instance] section. When the user runs buildout against this file for the first time, she will be interactively prompted to enter the values for these variables, which will then be stored in a cfgsubs.cfg file for use during subsequent builds. The settings persist, but the buildout.cfg file itself is not changed.
The recipe sort of abuses buildout at the moment by claiming to have installed a file even though it didn't, so that buildout will re-install the part (i.e. perform the value substitutions from cfgsubs.cfg) every time. There's probably a better way to do that. It's proven immediately useful, however; here's the buildout.cfg for our nascent Varnish and nginx build setup.