Git pre-commit hook for DNS zone data

If you’re storing your DNS configuration in Git, a pre-commit hook to automatically run named-checkzone before zone file changes are committed may be useful to you. The pre-commit hook I use assumes that zone files (and only zone files) are in the format db.<zonename> (e.g. “”), and only tests zone files (e.g. named-checkconf is not run against configuration files).

This pre-commit hook’s structure is based heavily on a Puppet 2.7 pre-commit published elsewhere. Without further ado:


# Adapted from a puppet pre-commit hook at:
# install this as .git/hooks/pre-commit to check DNS zone files
# for errors before committing changes.


[ "$SKIP_PRECOMMIT_HOOK" = 1 ] && exit 0

# Make sure we're at top level of repository.
cd $(git rev-parse --show-toplevel)

trap 'rm -rf $tmpdir $tmpfile1' EXIT INT HUP
tmpdir=$(mktemp -d precommitXXXXXX)
tmpfile1=$(mktemp errXXXXXX)

echo "$(basename $0): Validating changes."

# Here we copy files out of the index into a temporary directory. This
# protects us from a the situation in which we have staged an invalid
# zone file using ``git add`` but corrected the changes in the
# working directory. If we checked the files &quot;in place&quot;, we would
# fail to detect the errors.

git diff-index --cached --name-only HEAD |
grep '^db.' |
git checkout-index --stdin --prefix=$tmpdir/

find $tmpdir -type f -name 'db.*' |
while read zonefile; do
    zone=`echo $zonefile | sed -e "s/^${tmpdir}/db.(.*)$/1/"`
    named-checkzone -q $zone $zonefile
    # If named-checkzone reports an error, get some output:
    if [ $? -ne 0 ]; then
	named-checkzone $zone $zonefile | sed "s#$tmpdir/##" >> $tmpfile1 2>&1

if [ -s "$tmpfile1" ]; then
echo Error: Zone file problem:
echo ----------------------------
cat $tmpfile1
echo ----------------------------


exit $rc

Update: Now available as a Gist.


One comment