I'm tired of changing the configuration files as I test under different systems [1]. 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 [2], the only program I know of that has a thousand page tome dedicated to describing the configuration file [3], and it's little wonder when the syntax makes Perl look sane [4]:
>
```
# 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 > $* $: {body}amp;{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 (Internet Protocol) 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 (eXtensible Markup Language) so parsers are readily available) from the source repository and then making changes (directly to the in-memory DOM (Document Object Model)) 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™.
[3] https://www.amazon.com/exec/obidos/ASIN/0596510292/conmanlaborat-20
[4] http://okmij.org/ftp/Computation/sendmail-as-turing-machine.txt