Hi,

On Tue, 28 Mar 2023 20:30:59 +0200
Andras Korn <korn-debb...@elan.rulez.org> wrote:

> On Tue, Mar 28, 2023 at 01:10:36AM +0200, Lorenzo wrote:
> > I propose the following:
> > 
> > * patch runit-helper, update-service and /lib/runit/trigger_sv so
> > that every (package provided) runit service is always represented
> > in /etc/service/, either with a foo symlink (enabled) or with a
> > .foo symlink (disabled).
> 
> OK, this works (although I don't see why it's necessary), as long as
> nothing gets confused by the existence of both symlinks. For example,
> under this scheme, I may have:
Both links should not happen, a service is either enabled or disabled

> 
> /service/ssh -> /some/dir/where/I/keep/my/services/ssh
> # created "manually"
ok this should already override the default link to /etc/sv, there is
no code that replaces your link with one to /etc/sv/

> /service/.ssh -> /etc/sv/ssh
> # created during container provisioning to prevent
> the ssh package from installing its version of the service (otherwise
> it creates /etc/service/ssh/ssh)
old bug, runit-helper code didn't check for the existance of the symlink
and there was an infinite loop of symlinks (it doesn't create problem
to the service, but in any case should not happen), I thought I already
fixed this, will have another look

> 
> If there is potential for confusion, then a mechanism to delete the
> .ssh symlink if/when the plain ssh symlink is present would also be
> needed.
> 
> >   This way I (as a packager) can test /etc/service/ to know if a
> > runscript exists in /etc/sv/.
> 
> You can, but I'm not sure I see why you have to. The /etc/sv location
> is not special per se; why does it matter whether there is anything
> there in particular?

Since I want to provide the nanny-automation (enable a service
when the package that ships the corresponding bin is installed and
disable it when such package is removed) I have to know where the stash
of available runit services is, to check if a native service exists and
to enable it by creating a symlink to it.
That's what other inits like Sysv and systemd do, and users that come
from those other inits expect such automation: that would be the case
for a large part of the ~350 runit-init users in Devuan.

> 
> >   For users that have their own runscripts collection somewhere in
> > the filesystem: they will enable their services by creating the foo
> > symlink, and they can have the sysv emulation skip certain services
> > (let's say a bar service) by creating a /etc/service/.bar symlink.
> 
> That's a needless extra hoop to jump through. When deciding whether
> to skip invoking /etc/init.d/bar, why is it better to check for the
> existence of "/etc/service/.bar" than "/etc/service/bar"? The latter
> needs to exist anyway, because that's what will cause runit to start
> the service.
Reason is that if none of the two link is there I'm sure that no
package provided runit service is available. For a use case on
user side, see at the bottom.

> > * turn the run_sysv_scripts into a runit service that test for
> > /etc/service/$name. Two main reason for this:
> 
> This needs to be thought through carefully (it would need to only run
> once, but finish before other services are started -- for example, it
> could do a runsvchdir in ./finish).

Not necessarily: by default in runit services are started asynchronously
so in principle there is no reason to run sysv scripts sequentially and
strictly before any runit service. Of course there are dependencies, my
bet is that no more than two maybe three loop are needed.
Of course there is an entire Debian cycle to prove me wrong.

> 
> >   1. users can disable it, or change it at their will, while any
> > change into /lib/runit/run_sysv_scripts is overwritten by the
> > package, so users are forced to change stage 2 and create their own
> > version of the script
> 
> You could also achieve this by preferring
> /etc/runit/lib/run_sysv_scripts if it is executable, and only running
> /lib/runit/run_sysv_scripts if not. Even more complex setups would
> also be possible, with /lib/runit/run_sysv_scripts relying on shell
> functions that a user-supplied sourced file could override, but I
> think that would go too far.
The point is that I would like to drop this sysv emulation; runit need
to be able to run scripts before runsvdir starts services, an it can be
done in stage2, but such scripts don't necessarily need to be sysv
scripts, and don't need to obey the sysv (insserv) order. For now I'm
just going to separate the two mechanism.

> 
> >   2. when runit services are mixed with sysv scripts in the start
> > sequence, the run_sysv_scripts can be RC-buggy, see #1024969 [1]
> > for an example
> 
> Yeah, that's a hard problem to solve cleanly.
> 
> Maybe you just shouldn't ship (or enable by default) runit services
> that initscript-based stuff frequently depends on. I'm not sure how
> much else there is, other than dbus.
I think there are syslog, rmnologin and dbus: the one that really
breaks stuff is dbus, the other two are less important (or much harder
to trigger/notice).
> 
> Alternatively, you could ship a one-shot runit service that depends
> on the dbus service and that invokes all initscripts that declare a
> dependency on dbus... Far from my idea of clean.
> 
> I also have another idea but it's so complex that I won't even write
> it down. :)
> 
> I'd be perfectly fine with manual setup being required to run dbus
> from runit. The <15 users worldwide who want to do so can do it.
> 
> > > This is still imperfect during boot because /etc/service may
> > > point to some directory that is not the one we'll switch to with
> > > runsvdir in stage 2. I don't know what the best way of handling
> > > this (likely rare) case is, but the following solutions come to
> > > mind:
> > 
> > I think with the above solution this should be no longer a problem
> > as we run the sysv emulation from within runsvdir.
> >
> > Hopefully this will make your "runit" life easier (?)
> 
> I'm not sure the added complexity is worth it.
> 
> One alternative would be to just have people who actively use
> runsvchdir provide their own solution to avoid starting initscripts
> that don't need to be started (giving them some hooks to make this
> easier).
> 
> I suspect that for most users, the "/etc/runit/runsvdir/current"
> symlink never changes, and thus relying on seeing whether
> /etc/service/foo exists before starting /etc/init.d/foo is
> sufficient. People who want more complexity should have the option to
> implement it, but I don't think it's necessary to push complexity on
> everyone.

I'm doing a bit different: people who use runsvchdir to run a non
default directory will have to enable services by their own and
sysv.emulation is a service, so they'll have to enable it if they want
it.

> 
> Whatever you do is just going to be an imperfect heuristic anyway;
> for example, maybe the user has /etc/service/apache2-{foo,bar,baz}
> and doesn't want /etc/init.d/apache2 started. Such cases will need
> manual configuration, and we should accept that.
This would be a use case for the /etc/service/.apache2 symlink

Lorenzo

> 
> AndrĂ¡s
> 

Reply via email to