summaryrefslogtreecommitdiff
path: root/doc/s6-usertree-maker.html
blob: b62727aa0284e0991ba63c9d4417b0bc594731c4 (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
<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>s6: the s6-usertree-maker program</title>
    <meta name="Description" content="s6: the s6-usertree-maker program" />
    <meta name="Keywords" content="s6 command s6-usertree-maker user supervision tree s6-svscan" />
    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
  </head>
<body>

<p>
<a href="index.html">s6</a><br />
<a href="//skarnet.org/software/">Software</a><br />
<a href="//skarnet.org/">skarnet.org</a>
</p>

<h1> The s6-usertree-maker program </h1>

<p>
s6-usertree-maker creates a <a href="servicedir.html">service directory</a>
implementing a service that runs an <a href="s6-svscan.html">s6-svscan</a>
instance owned by a given user, on a <a href="scandir.html">scan directory</a>
belonging to that user. It is meant to help admins deploy systems where
each user has their own supervision subtree, rooted in the main supervision
tree owned by root.
</p>

<p>
 Alternatively, s6-usertree-maker can create source definition directories
for the <a href="//skarnet.org/software/s6-rc/">s6-rc</a> service manager.
</p>

<h2> Interface </h2>

<pre>
     s6-usertree-maker \
       [ -d <em>userscandir</em> ] \
       [ -p <em>path</em> ] \
       [ -E <em>envdir</em> [ -e <em>var</em> -e <em>var</em> ... ] ] \
       [ -r <em>service</em>/<em>logger</em>[/<em>pipeline</em>] ] \
       [ -l <em>loguser</em> ] \
       [ -t <em>stamptype</em> ] \
       [ -n <em>nfiles</em> ] \
       [ -s <em>filesize</em> ] \
       [ -S <em>maxsize</em> ] \
       user logdir dir
</pre>

<p>
s6-usertree-maker creates a service directory in <em>dir</em>, that launches
a supervision tree as user <em>user</em> on scan directory <em>userscandir</em>,
with a catch-all logger logging the tree's output via
<a href="s6-log.html">s6-log</a> to the <em>logdir</em> directory.
</p>

<h2> Exit codes </h2>

<ul>
 <li> 0: success </li>
 <li> 100: wrong usage </li>
 <li> 111: system call failed </li>
</ul>

<h2> Options </h2>

<ul>
 <li> <tt>-d</tt>&nbsp;<em>userscandir</em>&nbsp;: the supervision tree will be run
on the <em>userscandir</em> directory. <em>userscandir</em> is subject to variable
substitution (see below). Default is <strong><tt>${HOME}/service</tt></strong>. </li> <br />

 <li> <tt>-p</tt>&nbsp;<em>path</em>&nbsp;: the supervision tree will be run with a
PATH environment variable set to <em>path</em>. <em>path</em> is subject to variable
substitution. Default is <strong><tt>/usr/bin:/bin</tt></strong>, or whatever has been
given to the <tt>--with-default-path</tt> option to skalibs' configure script. </li> <br />

 <li> <tt>-E</tt>&nbsp;<em>envdir</em>&nbsp;: the supervision tree will be run with
the environment variables defined in the directory <em>envdir</em>, which will be
read via <a href="s6-envdir.html">s6-envdir</a> without options. By default, no
envdir is defined and the supervision tree will only be run with the basic
environment variables listed below. </li> <br />

 <li> <tt>-e</tt>&nbsp;<em>var</em>&nbsp;: Perform variable substitution on <em>var</em>.
This option is repeatable, and only makes sense when the <tt>-E</tt> option is also
given. For every <em>var</em> listed via a <tt>-e</tt> option, the contents of
<em>var</em> will be subjected to variable substitution before the supervision tree
is run. This is only useful if <em>var</em> is defined in <em>envdir</em>, as a
template, that is then instanced for <em>user</em> when the service is run. By
default, only the PATH environment variable, customizable via <tt>-p</tt>, is
subjected to variable substitution. </li> <br />

 <li> <tt>-r</tt>&nbsp;<em>service</em>/<em>logger</em>/<em>pipeline</em>&nbsp;:
create <a href="//skarnet.org/software/s6-rc">s6-rc</a> source definition directories.
When this option is given, <em>dir</em> is not created as a service directory, but
as a directory containing two services: <em>dir</em>/<em>service</em> and
<em>dir</em>/<em>logger</em>, and <em>dir</em> is suitable as a source argument to
<a href="//skarnet.org/software/s6-rc/s6-rc-compile.html">s6-rc-compile</a>. The
<tt>/</tt><em>pipeline</em> part can be omitted, but if it is present, <em>pipeline</em>
is used as a name for a bundle containing both <em>service</em> and <em>logger</em>.
When this option is not given, <em>dir</em> is a regular service directory for direct
inclusion (or linking) in the parent scan directory (and the catch-all logger for
the user subtree is declared in <em>dir</em><tt>/log</tt>). </li> <br />

 <li> <tt>-l</tt>&nbsp;<em>loguser</em>&nbsp;: run the catch-all logger of the user
subdirectory as user <em>loguser</em>. Default is <strong><tt>root</tt></strong>. </li> <br />

 <li> <tt>-t</tt>&nbsp;<em>stamptype</em>&nbsp;: how
logs are timestamped by the catch-all logger. 0 means no
timestamp, 1 means
<a href="https://cr.yp.to/libtai/tai64.html">external TAI64N format</a>,
2 means
<a href="https://www.iso.org/iso/home/standards/iso8601.htm">ISO 8601 format</a>,
and 3 means both. Default is <strong><tt>1</tt></strong>. </li> <br />

  <li> <tt>-n</tt>&nbsp;<em>nfiles</em>&nbsp;: maximum number of archive files
in <em>logdir</em>. Default is <strong><tt>10</tt></strong>. </li> <br />

  <li> <tt>-s</tt>&nbsp;<em>filesize</em>&nbsp;: maximum size of the <tt>current</tt>
file (and archive files) in <em>logdir</em>. Default is <strong><tt>1000000</tt></strong>. </li> <br />

  <li> <tt>-S</tt>&nbsp;<em>maxsize</em>&nbsp;: maximum total size of the
archives in the <em>logdir</em>. Default is <strong><tt>0</tt></strong>,
meaning no limits apart from those enforced by the <tt>-n</tt> and
<tt>-s</tt> options. </li> <br />
</ul>

<h2> Operation of the service </h2>

<p>
 When the service is started, its run script will execute the following
operations:
</p>

<ul>
 <li> Clear all its environment variables, except PATH. This prevents
any data leak from the parent supervision tree into the user subtree. </li>
 <li> Fill its environment with data related to <em>user</em>:
  <ul>
   <li> USER is set to <em>user</em> </li>
   <li> HOME is set to <em>user</em>'s home directory </li>
   <li> UID is set to <em>user</em>'s uid </li>
   <li> GID is set to <em>user</em>'s primary gid </li>
   <li> GIDLIST is set to <em>user</em>'s supplementary groups list </li>
  </ul> </li>
 <li> If the service has been created with the <tt>-E</tt> option to s6-usertree-maker:
  <ul>
   <li> Add all the variables defined in <em>envdir</em> to its environment </li>
   <li> For every variable <em>var</em> given via a <tt>-e</tt> option, subject
<em>var</em> to substitution with the USER, HOME, UID, GID and GIDLIST variables
(see below). </li>
  </ul> </li>
 <li> Set the PATH environment variable to <em>path</em>, subjected to
variable substitution. </li>
 <li> Execute into <a href="s6-svscan.html">s6-svscan</a>, running in
<em>userscandir</em> (which is first subjected to variable substitution). </li>
</ul>

<p>
 The service is logged: its stderr and stdout are piped to an
<a href="s6-log.html">s6-log</a> process running as <em>loguser</em> and
writing to the <em>logdir</em> directory. This logger is the catch-all logger
for the supervision tree owned by <em>user</em>; it is recommended to make
<em>loguser</em> distinct from <em>user</em>, and to have <em>logdir</em>
in a place that is <strong>not</strong> under the control of <em>user</em>.
If <em>user</em> wants to keep control of their logs, they can declare a
logger for each of their services.
</p>

<h2> Variable substitution </h2>

<p>
 When the service starts, the USER, HOME, UID, GID and GIDLIST
environment variables are deduced from <em>user</em>'s identity.
The value of those variables may be used in a few configuration
knobs:
</p>

<ul>
 <li> The value of <em>userscandir</em>: it is likely that the
scan directory belonging to <em>user</em> resides under <em>user</em>'s
home directory. Or under <tt>/run/user/${UID}</tt>, or some similar
scheme. </li>
 <li> The PATH environment variable, declared in <em>path</em>: it is
often useful to prepend the default system PATH with a user-specific
directory that hosts that user's binaries. For instance, you may want
the PATH to be set as something like <tt>${HOME}/bin:/usr/bin:/bin</tt>. </li>
 <li> Any variable declared in <em>envdir</em> and given as an argument
to a <tt>-e</tt> option to s6-usertree-maker. If <em>envdir</em> is a
template valid for all users, it may contain variables that depends on
user-specific data: for instance, the XDG_CONFIG_HOME variable may be
set to <tt>${HOME}/.config</tt>. </li>
</ul>

<p>
 When the strings <tt>${USER}</tt>, <tt>${HOME}</tt>, <tt>${UID}</tt>,
<tt>${GID}</tt>, or <tt>${GIDLIST}</tt> appear in the value for
<em>userscandir</em>, <em>path</em>, or any of the <em>var</em>
variables, they are substituted with the corresponding value of the USER,
HOME, UID, GID, or GIDLIST environment variable instead.
</p>

<p>
 For instance, if no <tt>-d</tt> option is provided, the default value
for <em>userscandir</em> is <tt>${HOME}/service</tt>. If the provided
<em>user</em> is <tt>ska</tt> and ska's home directory is <tt>/home/ska</tt>,
then <a href="s6-svscan.html">s6-svscan</a> will be run on
<tt>/home/ska/service</tt>.
</p>

<h2> Examples </h2>

<pre>
     s6-usertree-maker -d '/run/user/${UID}/service' -p '${HOME}/bin:/usr/bin:/bin' -E /etc/user-env -e XDG_CONFIG_HOME -l catchlog ska /var/log/usertree/ska usertree-ska
</pre>

<p>
 creates a service directory in <tt>usertree-ska</tt> declaring a service that
starts a supervision tree on <tt>/run/user/1000/service</tt> if ska has uid 1000,
with <tt>/home/ska/bin:/usr/bin/bin</tt> as its PATH if ska's home directory is
<tt>/home/ska</tt>, and with all the environment variables declared in
<tt>/etc/user-env</tt>, among which the XDG_CONFIG_HOME variable is processed
for variable substitution. The supervision tree has a catch-all logger running
as user catchlog, and storing its data in the <tt>/var/log/usertree/ska</tt>
directory.
</p>

<p>
 Note that simple quotes are used here to prevent the shell from
interpreting <tt>${UID}</tt> and <tt>${HOME}</tt>.
</p>

<pre>
     s6-usertree-maker -d '/run/user/${UID}/service' -p '${HOME}/bin:/usr/bin:/bin' -E /etc/user-env -e XDG_CONFIG_HOME -l catchlog -r usertree-ska/usertree-ska-log/usertree-ska-pipeline ska /var/log/usertree/ska usertree
</pre>

<p>
 Same as above, except it does not create a service directory &mdash; instead, it
creates a <tt>usertree</tt> directory containing two subdirectories: <tt>usertree-ska</tt>, the
<a href="//skarnet.org/software/s6-rc/">s6-rc</a> source definition directory
for the service, and <tt>usertree-ska-log</tt>, the source definition directory
for its logger. It also creates an implicit <tt>usertree-ska-pipeline</tt> bundle
containing both the service and the logger.
</p>

<h2> Notes </h2>

<ul>
 <li> s6-usertree-maker makes use of the fact that
<a href="//skarnet.org/software/execline/">execline</a> scripts are much
easier to generate programmatically and to harden than shell scripts, so it is only
built if s6 is built with <a href="//skarnet.org/software/execline/">execline</a>
support - i.e. the <tt>--disable-execline</tt> switch has <em>not</em> been given
to configure. </li>
 <li> For the admin who wants to automate user tree management, s6-usertree-maker
is a <em>building block</em> meant to be used in scripts, not a complete turnkey
solution. For instance, s6-usertree-maker does not create <em>userscandir</em> for
a user: it assumes that that scandir is already in place. It does not create
<em>logdir</em> either: <em>logdir</em>, or at least its parent directory, must
already exist before the logger is run, else <a href="s6-log.html">s6-log</a> will
fail repeatedly. Make sure that all the data and metadata referenced by the service's
and the logger's run scripts are actually present and valid before starting the
service. </li>
 <li> If s6-usertree-maker encounters failure (and exits 111), it does not clean up
the directories it created. Make sure to always test s6-usertree-maker's return code
and clean up after it if needed. </li>
</ul>

</body>
</html>