Re[2]: Have an external script wait for a oneshot service

2024-12-06 Thread Laurent Bercot

We now have two examples of application from the other mails.


 And both can be solved without s6-rc in a simpler way than with it.


When I talked about "users", I mean people actually *using* these tools,
meaning s6, s6rc, execline, POSIX tools, ... hence power users and distribution 
maintainers.


 Yeah. So do I. Do you have any idea how difficult it is to make
distribution maintainers adopt the s6 paradigms? Change their habits
even a little bit? Do you have any idea of the inertia I've had to
bump against, again and again? When I tell you "make this simpler",
it's not because Joe Schmoe won't understand your stuff. It's because
Power Maintainer Dan J. Hacker won't want to jump through two hoops
so you better make sure there's only one.



I therefore try to make life as easy as possible for power users
and distribution maintainers, who manage their own supervision trees
or setup the presets for said managed distros respectively.


 If that really was what you're trying to do, you'd listen to me.

 Look, I *like* s6-rc. I'm happy that you like it too. I'm happy that
you want to use it. I'm happy when people use my stuff. Don't get me
wrong. But what I like even more is when the right tool is used for a
job, in the right place, with the right glue. That's what makes life
simpler for everyone, truly.



Assuming s6-rc is used for the main supervision tree and on login,
which is fair, since the very thing we discuss about is part of my project
doing all of that with s6-rc,
this would cause users to need to learn s6 additionally to s6-rc,
when s6-rc can be used for all cases.


 The vast majority of services a user will want to have are longruns.
And longruns are run under s6; longrun service definition directories
are pretty much s6 service directories. I don't think it's honest to
say "you only need to learn s6-rc, not s6"; the s6-rc learning curve
*includes* learning at least the fundamentals of s6.



This is an argumentum ad verecundiam.


 Not at all. I never refer to systemd as an authority (lol).
 It's just that systemd is maximalist: every use case they can think of,
they include. (Since the unit file format is extensive, they have to.)
They include way, way more than they should; they are by no means an
example to follow. My point is that if a use case isn't planned for in
systemd, there's a pretty good chance it's not a real one.

 Anyway. You obviously think your design is superior, so who am I to
say otherwise. We're not going to agree on this, so, since it's the
person who does the work who has the final say, you're right. Write your
project however you want to. But I'm not adding hooks to s6-rc to
support notification of intermediary states to external programs, 
because

I simply don't believe it's how it should be used.

--
 Laurent



Re[2]: Have an external script wait for a oneshot service

2024-12-05 Thread Laurent Bercot




fusermounting some network/encrypted filesystem comes to mind.
e.g. mount a NAS share so that a longrun snooze "cronjob" can record a
livestream to it.


 Okay. I'd argue it's still under the complexity line where doing
this manually - fuser(un)mounting at snooze service (de)installation
time - is easier and faster than setting up an s6-rc infrastructure.

--
 Laurent



Re[2]: Have an external script wait for a oneshot service

2024-12-05 Thread Laurent Bercot

- A Users might want to achieve a state of the user-tree on boot, which is 
impossible without s6-rc
  Though I have to admit that I can not find concrete examples of 
application.


 Exactly. That's the YAGNI principle: don't try to solve problems you
haven't encountered yet. Chances are you'll actually never encounter
them. Adding complexity in the name of "just in case" is overengineering
and it will only worsen your design.

 And if I have learned anything about users, it's that most of your
users will have trouble understanding what a supervised service is,
and if you start talking about them about s6-rc services, their brain
will start melting and they'll run away from your system as fast as
they can. And they won't be wrong.



- B Imagine the following scenario:

  A user wants to run a script every day at 12:00 and sets up a snooze 
user-longrun for that,


 So far so good (I understand Brett's point, but that should not be
the basis for an argument, because there are other things that can
only be achieved via a longrun, crontab is only an example here)



  which he installs and starts using s6-rc-init and s6-rc respectively 
while logged in,


 ... and here you lose me.

 The user has a supervision tree. They can install their longrun 
directly

in it. They don't need s6-rc for that. Pure s6 is enough.
 Their service will run as long as they keep it there. They can stop
it with s6-svc. Or s6-svunlink.

 s6-rc is good when you have an intricate mix of longruns and oneshots.
This is the case in a boot sequence. This *might* be the case for a
user login sequence. And this is almost certainly *not* the case for
a set of user services that you would hypothetically start at boot time
and do stuff with before a user even logs in, wtf.

 You want to run s6-rc at login time, sure, I can totally see where i
can be beneficial there. But earlier? Even systemd doesn't run user
stuff before a user logs in. And if *they* don't do it, it means that
there are ZERO use cases.


|  Now the server reboots, brings up the user-tree again, but 
without the snooze user-service of course.


 And what is preventing that? The fact that your default bundle does not
include the services that the user has defined themself. This should 
give

you a hint that this design goes against what supervision is supposed to
be doing, and thus, that it's not a good design. Whatever longrun the
user wants to have survive a reboot should survive a reboot and the
user shouldn't need a PhD to accomplish that.

 If the user has installed their service in the pure s6 way with e.g.
one (1) call to s6-svlink, it works: after a reboot, the snooze will
be back up.



All in all this would make things more complicated,
in that users have to learn and consider more things while distribution 
maintainers have more work.


 Exactly. You're *so close*.



So while I agree to you, that until I find a concrete examples for A,
s6-rc during "non-login" time is technically not necessary,
lacking it makes many things more inconvenient, complex and inconsistent.


 It's more inconvenient, complex and inconsistent because you want to
keep the framework that makes it so. Remove a little more and you'll
have something elegant again.



On the other side, why not have it? It is a feature that is probably going be
useful at some point and comes with little to no cost.


 Little to no cost? This whole thread is about the costs! And from my
perspective, "probably going to be useful at some point" is a pretty
light argument, it's definitely not going to outweigh "too complex to
make work properly".



Finally, I want to say that I really admire you being very conservative on 
adding features,
it is great to know that s6/s6-rc will stay sleek and efficient.


 Thank you. Now take inspiration from that for your own designs. ;)

--
 Laurent



Re[2]: Have an external script wait for a oneshot service

2024-12-05 Thread Laurent Bercot

- 2cA third system-oneshot does:
- 2ciPrepare the live directory for the user-tree for each user 
specified in config C (preferably under /run/user/${USER}).
- 2ciiRun "s6-rc-init" and "s6-rc start default" for each user 
specified in config C.
  (this can be merged with the instantiation system-oneshot if desired.)


 Okay. My point is, why do you need that "default" bundle here? Why do
you want an s6-rc infrastructure active when the user isn't logged in?

 I can understand a permanent supervision tree per user, but a permanent
service set that includes oneshots feels overengineered to me. What
problem is this supposed to solve?



- Upon login, a login script L shall invoke an "s6-rc start login" with 
("login" being a bundle) for the user logging in.
  (this can be further extended using PAM to run "s6-rc start ${PAM_TYPE}" to 
differentiate different types of logins)
  The script L can be started by PAM, .profile or in some other way.


 My advice is to do your whole 2c point at login time. The script L can
perform XDG stuff, s6-rc-init, and s6-rc start default. On last logout,
you stop everything with "s6-rc -da change" and you delete the livedir.
Only the supervision tree remains, maintaining whatever services the
user has manually added.

 I don't think there is a good argument for keeping state (which is
what oneshots do) in user services when the user is logged out. Feel
free to give counterexamples though.

--
 Laurent



Re[2]: Have an external script wait for a oneshot service

2024-12-05 Thread Laurent Bercot




To be more precise, I have the following setup:
- A longrun L setting up s6-svscan for a user-service-tree.

- A oneshot O setting up "s6-rc-init" and "s6-rc start default".

(two allow users to have services running on boot without login)

- A script run on login (bee it by PAM, .profile or another way),
  that starts user services only useful after login, e.g. pipewire.

Now of course the script should only be ran after the the "s6-rc-init" 
oneshot.


 I get the feeling there's an XY problem here, or some confusion (but
maybe just in my own brain) because user services are an underspecified
concept. Can you please describe the details of your setup: at what
time do you want to start up a supervision tree and an s6-rc-init
process for a given user?
 - at boot time? if so, how do you decide what users to start a
tree for?
 - at login time? if so, you have a script that you run at login time,
I don't see the problem here: start the tree and the s6-rc-init in that
script, not as a part of a set of s6-rc services.

--
 Laurent



Re[2]: Have an external script wait for a oneshot service

2024-12-04 Thread Laurent Bercot

Although it would be nicer to have a standard way to do this


 There is a standard way to block until a oneshot has completed:
depend on that oneshot.

 Duh.

 The thing is, s6-rc wasn't designed to have external scripts
interacting in this way with this engine, because if you have programs
depending on intermediary s6-rc states, they should be managed by s6-rc
as well. The point is to have a predictable machine state when s6-rc
exits; if you have random other stuff doing things in parallel, that
defeats the purpose.

 And with an s6-linux-init setup, at boot time there is no other
process than s6-rc managing your services. You have the supervision
tree, and the stage 2 script, and that's it. And if you're going to
spawn stuff in your rc.init that waits for oneshot X in the s6-rc db,
then... why? Why not have said stuff as another service?

 If you cannot, for whatever reason, maybe bring your services up in
two steps?
 s6-rc change X && stuff & s6-rc change default

 And if all else fails, the generic solution would be to have a oneshot
Y depending on X (so, that would run once X is done) that sends a
notification to a place of your choice via a mechanism of your choice,
you could use a fifodir and s6-ftrig-notify for this. You would still
have to deal with the race conditions around setting up the listener 
etc.


 The cleanest way to achieve what you want, without support in the
service set itself, is to s6-rc change X first, then s6-rc change the
rest of your services. That way, you avoid breaking abstraction with
hacks of questionable aesthetic value.

--
 Laurent