S6-USERTREE-MAKER(8)
π s6-usertree-maker(8) π
okay so bestie, this is a section 8 man page β a System Manager's Manual situation β and today's main character is s6-usertree-maker. she's here to make your users their very own supervision trees and honestly? iconic.
β¨ NAME β¨
s6-usertree-maker β creates an s6-service-directory(7) that implements a service, and that service runs an s6-svscan(8) process which is owned by a given user, running on an s6-scan-directory(7) that belongs to that same user π«Ά
πΈ SYNOPSIS πΈ
s6-usertree-maker [-d userscandir] [-p path]
[-E envdir [-e var -e var ...]]
[-r service/logger[/pipeline]] [-l loguser]
[-t stamptype] [-n nfiles] [-s filesize] [-S maxsize]
[-P prefix] user logdir dir
π¦ DESCRIPTION π¦
s6-usertree-maker is basically the admin's bestie when you're deploying systems where every single user gets their own supervision subtree, rooted in the main supervision tree (the one owned by root). no cap, it's giving delegation π
okay and alternatively? s6-usertree-maker can also create source definition directories for the s6-rc[1] service manager. so it's versatile. we love a multi-talented queen.
so what does it actually do: s6-usertree-maker creates an s6-service-directory(7) in dir, and that directory launches a supervision tree as user user, on the s6-scan-directory(7) called userscandir, with a catch-all logger that logs the tree's output via s6-log(8) into the logdir directory. caught every last crumb of output. obsessed.
the trick here β the whole reason this works so nicely β is that execline[2] scripts are way easier to generate programmatically and to harden than shell scripts. so s6-usertree-maker only gets built if s6 is built with execline support, i.e. if the --disable-execline switch has not been given to configure. if you disabled execline, sorry bestie, this binary isn't happening π
now, important vibe check for the admin who wants to automate user tree management: s6-usertree-maker is a building block meant to be used in scripts, not a complete turnkey solution. it's a supporting character, not the lead. for instance:
s6-usertree-makerdoes not createuserscandirfor a user β it just assumes that thats6-scan-directory(7)is already in place.- it does not create
logdireither βlogdir, or at least its parent directory, must already exist before the logger is run, elses6-log(8)will fail repeatedly. π so, like, please make sure 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.
and here's a warning that matters: ifs6-usertree-makerencounters failure (and exits111), it does not clean up the directories it created. so like, always tests6-usertree-maker's return code and clean up after it if needed. she leaves a mess, you tidy it. that's the deal π
π Operation of the service π
when the service is started, its run script will execute the following operations, in order:
- Clear all its environment variables, except
PATH. this is the anti-leak measure β it prevents any data leak from the parent supervision tree into the user subtree. clean slate energy β¨ - Fill its environment with data related to
user:USERis set touser.HOMEis set touser's home directory.UIDis set touser's uid.GIDis set touser's primary gid.GIDLISTis set touser's supplementary groups list.
- If the service has been created with the
-Eoption tos6-usertree-maker:- Add all the variables defined in
envdirto its environment. - For every variable
vargiven via a-eoption, subjectvarto substitution with theUSER,HOME,UID,GIDandGIDLISTvariables (see below).
- Add all the variables defined in
- Set the
PATHenvironment variable topath, subjected to variable substitution. - Execute into
s6-svscan(8), running inuserscandir(which is first subjected to variable substitution).
and the service is logged β its stderr and stdout are piped to an s6-log(8) process running as loguser and writing to the logdir directory. this logger is the catch-all logger for the supervision tree owned by user.
lowkey a security note: it is recommended to makeloguserdistinct fromuser, and to havelogdirin a place that is not under the control ofuser. separation is self-care π§
if user wants to keep control of their logs, they can declare a logger for each of their services. their logs, their rules π
π Variable substitution π
when the service starts, the USER, HOME, UID, GID and GIDLIST environment variables are deduced from user's identity. and the values of those variables may be used in a few configuration knobs:
- The value of
userscandir: it's likely that thes6-scan-directory(7)belonging touserresides underuser's home directory. or under/run/user/${UID}, or some similar scheme. - The
PATHenvironment variable, declared inpath: it's often useful to prepend the default systemPATHwith a user-specific directory that hosts that user's binaries. for instance, you may want thePATHto be set as something like${HOME}/bin:/usr/bin:/bin. - Any variable declared in
envdirand given as an argument to an-eoption tos6-usertree-maker. ifenvdiris a template valid for all users, it may contain variables that depend on user-specific data: for instance, theXDG_CONFIG_HOMEvariable may be set to${HOME}/.config.
when the strings β${USER}β, β${HOME}β, β${UID}β, β${GID}β, or β${GIDLIST}β appear in the value for userscandir, path, or any of the var variables, they are substituted with the corresponding value of the USER, HOME, UID, GID, or GIDLIST environment variable instead. (yes, that quoting is exactly how the original rolls, don't come for me π«Ά)
for instance β a little example, because examples slay: if no -d option is provided, the default value for userscandir is ${HOME}/service. so if the provided user is βskaβ and ska's home directory is /home/ska, then s6-svscan(8) will be run on /home/ska/service. and that's the whole plot π₯
π OPTIONS π
-d userscandirβ the supervision tree will be run on theuserscandirdirectory.userscandiris subject to variable substitution (see above). default is${HOME}/service.-p pathβ the supervision tree will be run with aPATHenvironment variable set topath.pathis subject to variable substitution. default is/usr/bin:/bin, or whatever has been given to theβ--with-default-pathβoption toskalibs'configurescript.-E envdirβ the supervision tree will be run with the environment variables defined in the directoryenvdir, which will be read vias6-envdir(8)without options. by default, noenvdiris defined and the supervision tree will only be run with the basic environment variables listed below.-e varβ perform variable substitution onvar. this option is repeatable, and only makes sense when the-Eoption is also given. for everyvarlisted via an-eoption, the contents ofvarwill be subjected to variable substitution before the supervision tree is run. this is only useful ifvaris defined inenvdir, as a template, that is then instanced foruserwhen the service is run. by default, only thePATHenvironment variable, customizable via-p, is subjected to variable substitution.-r service/logger/pipelineβ create ans6-rc[1] source definition directory. when this option is given,diris not created as ans6-service-directory(7), but as a directory containing two services:dir/serviceanddir/logger, anddiris suitable as a source argument tos6-rc-compile[3]. theβ/pipelineβpart can be omitted, but if it is present,pipelineis used as a name for a bundle containing bothserviceandlogger. when this option is not given,diris 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 indir/log).-l loguserβ run the catch-all logger of the user subdirectory as userloguser. default isβrootβ.-t stamptypeβ how logs are timestamped by the catch-all logger.β0βmeans no timestamp,β1βmeans external TAI64N format[4],β2βmeans ISO 8601 format[5], andβ3βmeans both. default isβ1β.-n nfilesβ maximum number of archive files inlogdir. default isβ10β.-s filesizeβ maximum size of the current file (and archive files) inlogdir. default isβ1000000β.-S maxsizeβ maximum total size of the archives in thelogdir. default isβ0βmeaning no limits apart from those enforced by the-nand-soptions.-P prefixβ when logging tologdir, prefix logged lines with theprefixstring.
β EXIT STATUS β
0β Success. we love a happy ending π100β Wrong usage.111β System call failed. π and remember, no cleanup happens on this one!
π EXAMPLES π
okay here's the first one, look at her go:
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
this creates a service directory in βusertree-skaβ declaring a service that starts a supervision tree on /run/user/1000/service if ska has uid 1000, with /home/ska/bin:/usr/bin/bin as its PATH if ska's home directory is /home/ska, and with all the environment variables declared in /etc/user-env, 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 /var/log/usertree/ska directory.
note that simple quotes are used here to prevent the shell from interpretingβ${UID}βandβ${HOME}β. protect your variables, bestie π«Ά
and the second one, the s6-rc variant:
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
same as above, except it does not create a service directory. instead, it creates a βusertreeβ directory containing two subdirectories: βusertree-skaβ, the s6-rc[1] source definition directory for the service, and βusertree-ska-logβ, the source definition directory for its logger. it also creates an implicit βusertree-ska-pipelineβ bundle containing both the service and the logger. two birds, one gorgeous command β¨
π SEE ALSO π
- [1] https://skarnet.org/software/s6-rc/
- [2] https://skarnet.org/software/execline/
- [3] https://skarnet.org/software/s6-rc/s6-rc-compile.html
- [4] https://cr.yp.to/libtai/tai64.html
- [5] https://www.iso.org/iso/home/standards/iso8601.htm
this man page is ported from the authoritative documentation at: https://skarnet.org/software/s6/s6-usertree-maker.html
π AUTHORS π
- Laurent Bercot
- Alexis <flexibeast@gmail.com> (man page port)
and that's a wrap! π sourced from Debian, dated January 15, 2023, filed under S6-USERTREE-MAKER(8) β go forth and supervise, bestie πΈβ¨π
π¦ where this page comes from
- nixpkgs unstable: s6 2.15.1.0
- nixpkgs unstable: s6-man-pages 2.14.0.1.4
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms