I don't think avoiding Turnstile (and similar projects) in favor of s6
services is reasonable, given the concerns you've raised in the first
block of https://skarnet.org/lists/supervision/3122.html (especially
"I'd like for the user supervision tree to only start on-demand").

I do not want to avoid them, they are straight up required to setup option B) from https://skarnet.org/lists/supervision/3114.html.

Instead, I want to delegate as few functionality to them as possible. Why should I e.g. delegate the creation a directory to a binary, configured through its own config file, if it would just be one line in a script that loads the defining variables and is ran anyway?


Turnstile's interface is reasonably simple and easy to implement in an
alternative: backends are effectively supervised 'run' (in the
s6/runit sense) scripts for the service manager with extra arguments,
and I believe it to be pretty much the minimum viable program for
adding XDG_RUNTIME_DIR compliance to any given service manager.
I experimented with Turnstile yesterday and hit major roadblocks.

Here is what I have understood it does:

once the user first logs in:

a1) execute "${BACKEND} run ${notification_fd}"    with an environment of ${USER}, ${HOME}, ...

 once ${BACKEND} writes back to ${notification_fd}:

a2) execute "${BACKEND} ready ${string}"    without the environment, but passing what was written back to ${notification_fd} beforehand as ${string}

once the user last logs out:

b1) execute "${BACKEND} stop"

b2) kill the process started in a1) (in our case s6-svscan)

From that structure I naturally would propose the following script, having ${XDG_RUNTIME_DIR} managed by Turnstile:


#!/usr/bin/env execlineb

importas directive 1
importas readinessPipe 2
importas -S XDG_RUNTIME_DIR
importas -S USER

case ${directive}
{
    run
    {
        foreground {
            install -d -o ${USER} -g ${USER} ${XDG_RUNTIME_DIR}/service
        }
        redirfd -w 3 ${readinessPipe} s6-svscan -d3 ${XDG_RUNTIME_DIR}/service
    }
    ready
    {
        foreground {
            s6-rc-init -c /home/${USER}/.local/share/s6-rc/compiled -l ${XDG_RUNTIME_DIR}/s6-rc ${XDG_RUNTIME_DIR}/service
        }
        s6-rc -v2 -l ${XDG_RUNTIME_DIR}/s6-rc -up change default
    }
    stop
    {
        s6-rc -l ${XDG_RUNTIME_DIR}/s6-rc -bDa change
    }
}

exit 100


This does not work, since when a2) is invoked to run the "ready" part, we do not have ${XDG_RUNTIME_DIR} anymore. I do not see how to solve this without a workaround.

A possible workaround would be doubly defining XDG_RUNTIME_DIR, once in the Turnstile config and once in an env file which is sourced in the "ready" "function".


I have two major issues here:

A) ${BACKEND} is always invoked with the user's privileges, thus it can not create ${XDG_RUNTIME_DIR} itself.

B) a2) happens without the environment, see the issue with the script.


I think A) is a problem, since I am planning:

a)  to have a central user env file, preferably at /home/${USER}/.config/s6-env (${XDG_CONFIG_HOME}/s6-env), for the user to tweak his settings, e.g. ${DBUS_SESSION_BUS_ADDRESS}

b) to have a central sysadmin env file, preferably at /etc/s6-rc/config (or similar), for the system admin to tweak the settings, e.g. the ${XDG_RUNTIME_DIR} general structure, the creation of which has to be delegated to Turnstile, since the script does not have enough permissions. This would then have to be doubly defined(once in the Turnstile config and once in the env-file)


Saying "this will make it easier to implement an alternative"
overlooks the fact that the complexity will be shifted into the
service set and the service manager. Is it really worth it to go
through dynamic services and events (at least, one `install -d`
oneshot per user, and a first login/last logout event source), and
probably other things required to make this more reliable, pretty much
just to make a folder?
I agree about the complexity shift. But I think the solution of using Turnstile just as a "notifications-system" is the best: ideally it should do the following: if ${USER} first logs in, start the system service ${USER}, if he logs out of the last instance stop the system service ${USER}.

This yields the following advantages:

A) The added complexity is in my opinion negligible(see my current scripts here: https://skarnet.org/lists/supervision/3123.html).

B) My idea gives the sysadmin and the user more control over their system (e.g. basing the location of ${XDG_RUNTIME_DIR} on a central env file where other settings are set too).

C) My idea allows plugging the user supervision tree directly into the system supervision tree, with the following advantages

    1) Allowing to directly attach a "catch all" logger separated from the logger of Turnstile

    2) Keeping the chain of efficient and reliable "skarware" from the top of the tree until the last user service, without Turnstile in between.

D) Now if I want to replace Turnstile I only need to tell the Replacement the system service to start and stop. I think it is reasonable to plan that, since Turnstile is based on PAM and as Bercot said in https://skarnet.org/lists/supervision/3114.html:

  I'm not going to write such a program in the s6 suite, because all the
stuff around PAM and utmp is 1. very Linux-specific and 2. extremely
brittle and badly/underspecified. At some point, however, I intend to
take a good look at PAM and brainstorm about a replacement, because the
current situation is just holding with massive amounts of duct tape,
good
will and headaches, and this makes me fearful for the future.


Thank you for your valuable input!

Have a nice Sunday!


Paul