Re: s6-rc design ; comparison with anopa

2015-04-25 Thread Colin Booth
On Sat, Apr 25, 2015 at 12:36:24PM +0200, Laurent Bercot wrote:
> On 25/04/2015 09:35, Colin Booth wrote:
> >I've been having a hard time thinking about bundles the right way. At
> >first they seemed like first-class services along with longruns and
> >oneshots, but it sounds more like they are more of a shorthand to
> >reference a collection of atomic services than a service in their own
> >right. Especially since bundles can't depend on anything it clarifies
> >things greatly to think of them as a shorthand for a collection of
> >atomic services instead of a service itself.
> 
>  Yes, that's exactly what a bundle is: a shorthand for a collection of
> atomic services. Sorry if I didn't make it clear enough.
> 
Sounds good. I was having problems reconciling a bundle as a full
service and the ability to bring down bundle A and have it change bundle
B if there was overlap in member services. In more concrete terms, if we
have bundle web {httpd, php, sql} and bundle java {tomcat, sql} and we
ask to shut down java, if bundles were first-class services than I'd
expect to have s6-rc bring down tomcat and keep sql running since it's a
component of another bundle that still needs to be up. 

This actually brings up another question, is there any provision for
automatic bundling? If sshd requires sshd-log and a oneshot to create a
chroot directory does s6-compile also create a bundle to represent that 
relationship or do we need to define those namings ourselves. This is
the inverse of my question about loggers being implicit dependencies of
services. 
> 
> >As long as A depends on B depends on C, if you ask s6-rc (or whatever)
> >to shutdown A, the dependency manager should be able to walk the graph,
> >find C as a terminal point, and then unwind C to B then finally A. While
> >packagers will screw up their dependency graph, they'll screw it up (and
> >fix it) in the instantiation direction.
> 
>  If A depends on B depends on C, and you ask s6-rc to shutdown A, then it
> will *only* shutdown A. Hoever, if you ask it to shutdown C, then it will
> shutdown A first, then B, then C. For shutdowns, s6-rc uses the graph of
> reverse dependencies (which is computed at compile time).
> 
That's actually what I meant wrt the order. Mostly it was a comment
about how packagers will screw up dependencies but that it'll get
screwed up in the startup direction.
> 
> 
> >If you have a wireless router running hostapd (to handle monitor mode on
> >your radios) and dnsmasq (for dhcp and dns) you're going to want an
> >ordering where dnsmasq starts before hostapd is allowed to run. There's
> >isn't anything in hostapd what explicitly requires dnsmasq to be running
> >(so no dependency in the classic sense) but you do need those started in
> >the right order to avoid a race between a wireless connection and the
> >ability to get an ip address.
> 
>  Hmmm.
>  If hostapd dies and is restarted while dnsmasq is down, the race condition
> will also occur, right ?
>  Since hostapd, like any longrun process, may die at any time, I would
> argue that there's a real dependency from hostapd to dnsmasq. If dnsmasq
> is down, then hostapd is at risk of being nonfunctional. I still doubt
> "ordering" without "dependency" is a thing.
> 
It depends on the persons setup. In my case it's a user-supplied
dependency since there's nothing intrisic to dnsmasq or hostapd that
reqires them to run together which I currently get around by polling for
dnsmasq's status from within the hostapd run script. All in all it's a
semantic difference between dependencies that are needed to start
(dependencies), and depenencies that are needed for correct functioning 
but are not needed to run (orderings). The nice part is that while there
is a slim difference between the two, all the mechanisms for handling
dependencies can also handle orderings as long as the dependency tracker
handles user-supplied dependencies. Handling user supplied dependencies
also simplifies the system conceptually since people won't have to track
multiple types of requirements.

One last thing and I'm not sure if this has been mentioned earlier, but
how easy is it to introspect the compiled form without using the
supplied tools? A binary dumper is probably good enough, but I'd hate to 
be in a situation where the only way to debug a dependency ordering 
issue that the compiler introduced is from within the confines of the 
s6-rc-* ecosystem.

Cheers!
-Colin


Re: s6-rc design ; comparison with anopa

2015-04-25 Thread Laurent Bercot

On 25/04/2015 09:35, Colin Booth wrote:

I've been having a hard time thinking about bundles the right way. At
first they seemed like first-class services along with longruns and
oneshots, but it sounds more like they are more of a shorthand to
reference a collection of atomic services than a service in their own
right. Especially since bundles can't depend on anything it clarifies
things greatly to think of them as a shorthand for a collection of
atomic services instead of a service itself.


 Yes, that's exactly what a bundle is: a shorthand for a collection of
atomic services. Sorry if I didn't make it clear enough.



As long as A depends on B depends on C, if you ask s6-rc (or whatever)
to shutdown A, the dependency manager should be able to walk the graph,
find C as a terminal point, and then unwind C to B then finally A. While
packagers will screw up their dependency graph, they'll screw it up (and
fix it) in the instantiation direction.


 If A depends on B depends on C, and you ask s6-rc to shutdown A, then it
will *only* shutdown A. Hoever, if you ask it to shutdown C, then it will
shutdown A first, then B, then C. For shutdowns, s6-rc uses the graph of
reverse dependencies (which is computed at compile time).



Will s6-rc make loggers implicit dependencies of services, or will need
to define that? In other words, if we have a bundle 'ssh-daemon' that
contains the longruns sshd and sshd/log, will the dependency compiler
correctly link those so that when you ask the bundle to start it brings
up sshd/log first, and when you ask it to start it brings down the
logger last.


 Unless there's a compelling reason not to, if there's a "sshd" service
and a "sshd-log" service and there's an annotation somewhere in the
definition of sshd or sshd-log that sshd-log is the logger for
sshd, then s6-rc-compile will automatically create a dependency from
sshd to sshd-log, and ensure that $live/servicedirs/sshd is the servie
directory for sshd and $live/servicedirs/sshd/log is the service
directory for sshd-log.
 So yes, when you start the sshd-daemon bundle, s6-rc will start the
logger first and then the daemon, or stop the daemon first and then the
logger.



Are oneshots assumed (requored) to be idempotent? Or does $live/state
track if a oneshot has already been fired and no-op if that is the case?


 $live/state tracks oneshots, of course. :)



Not to be too pedantic, but how often do daemons ask for user input? I
don't know about you, but being required to pass user input on boot is a
big nono in my book.


 Tell that to Olivier. :)
 ISTR some encrypted filesystems require a passphrase to be given at
mount time, so this is a real use case. I don't intend to add terminal
support to s6-rc; if the problem comes up, i.e. if several terminal-
using services are started in parallel and conflicts arise, I'll think
of a specific solution in time.



So components of a bundle can fail and the bundle is still considered to
be functional? This make sense only if bundles are really tag sets or
some other loose grouping.


 Yes, that's what they are. The atomic services that can be started are
still started; however, the "s6-rc -u bundle" invocation will exit
nonzero, since some atomic services failed. It is then possible to use
some ui to list running atomic services and see what has succeeded and
what has failed.



If you have a wireless router running hostapd (to handle monitor mode on
your radios) and dnsmasq (for dhcp and dns) you're going to want an
ordering where dnsmasq starts before hostapd is allowed to run. There's
isn't anything in hostapd what explicitly requires dnsmasq to be running
(so no dependency in the classic sense) but you do need those started in
the right order to avoid a race between a wireless connection and the
ability to get an ip address.


 Hmmm.
 If hostapd dies and is restarted while dnsmasq is down, the race condition
will also occur, right ?
 Since hostapd, like any longrun process, may die at any time, I would
argue that there's a real dependency from hostapd to dnsmasq. If dnsmasq
is down, then hostapd is at risk of being nonfunctional. I still doubt
"ordering" without "dependency" is a thing.



Shouldn't this be handled prior to Stage-2 handoff? At the tail-end of
Stage-1 you Try to start a getty along with the catch-all logger. If
that fails we bring up our debug shell. Assuming it doesn't fail,
Stage-2 starts, s6-rc does its work, and brings up the `gettys' bundle
which no-ops on getty-1 (already started) and bring up 2-N. As long as
s6-rc is constrained to Stage-2 and multiple start attempts on a service
remain idempotent, we should be able to use the same shell escape-hatch
mechanisms in the early stages without having to add extra logic
handling to the application.


 Yes, for the initial getty or debug shell, this can be directly handled
in stage 1. For other conditional executions, I think conditionally
running different s6-rc invocations will be enough. In any case, it can

Re: s6-rc design ; comparison with anopa

2015-04-25 Thread Joan Picanyol i Puig
* Laurent Bercot  [20150425 03:10]:
>  Bundles are great. You can define a bundle for every possible combination
> of services if you're so inclined (it's still 2^n, so don't overdo it, but
> yeah).

This means that a service can be part of more than one bundle right?

> >What I like with aa-enable is that servicedirs are created from a source
> >servicedir and some config data. So one can have a single openvpn@
> >source servicedir, and use it to create different servicedirs with
> >different configs. There's also the bits to easily use the same logger,
> >but also service-specific log script...
> 
>  s6-rc-compile actually generates the servicedirs from the source data,
> which isn't exactly a servicedir - it contains run and finish scripts,
> but also additional information. I haven't settled on a format yet, if
> for instance instantiability is important I'll think about supporting it.

FWIW, I do believe instantiability is an important feature: it enables
the common use case administratively scaling the ability to serve
independent but similar services (a.k.a. "virtual" hosting, or
"multi-tenant").

> >The wants dependencies are just a way to pull a service without failing
> >if that service fails to start, some sort of "optional dependency" I guess.
> >E.g. one could say that php only wants sqld, so even if the later can't
> >be started the website can work, and everything that doesn't need db
> >will work, the rest failing with db connection errors, instead of having
> >no website at all.
> 
>  I see. With s6-rc, you would just make a "web" bundle, containing "httpd"
> and "php", and a "web+sqld" bundle, containing "web" and "sqld". You would
> launch web+sqld, and even if sqld fails, httpd and php are still brought up.

Remember to put this example in the documentation ;)

> >Separating order & dependency also allows to set up some order in
> >services in case, but without the need for them to be actual
> >dependencies, which may also be handy for source servicedirs to plan for
> >different uses/configs.
> 
>  Do you have a real-life example ? I can imagine how that can be useful,
> but a dependency manager is complex enough as is, and I don't want to
> add more complexity if there's no real, actual use for it that cannot
> be achieved another way.

I believe the motivation here is easy of use: the ability to re-use
service definitions for different setups. It's similar to the "wants"
dependencies: it's easier to setup a configuration with wider purposes
if "wants" is supported.

As I see it it's a "nice-to-have": it need not be in an initial release,
but it should be in the roadmap since it is not required but useful
feature.

qvb
--
pica


Re: s6-rc design ; comparison with anopa

2015-04-25 Thread Joan Picanyol i Puig
* Laurent Bercot  [20150424 00:24]:
> On 23/04/2015 23:26, Joan Picanyol i Puig wrote:
> >I'd really expect a ui that can "diff" "compiled" & "live" vs. "source" 
> >(and
> >obviously, to inspect "compile" & "live").
> 
>  There will definitely be a ui to inspect compiled + live.
> 
>  As for diffing the current state vs. source, I think it will be too
> complex, because it would amount more or less to performing the work
> of the compiler again. What can be done is something that compares
> two "compiled" databases, so to diff against the source, you would
> compile the source into a temp database then compare the temp to the
> current compiled.

That would certainly be enough.

> >I find ./down so convinient that would like having support for it in the
> >"source" format.
> 
>  The thing is, s6-rc already makes use of ./down internally. When you
> run "s6-rc -d this-longrun-service", it first brings down everything
> that depends on this-longrun-service, then creates ./down in
> this-longrun-service's service directory in live, then calls
> s6-svc -d on this-longrun-service. It says that the service is supposed
> to be down and remain that way, because that is the state you want to
> see enforced.

I probably did not explain myself.

What I'd like is the ability to have some services "ready-to-run", but not
up by default. Some of them might be there for contingency purposes (so
that an operator can start a failover), some of them might have to go up
(and down) at certain times only.

If a longrun-service can't be source-annotated with ./down, this use
case requires configuring a oneshot-service just to 's6-rc -d' it which
looks akward to say the least.


> > > I am thinking about a utility, "s6-rc-update", that would take the
> > > live, the old compiled and the new compiled as inputs, and that
> > > would update the live as smartly as possible, with carefully
> > > designed heuristics; users could also tell s6-rc-update exactly
> > > what to do via annotations in the source, that s6-rc-compile would
> > > translate into the new compiled.
> > > 
> >Any heuristics will face unsolvable situations. I'd aim at getting the
> >"patch" (dual of "diff" above) action right all the time first.
> >
>  That can be done, but with or without heuristics, there will still need
> to be a tool to actually update the live state. "diff" is easier than
> "patch"; the details of "patch" are what I'm interested in.

I lack knowledge & experience to attempt to provide details, so I'll
just handwave poiting that the first concept to have clear is that of
"identity": is this servicedir a "new" service definition or a
modification of an existing one? It then should be feasible to compute
the modifications needed to the live DAG (inserting/removing nodes as
well as restarting them).

qvb
--
pica