Sam Trenholme's webpage
Support this website

Configuration files

 

May 5 2018

This blog is about some ways of formatting configuration files.

==The MaraDNS way==

The MaraDNS way to format a configuration file is a syntax based on a subset of Python. It looks like this:

foo = 1
bar = "String"
# This is a comment
bar += ", and some more text"
# bar is now "String, and some more text"
bax = {}
bax["something"] = "Something else"

Here, the name of a parameter at the top level is a bare string (and, yes, MaraDNS and Deadwood will exit with a fatal error if the name is not one that they recognize).

I designed this syntax back in 2000 and used it in both MaraDNS (2001) and in Deadwood (2007)—I felt no need to change the syntax for the MaraDNS 2.0 recursive resolver.

If I were designing something like MaraDNS today, I would do it differently, since there is more standardization on how to convert hierarchical data in to a text file.

In the mid-2000s, the trend was to use XML, which could look like this:

<foo>1</foo>
<bar>String, and some more text</bar>
<!-- This is a comment -->
<bax><something>Something else</something></bax>

Or like this:

<foo value=1 />
<bar text="String, and some more text" />
<bax><something data="Something else" /></bax>

Or even a combination of the above two:

<foo value=1 />
<bar>String, and some more text</bar>
<bax somethingData="Something else" />

Needless to say, except in domains where people wanted marked up text (web pages, word processing documents, etc.), XML was not the best choice. So the next format which came out was JSON:

{"foo": 1,
 "bar": "String, and some more text",
 "REM": "Since JSON doesn't have comments, let's fake them",
 "bax": {
         "something": "Something else"
        }
}

Simple, direct, easy to parse. This is probably the lingua franca of transferring hierarchical data between programs right now.

However, JSON, while great for machines to read and write, is less suitable for text files edited by humans. There are a couple of formats which try to be a "JSON for humans".

One simple solution is to just have comments in JSON. There are proposals to allow both "//" and "#" to specify a comment; I have written simple Comment JSON parsers which strip a file of all lines beginning with the character "#" before processing the file with a conventional JSON parser. The format is similar to the JSON example above:

{"foo": 1,
 "bar": "String, and some more text",
# This is a simple way to have comments in JSON
 "bax": {
         "something": "Something else"
        }
}

The inventor of JSON wrote that a good way to have comments in JSON is to run a JSON-with-comments file through his JSMin processor, which strips out '//' and '/* */' comments from a file. For example:

{"foo": 1,
 "bar": "String, and some more text",
// This is another simple way to have comments in JSON
 "bax": { /* We can have comments which
             span multiple lines, if
             desired */
         "something": "Something else"
        }
}

If something with more features than JSON with comments is desired, one popular option (used by, for example, Docker and Ansible), is YAML:

foo: 1
bar: String, and some more text
# YAML, naturally, supports comments
bax:
    something: Something else

YAML can also parse JSON files; it is a superset of JSON and even a superset of JSON with comments.

Some feel that while JSON is too simple, YAML is too complex. One attempt at a middle ground between JSON and YAML is the language Terraform uses, HCL (HashiCorp configuration language):

foo = 1
bar = "String, and some more text"
# Comments are supported
bax = { "something": "Something else" }

I’m sure there are other mini-languages for representing hierarchical data, but this covers the ones I have seen working in the software industry.

Comments are closed.