Finally, Templating in Bashtard!

Bash Bashtard FreeBSD GNU+Linux — Published on .

In the past year, I’ve written Bashtard, a simple configuration system written in Bash to minimize the required dependencies, and to have a better system to handle different distributions/OSs in your cluster. Especially the past two months I’ve done quite a bit of work on it. I’ve worked out how to do reusable playbooks, generate a usable Debian package from the Makefile, extend the supported platforms, and more. And now, I’ve finally found a library to improve templating functionality, Bash Pure Template.

When I originally started Bashtard I had looked around for nice and simple templating solutions that I could use. Sadly, pretty much all the available results required me to add dependencies, or couldn’t really do more than what I did using sed and awk.

For a long time, I had accepted that the kind of system that I wanted didn’t exist, and I wasn’t interested in making it myself at the time. Last night, however, I decided to just give it a quick search to see if anything had changed, and BPT popped up somewhere in my results. Having a quick look through the documentation made me very interested, it seemed to have all the features I desired, while still sticking to utilities I’ve already accepted for Bashtard.

With one small exception, md5sum. This utility is not available on the FreeBSD systems I maintain. On FreeBSD, this tool is called md5, and has different options it can use. On the bright side, both md5sum and md5 accept the content to be hashed on STDIN, and will write the hash to STDOUT. Additionally, Bashtard already contains logic to deduce what kind of system it is running on.

And so I decided it’s worth a try. There’s only 5 references to md5sum, and the all happen in the same function, bpt.fingerprint. I’ve added an extra variable, util, and a case...esac to set this variable.

local util

case "${BASHTARD_PLATFORM[key]}" in
    freebsd) util=md5 ;;
    linux-*) util=md5sum ;;
    *)
        debug "bpt/fingerprint" "Falling back to md5sum for hashing"
        util=md5sum
        ;;
esac

After that, just replace all the md5sum invocations with "$util". And a quick test later, it seems to function just fine. Implementing BPT as a library was incredibly straightforward too.

. "$BASHTARD_LIBDIR/vendor/bpt.bash"

file_template_bpt()
{
    local file

    file="$1" ; shift

    eval "$* bpt.main ge \"$file\""
}

The eval is a bit icky, but it saves me from polluting the environment variables through various exports.

Another small adjustment I’ve made to BPT is the shebang. Upstream uses #!/bin/bash, but this is incorrect on some systems, including FreeBSD. It uses #!/usr/bin/env bash in the Bashtard version. Additionally, the upstream repository uses .sh as the file extension, which I’ve updated to be .bash to more accurately reflect which shell it is used with. Upstream also uses a 4-space indent, which I’ve left as-is for now, since indentation is more of a personal choice, even if that choice is wrong. Finally, I added 3 shellcheck disable rules to make shellcheck happy.

After some playbook testing on my own systems, I can say that BPT works pretty well so far, and I’m very glad the author made it available as free software. Thanks!