Friday, March 29, 2013
A meta configure file
I'm tired of changing the configuration files as I test under different systems. It also seemed silly that I needed to replicate the configuration files for each system (or set of systems). What I wanted was a configuration for the configuration and that notion set off an alarm bell in my head.
The poster child for the “a configuration file for the configuration
file” is sendmail
, the only program I know
of that has a thousand page tome
dedicated to describing the configuration file, and it's little wonder
when the
syntax makes Perl look sane:
# try UUCP traffic as a local address R$* < @ $+ . UUCP > $* $: $1 < @ $[ $2 $] . UUCP . > $3 R$* < @ $+ . . UUCP . > $* $@ $1 < @ $2 . > $3 # hostnames ending in class P are always canonical R$* < @ $* $=P > $* $: $1 < @ $2 $3 . > $4 R$* < @ $* $~P > $* $: $&{daemon_flags} $| $1 < @ $2 $3 > $4 R$* CC $* $| $* < @ $+.$+ > $* $: $3 < @ $4.$5 . > $6 R$* CC $* $| $* $: $3 # pass to name server to make hostname canonical R$* $| $* < @ $* > $* $: $2 < @ $[ $3 $] > $4 R$* $| $* $: $2 # local host aliases and pseudo-domains are always canonical R$* < @ $=w > $* $: $1 < @ $2 . > $3 R$* < @ $=M > $* $: $1 < @ $2 . > $3 R$* < @ $={VirtHost} > $* $: $1 < @ $2 . > $3 R$* < @ $* . . > $* $1 < @ $2 . > $3
It's so bad that there does indeed exist a configuration file
for sendmail.cf
that's not ugly in a “line noise” way, but
ugly in a “needlessly verbose” way:
include(`/usr/share/sendmail-cf/m4/cf.m4')dnl VERSIONID(`setup for Red Hat Linux')dnl OSTYPE(`linux')dnl dnl # dnl # default logging level is 9, you might want to set it higher to dnl # debug the configuration dnl # dnl define(`confLOG_LEVEL', `9')dnl dnl # dnl # Uncomment and edit the following line if your outgoing mail needs to dnl # be sent out through an external mail server: dnl # dnl define(`SMART_HOST',`smtp.your.provider') dnl # define(`confDEF_USER_ID',``8:12'')dnl dnl define(`confAUTO_REBUILD')dnl define(`confTO_CONNECT', `1m')dnl define(`confTRY_NULL_MX_LIST',true)dnl define(`confDONT_PROBE_INTERFACES',true)dnl define(`PROCMAIL_MAILER_PATH',`/usr/bin/procmail')dnl define(`ALIAS_FILE', `/etc/aliases')dnl define(`STATUS_FILE', `/var/log/mail/statistics')dnl define(`UUCP_MAILER_MAX', `2000000')dnl define(`confUSERDB_SPEC', `/etc/mail/userdb.db')dnl define(`confPRIVACY_FLAGS', `authwarnings,novrfy,noexpn,restrictqrun')dnl define(`confAUTH_OPTIONS', `A')dnl
My thought was (and still is) if a configuration file needs a configuration file, you're doing it wrong. So yes, I was experiencing some cognitive dissonance with writing a configuriation file for a configuration file.
But on second thought, I'm not configuring a single configuration file, I'm configuring multiple configuration files. And no, it's not one configuration file (with changes for different systems) but several configuration files, all of which need to be changed for a different system. And not only changed, but that the changes are consistent with each other—that component P is configured with the IP address of component W, and that W has the IP address of component P. And in that view, I feel better with having a configuration file for the configuration files.
Another factor to keep in mind is that I'm reading in the sample configuration file (they're in XML so parsers are readily available) from the source repository and then making changes (directly to the in-memory DOM) and saving the results to a new file. That way, I'm sure to get the latest and greatest version of the configuration file (they do change, but it's rare and it can be easy to miss, like what happened in production about two weeks ago)—most of the contents are sensible defaults.
If this sounds like I'm trying to justify an approach, I am. I still dislike “configuration files for a configuration file” and I needed to convince myself that I'm not doing something nasty in this case.
Yes, I might be overthinking this a tad bit. But then again, trying to ensure six different components are consistently configured by using a single configuration file might make this approach A Good Thing™.