1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Language" content="en" />
<title>tipidee: the tipidee-config program</title>
<meta name="Description" content="tipidee: the tipidee-config program" />
<meta name="Keywords" content="tipidee tipidee web server configuration text cdb file compilation cdbmake" />
<!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
</head>
<body>
<p>
<a href="index.html">tipidee</a><br />
<a href="//skarnet.org/software/">Software</a><br />
<a href="//skarnet.org/">skarnet.org</a>
</p>
<h1> The <tt>tipidee-config</tt> program </h1>
<p>
<tt>tipidee-config</tt> is a tool that compiles a text configuration file
into a binary cdb file that is used by the <a href="tipideed.html">tipideed</a>
web server.
</p>
<h2> Interface </h2>
<pre>
tipidee-config [ -i <em>textfile</em> ] [ -o <em>cdbfile</em> ] [ -m <em>mode</em> ]
</pre>
<ul>
<li> tipidee-config reads the <a href="tipidee.conf.html">/etc/tipidee.conf</a>
configuration file, parses it, and outputs a cdb file to <tt>/etc/tipidee.conf.cdb</tt>.
(The <tt>/etc</tt> default can be changed at build time with the <tt>--sysconfdir</tt>
option to configure.) </li>
<li> It then exits 0. </li>
</ul>
<h2> Exit codes </h2>
<dl>
<dt> 0 </dt> <dd> success </dd>
<dt> 1 </dt> <dd> syntax error </dd>
<dt> 2 </dt> <dd> invalid inclusion (cycle or unauthorized duplicate) </dd>
<dt> 100 </dt> <dd> wrong usage </dd>
<dt> 111 </dt> <dd> system call failed </dd>
<dt> 129+ </dt> <dd> <a href="tipidee-config-preprocess.html">tipidee-config-preprocess</a> was killed </dd>
</dl>
<h2> Options </h2>
<dl>
<dt> -i <em>textfile</em> </dt>
<dd> Use <em>textfile</em> as input instead of <tt>/etc/tipidee.conf</tt> </dd>
<dt> -o <em>cdbfile</em> </dt>
<dd> Use <em>cdbfile</em> as output instead of <tt>/etc/tipidee.conf.cdb</tt>.
You can then use the <tt>-f <em>cdbfile</em></tt> option to
<a href="tipideed.html">tipideed</a>. </dd>
<dt> -m <em>mode</em> </dt>
<dd> Create the output file with permissions <em>mode</em> (given in octal).
Default is <strong>0644</strong>. Note that the output file should be readable
by the user <a href="tipideed.html">tipideed</a> is started as. If
<a href="tipideed.html">tipideed</a> is started as root and drops its privileges
itself, the file can be made private. </dd>
</dl>
<h2> Detailed operation </h2>
<ul>
<li> tipidee-config spawns a
<a href="tipidee-config-preprocess.html">tipidee-config-preprocess</a> helper
that reads <tt>/etc/tipidee.conf</tt>, takes care of all the inclusions, and
feeds it a single stream of data. If
<a href="tipidee-config-preprocess.html">tipidee-config-preprocess</a> dies
with a nonzero exit code at any point, tipidee-config exits with the same
error code, or 128 plus the signal number if
<a href="tipidee-config-preprocess.html">tipidee-config-preprocess</a> was
killed by a signal. </li>
<li> It reads the data and parses it, expecting it to follow the
<a href="tipidee.conf.html">/etc/tipidee.conf file format</a>. </li>
</li> On failure, it exits nonzero with an error message. </li>
<li> It supplies sane defaults for configuration values that have not
been provided. </li>
<li> It writes the data as a <a href="https://cr.yp.to/cdb/cdb.txt">cdb file</a>,
<tt>/etc/tipidee.conf.cdb</tt>. A previously existing file is replaced
atomically. </li>
<li> Running instances of <a href="tipideed.html">tipideed</a> will keep
using the old <tt>/etc/tipidee.conf.cdb</tt> data until their connection is closed;
new instances will use the new one. </li>
</ul>
<h2> Notes </h2>
<ul>
<li> It is by design that tipidee uses this unconventional "compile the
configuration file" approach. There are several benefits to it:
<ul>
<li> Parsing a configuration file is not very efficient. Every instance of
<a href="tipideed.html">tipideed</a> would have to do it on startup, and
there is an instance of <a href="tipideed.html">tipideed</a> for every
HTTP connection. Pre-parsing the configuration makes the initial server
response faster. </li>
<li> Data parsed by <a href="tipideed.html">tipideed</a> needs to use
<em>private dirty</em> memory for every instance, even if the data is
static — and that means incompressible RAM. By contrast, a cdb file
is mapped read-only, so its pages are <em>shared clean</em>, which means it's
essentially free. </li>
<li> <a href="tipideed.html">tipideed</a> is exposed to the network. You
want its attack surface to be as small as possible. Taking the parsing code
out of it goes a long way — admittedly, having to parse HTTP in the
first place is more attack surface than a simple config file can ever hope
to be, but every little bit helps. </li>
<li> Run time is the worst time to detect errors. Nobody wants their
service to go down because Bob edited the live config file and made a typo.
Having the parsing done <em>offline</em> prevents that: tipidee-config
doubles as a syntax checker, and when it runs successfully, you know the
service will pick up the new config and be fine. </li>
<li> In general, decoupling the <em>live configuration</em>, which is
the one used by live services (here, <tt>/etc/tipidee.conf.cdb</tt>), from
the <em>working configuration</em>, which is the one that humans can
tinker with (here, <tt>/etc/tipidee.conf</tt>), is a good idea. Don't
touch production until you're ready to flip the switch atomically;
tipidee-config is the switch. </li>
</ul> </li>
</ul>
<p>
Just remember to run <tt>tipidee-config</tt> whenever you make
a modification to your config file, and you'll be set.
</p>
</body>
</html>
|