<metaname="Description"content="Documentation for the frontend service file of the 66 system tools which is a better method to manage all your different services in a centralized way.">
<metaname="Keywords"content="66 frontend service file supervision format key value ini">
The <ahref="https://skarnet.org/software/s6">s6</a> and <ahref="https://skarnet.org/software/s6">s6-rc</a>
programs each handle and use several kinds of services and different files. It is quite complex to
understand and manage the relationship between all those files and services. If you're interested in the details
you should read <ahref="https://skarnet.org/software/s6/servicedir.html">the documentation for the s6 servicedir</a>
and also about <ahref="https://wiki.obarun.org/doku.php?id=s6services"><em>classic</em></a>, <ahref="https://skarnet.org/software/s6-rc/s6-rc-compile.html">
<em>oneshot</em>, <em>longrun</em> and <em>bundle</em> services</a> on Obarun. The frontend service file of 66 tools allows you to deal with all these different services in
a centralized manner in one single place.<br>
By default 66 tools expect to find any service file in <tt>/etc/66/service</tt> although this
can be changed at compile-time by passing the <tt>--with-service-path=<em>DIR</em></tt>
option to <tt>./configure.</tt></p>
<p>The frontend service file has a format of INI with a specific syntax on the key field.
The name of the file usually corresponds to the name of the daemon and does not
have any extension or prefix.
</p><p>The file is made of <em>sections</em> which can contain one or more <em>key value</em> pairs
where the <em>key</em> name can contain special characters like <em>'-' (hyphen)</em> or <em>'_' (low line)</em>
except the character <em>'@' (commercial at)</em> which is reserved.</p>
<p>The parser will not accept any empty <em>value</em>. If a
<em>key</em> is set, the <em>value</em> cannot be empty. Comments are allowed
using the number sign '#'. Empty lines are also allowed.<br>
<em>Key names</em> are <strong>case sensitive</strong> and <em>cannot be
modified</em>. Most names should be specific enough to avoid confusion.<br>
The sections can be declared in any order but as a good practice
the <tt>[main]</tt> section should be declared first. That way the parser
can read the file as fast as possible.</p>
<h2>Sections</h2>
<p>All sections need to be declared with the name written between square brackets '[]'
and must be of lowercase letters <strong>only</strong>. This means that special characters, uppercase letters and numbers are not allowed in the name of a section. An <em>entire</em> section can be commented out by placing
the number sign '#' in front of the opening square bracket like this:</p>
<pre> #[stop]</pre>
<p>The frontend service file allows the following section names: </p>
<ul>
<li><ahref="#main">[main]</a></li>
<li><ahref="#start">[start]</a></li>
<li><ahref="#stop">[stop]</a></li>
<li><ahref="#logger">[logger]</a></li>
<li><ahref="#environment">[environment]</a></li>
</ul>
<p>Although a section can be mandatory not all of its key fields must be necessarily so.</p>
<hr>
<h2>Syntax legend</h2>
<p> The <em>value</em> of a <em>key</em> is parsed in a specific format depending on the key.
The following is a break down of how to write these syntaxes:</p>
<ul>
<li>
<tt>inline </tt> : An inline <em>value</em> must be on the same
line of its corresponding <em>key</em>.
<p>Valid syntax:</p><p>
</p><ul>
<pre>@type = classic</pre>
<pre>@type=classic</pre>
</ul>
<p>(!) Invalid syntax:</p>
<ul>
<pre>@type=
classic</pre>
</ul>
</li>
<br><hr>
<li>
<tt>quotes </tt> : A <em>value</em> between
double-quotes must stay on the same line of its corresponding <em>key</em>.
</li>
<p>Valid syntax:</p>
<ul>
<pre>@description = " some awesome description "</pre>
<p><em><strong>Note:</strong></em> The <em>funnel</em> feature of pipelining is not implemented yet.</p>
<br><hrstyle="border: 1px dashed #000000">
<li><h4>@flags</h4></li>
<p><tt>mandatory </tt> : no
</p><p><tt>syntax </tt> : bracket</p>
<p><tt>valid values </tt> :</p>
<ul>
<li><tt>nosetsid </tt> :
<h5>Corresponds to the file "<em>nosetsid</em>" of s6-rc and s6 programs</h5>
<p>This will create the file <tt>nosetsid</tt></p>
<p>Once this file was created the service will be run in the same process group
as the supervisor of the service <ahref="https://skarnet.org/software/s6/s6-supervise.html">(s6-supervise)</a>. Without this file the service will have its own process group and is started as a session leader.</p>
</li><li><tt>down </tt> :
<h5>Corresponds to the file "<em>down</em>" of s6-rc and s6 programs.</h5>
This will create the file <tt>down</tt><br><br>
Once this file was created the default state of the service will be considered <em>down</em>,
not <em>up</em>: the service will not automatically be started until it receives a
<tt>66-start</tt> command. Without this file the default state of the service will be <em>up</em> and started automatically.
</li>
</ul>
<br><hrstyle="border: 1px dashed #000000">
<li><h4>@notify</h4></li>
<h5>Corresponds to the file "<em>notification-fd</em>" of s6-rc programs.</h5>
<p><tt>mandatory </tt> : no
</p><p><tt>syntax </tt> : uint</p>
<p><tt>valid values </tt> :</p>
<ul>
<li>Any valid number.
<p>This will create the file <tt>notification-fd</tt>.
notification</a>. The <em>value</em> equals <em>the number of the file descriptor
that the service writes its readiness notification to.</em> (For instance,
it should be 1 if the daemon is <ahref="https://skarnet.org/software/s6/s6-ipcserverd.html">s6-ipcserverd</a>
run with the -1 option.) When the service is started or restarted and
this file is present and contains a valid descriptor number, <tt>66-start</tt>
will wait for the notification from the service and broadcast readiness,
i.e. any <ahref="66-svctl.html">66-svctl -U</a> process will be triggered.
</li>
</ul>
<br><hrstyle="border: 1px dashed #000000">
<li><h4>@timeout-finish</h4></li>
<h5>Corresponds to the file "<em>timeout-finish</em>" of s6-rc and s6 programs.</h5>
<p><tt>mandatory </tt> : no
</p><p><tt>syntax </tt> : uint</p>
<p><tt>valid values </tt> :</p>
<ul>
<li>Any valid number.
<p>This will create the file <tt>timeout-finish</tt>.
Once this file was created the <em>value</em> will equal the number of milliseconds
after which the <tt>./finish</tt> script—if it exists—will be killed with a
SIGKILL. The default is <tt>5000</tt>; finish scripts are killed if they're
still alive after 5 seconds. A value of <tt>0</tt> allows finish scripts to run forever.
</li>
</ul>
<br><hrstyle="border: 1px dashed #000000">
<li><h4>@timeout-kill</h4></li>
<h5>Corresponds to the file "<em>timeout-kill</em>" of s6-rc and s6 programs.</h5>
<p><tt>mandatory </tt> : no
</p><p><tt>syntax </tt> : uint</p>
<p><tt>valid values </tt> :</p>
<ul>
<li>Any valid number.
<p>This will create the file <tt>timeout-kill</tt>.
Once this file was created and the <em>value</em> is not <tt>0</tt>, then on reception of a <tt><ahref="66-stop.html">66-stop</a></tt>
command—which sends a SIGTERM and a SIGCONT to the service—a timeout
of <tt>value</tt> milliseconds is set. If the service is still not
dead after <tt>value</tt> milliseconds it will receive a SIGKILL.
If the file does not exist, or contains <tt>0</tt> or an invalid value,
then the service is never forcibly killed (unless, of course, a
<ahref="https://skarnet.org/software/s6/s6-svc.html">s6-svc -k</a> command is sent).
</li>
</ul>
<br><hrstyle="border: 1px dashed #000000">
<li><h4>@timeout-up</h4></li>
<h5>Corresponds to the file "<em>timeout-up</em>" of s6-rc programs.</h5>
<p><tt>mandatory </tt> : no
</p><p><tt>syntax </tt> : uint</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>Any valid number.
<p>This will create the file <tt>timeout-up</tt>.
Once this file was created the <em>value</em> will equal the maximum
number of milliseconds that <tt><ahref="66-start.html">66-start</a></tt> will wait
for successful completion of the service start. If starting the service
takes longer than this <em>value</em>, <tt>66-start</tt> will declare the transition
a failure. If the <em>value</em> is <tt>0</tt>, no timeout
is defined and <tt>66-start</tt> will wait for the service to start
until the <tt>maxdeath</tt> is reached. Without this file a <em>value</em> of <tt>3000</tt> (3 seconds) will be
taken by default.
</li>
</ul>
<br><hrstyle="border: 1px dashed #000000">
<li><h4>@timeout-down</h4></li>
<h5>Corresponds to the file "<em>timeout-down</em>" of s6-rc programs.</h5>
<p><tt>mandatory </tt> : no
</p><p><tt>syntax </tt> : uint</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>Any valid number.
<p>This will create the file <tt>timeout-down</tt>.
Once this file was created the <em>value</em> will equal the maximum
number of milliseconds <tt><ahref="66-stop.html">66-stop</a></tt> will wait
for successful completion of the service stop. If starting the service
takes longer than this <em>value</em>, <tt>66-stop</tt> will declare the transition
a failure. If the <em>value</em> is <tt>0</tt>, no timeout
is defined and <tt>66-stop</tt> will wait for the service to start
until the <tt>maxdeath</tt> is reached. Without this file a <em>value</em> of <tt>3000</tt> (3 seconds) will be
taken by default.
</li>
</ul>
<br><hrstyle="border: 1px dashed #000000">
<li><h4>@maxdeath</h4></li>
<h5>Corresponds to the file "<em>max-death-tally</em>" of s6-rc and s6 programs.</h5>
<p><tt>mandatory </tt> : no
</p><p><tt>syntax </tt> : uint</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>Any valid number.
<p>This will create the file <tt>max-death-tally</tt>.
Once this file was created the <em>value</em> will equal the maximum
number of service death events that the supervisor will keep track of. If
the service dies more than this number of times, the oldest event will
be forgotten and the transition (<tt>66-start</tt> or <tt>66-stop</tt>) will
be declared as failed. Tracking death events is useful,
for example, when throttling service restarts. The <em>value</em>
cannot be greater than <tt>4096</tt>. Without this file a default of <tt>3</tt>
is used.</p>
</li>
</ul>
</ul>
<br><hr>
<h2id="start">Section: [start]</h2>
<p>This section is <em>mandatory</em>. (!)</p>
<h3>Valid <em>key</em> names:</h3>
<ul>
<li><h4>@build</h4></li>
<h5>Without equivalent, this key is unique to 66 tools.</h5>
<p><tt>mandatory </tt> : yes (!)</p>
<p><tt>syntax </tt> : inline</p>
<p><tt>valid value </tt> :</p>
<ul>
<li><tt>auto </tt> : creates the service script file
as <ahref="https://skarnet.org/software/execline/">execline</a> script.</li>
<p>The corresponding file to start the service will automatically be written in
<ahref="https://skarnet.org/software/execline/">execline</a> format with
the <tt>@execute</tt> key <em>value</em>.</p>
<li><tt>custom </tt> : creates the service script file
in the language set in the <tt>@shebang</tt> key <em>value</em>.</li>
<p>The corresponding file to start the service will be written
in the language set in the <tt>@shebang</tt> key <em>value</em>.</p>
</li>
</ul>
<br><hrstyle="border: 1px dashed #000000">
<li><h4>@runas</h4></li>
<h5>Without equivalent, this key is unique to 66 tools.</h5>
<p><tt>mandatory </tt> : yes (!)</p>
<p><tt>syntax </tt> : inline</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>Any valid user set on the system</li>
<p>This will pass the privileges of the service to the given user before starting the daemon.</p>
</ul>
<p><tt><strong>Note:</strong></tt> (!) The daemon needs to be first started
with root. Only root can pass on privileges. This field has
no effects in other cases.</p>
<!-- This is very confusing!
You say this is mandatory but then make a note about how this has no other use case. What other use case could there possibly be if this is mandatory?
Will my service not start if I do not run it as root? You say the field has no effect but if this field is mandatory will my whole service error out?
Do you mean something like: "If not started with root, the service will not start at all!"? Do all services need to be run as root?
Also from what I understand and read a "daemon" is a running instance of a service, ain't that so? Then how can I start a daemon seperately from a service? Because that is how it sounds.
It's completely understandable what this key does. It's just that the note instead of explaining the key, raises doubt. To clear this confusion I propose to either: not use the word daemon and clearly explain the alternative effects—if there were any possible—or briefly explain how I possibly can mess things up with this key. -->
<hrstyle="border: 1px dashed #000000">
<li><h4>@shebang</h4></li>
<h5>Without equivalent, this key is unique to 66 tools.</h5>
<p><tt>mandatory </tt> : yes (!)—if the <tt>@build</tt> key is set to <em>custom</em>.</p>
<p><tt>syntax </tt> : quotes, slash</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>Any valid interpreter installed on your system.</li>
<p>This will set the language that will be used to read and write the <tt>@execute</tt> key <em>value</em>.</p>
</ul>
<hrstyle="border: 1px dashed #000000">
<li><h4>@execute</h4></li>
<h5>Corresponds to the file "<em>run</em>" for a <em>classic</em> or
<em>longrun</em> service and to the file "<em>up</em>" for
a <em>oneshot</em> service.</h5>
<p><tt>mandatory </tt> : yes (!)</p>
<p><tt>syntax </tt> : bracket</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>The command to execute when starting the daemon.</li>
<!-- The same as with @runas, why all of a sudden is it a daemon now? Could this be better named service here or would that be incorrect? -->
</ul>
<p><tt><strong>Note:</strong></tt> The field will be used as is. No changes will be applied at all. It's the
responsability of the author to make sure that the content of this field is correct.</p>
</ul>
<br><hr>
<h2id="stop">Section: [stop]</h2>
<p>This section is <em>optional</em>.</p>
<p>This section is exactly the same as <tt><ahref="#start">[start]</a></tt> and shares the same keys. With the exception that
it will only be considered when creating the file "<em>finish</em>" for a <em>classic</em> or <em>longrun</em> service
and when creating the file "<em>down</em>" for a <em>oneshot</em> service to create its content.</p>
<!-- Did I get that right? ._." -->
<br><hr>
<h2id="logger">Section: [logger]</h2>
<p>This section is <em>optional</em>.</p>
<p>It will only have an effect when the value <tt>log</tt> is added to the
<tt>@options</tt> key in the <tt>[main]</tt> section.</p>
<p>This section accepts the <tt>@build,@runas,@shebang,@execute</tt> key field
as the manner as the section <tt><ahref="#start">start</a>,<ahref="#stop">stop</a></tt>
and <tt>@timeout-finish,@timeout-kill</tt> key field as the section
<tt><ahref="#main">main</a></tt>more :</p>
<!-- You completely lost me here. I can not make any sense of this paragraph, sorry. -->
<h3>Valid <em>key</em> names:</h3>
<ul>
<li><h4>@destination</h4></li>
<h5>Without equivalent, this key is unique to 66 tools.</h5>
<p><tt>mandatory </tt> : no</p>
<p><tt>syntax </tt> : slash</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>Any valid path on the system.</li>
<!-- Only absolute or relative as well?
Must this directory be present? Is that what valid means here?
Or will it be created if not?
Could be:
"Any existing absolute path on the system" or
"An absolute path"
-->
<p>The directory where to save the log file. <!-- "The path must exist and be writable by [...?]." --> The default is <tt>/var/log/66/servicename</tt> for <tt>root</tt> and
<tt>$HOME/.66/log/servicename</tt> for any regular user. The default can also be changed at compile-time by
passing the <tt>--with-system-logpath=<em>DIR</em></tt> option
for root and <tt>--with-user-logpath=<em>DIR</em></tt> for a user to <tt>./configure.</tt></p>
</ul>
<hrstyle="border: 1px dashed #000000">
<li><h4>@backup</h4></li>
<h5>Without equivalent, this key is unique to 66 tools.</h5>
<p><tt>mandatory </tt> : no</p>
<p><tt>syntax </tt> : uint</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>Any valid number.</li>
<p>The log directory will keep <em>value</em> files.
The next log to be saved will replace the oldest file present. By default 3 files are kept.</p>
</ul>
<hrstyle="border: 1px dashed #000000">
<li><h4>@maxsize</h4></li>
<h5>Without equivalent, this key is unique to 66 tools.</h5>
<p><tt>mandatory </tt> : no</p>
<p><tt>syntax </tt> : uint</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>Any valid number.</li>
<p>A new log file will be created every time the current one approaches <em>value</em>
bytes. By default, filesize is <tt>1000000</tt>; it cannot be set lower than <tt>4096</tt>
or higher than <tt>268435455</tt>.</p>
</ul>
<hrstyle="border: 1px dashed #000000">
<li><h4>@timestamp</h4></li>
<h5>Without equivalent, this key is unique to 66 tools.</h5>
<p><tt>mandatory </tt> : no</p>
<p><tt>syntax </tt> : inline</p>
<p><tt>valid value </tt> :</p>
<ul>
<li>TAI
<p>The logged line will be preceded by a TAI64N timestamp
(and a space) before being processed by the next action directive.</p></li>
<li>ISO
<p>The selected line will be preceded by a ISO 8601 timestamp for
combined date and time representing local time according to the
systems timezone, with a space (not a 'T') between the date and
the time and two spaces after the time, before being processed by
the next action directive.</p></li>
</ul>
</ul>
<br><hr>
<h2id="environment">Section: [environment]</h2>
<p>This section is <em>optional</em>.</p>
<p>It will only have an effect when the value <tt>env</tt> is added to the
<tt>@options</tt> key in the <tt>[main]</tt> section.</p>
<p>A file named <em>key</em> with the <em>value</em> as contain will be
created by default at /etc/66/env/name_of_daemon directory. The default can also be changed at compile-time by
passing the <tt>--with-service-path=<em>DIR</em></tt> option to <tt>./configure</tt>.</p>
<h3>Valid <em>key</em> names:</h3>
<ul>
<li><h4>Any <em>key=value</em> pair</h4></li>
<h5>Without equivalent, this key is unique to 66 tools.</h5>
<p><tt>mandatory </tt> : no</p>
<p><tt>syntax </tt> : pair</p>
<p><tt>valid value </tt> :</p>
<ul>
<p>You can define any variables that you want to add to the environment
of the service. For example:</p>
<pre>
[environment]
RUNDIR=/run/openntpd
CMD_ARGS=-d -s
</pre>
<p>The '!' character can be put in front
of the <em>key=value</em> pair like this :</p>
<pre>
[environment]
!RUNDIR=/run/openntpd
!CMD_ARGS=-d -s
</pre>
<p>This will explicitly <em>not</em> set the <em>value</em>
of the <em>key</em> for the runtime process but only at the start of the daemon. <!-- Service?! -->
In this example the <em>key=value</em> pair passed to the command line does not need
to be present in the general environment variable of the daemon.</p><!-- Service?! -->
</ul>
</ul>
<br><hr>
<h2>A word about the @execute key</h2>
<p>As described above the <tt>@execute</tt> key can be written
in any language as long as you define the key <tt>@build</tt> as <em>custom</em>
and the <tt>@shebang</tt> key to the language interpreter to use. For example
if you want to write your <tt>@execute</tt> field with bash :
<pre> @build = custom
@shebang = "/usr/bin/bash"
@execute = (
echo "This script displays available services"
for i in $(ls /etc/66/service); do
echo "daemon : ${i} is available"
done
)
</pre>
This is an unnecessary example but it shows how to construct this use case. The parser will
put your <tt>@shebang</tt> at the beginning of the script and copy the contents of the <tt>@execute</tt> field. So, the resulting file will be :
<pre> #!/usr/bin/bash
echo "This script displays available services"
for i in $(ls /etc/66/service); do
echo "daemon : ${i} is available"
done</pre>
When using this sort of custom function <tt>@runas</tt> has <strong>no effect</strong>. You must define with care what you want to happen in a <em>custom</em>
case.</p>
<p>Furthermore when you set <tt>@build</tt> to <em>auto</em> the parser will take care about the
redirection of the ouput of the daemon <!-- Service?! --> when the logger is activated. When setting <tt>@build</tt> to <em>custom</em> though the parser will not do this automatically. You need to explicitly tell it to:
<pre> #!/usr/bin/bash
exec 2>&1
echo "This script redirects file descriptor 2 to the file descriptor 1"
echo "Then the logger reads the file descriptor 1 and you have"
echo "the error of the daemon written into the appropriate file"</pre>
</p>
<p>Finally you need to take care about how you define your environment variable
in the section <tt><ahref="#environment">[environment]</a></tt>. When setting <tt>@build</tt> to <em>auto</em> the parser will also take care about the '!' character if you use it. This character will have <strong>no effect</strong> in the case of <em>custom</em>.
</p>
<p>This same behavior applies to the <tt><ahref="#logger">[logger]</a></tt> section.
The fields <tt>@destination, @backup, @maxsize</tt> and <tt>@timestamp</tt> will have <strong>no effect</strong>
in a <em>custom</em> case. You need to explicitly define the program to use the logger and the options