* Essex: A simple command line interface for managing s6 services, using the s6 toolset
@ 2019-01-28 2:43 Andy Kluger
2019-01-28 10:54 ` Jonathan de Boyne Pollard
0 siblings, 1 reply; 2+ messages in thread
From: Andy Kluger @ 2019-01-28 2:43 UTC (permalink / raw)
To: supervision
Hello!
s6 is great, but its existing interface can feel a bit unwieldy for
me, and I need to re-read the docs frequently. So I've made a command
line frontend with helper functions for it, called essex:
on GitHub: https://github.com/AndydeCleyre/essex
video demo: https://streamable.com/oek3d
on PyPI: https://pypi.org/project/essex/
I hope someone else will also find it useful.
Here's an example runfile and loggerfile generated by the tool:
```
==> /home/andy/svcs/memdb/run <==
#!/bin/execlineb -P
fdmove -c 2 1 # Send stderr to stdout
foreground { redirfd -w 1 run.md5 md5sum run } # Generate hashfile,
to detect changes since launch
s6-setuidgid redis # Run as this user
cd /var/lib/redis # Enter working directory
redis-server # Do the thing
==> /home/andy/svcs/memdb/log/run <==
#!/bin/execlineb -P
foreground { redirfd -w 1 run.md5 md5sum run } # Generate hashfile,
to detect changes since launch
s6-log # Receive process output
T # Start each line with
an ISO 8601 timestamp
s4194304 # Archive log when it
gets this big (bytes)
S41943040 # Purge oldest
archived logs when the archive gets this big (bytes)
/home/andy/svcs-logs/memdb # Store logs here
```
It lends itself to aliases like:
`alias sussex="sudo essex -d /var/svcs"`
Thanks of course to skarnet for the excellent software that does all
the work, in a sane way, as well as the frequent immediate support and
feedback.
Essex does not (at least, not yet) offer any conveniences for
interdependence of processes, but for my cases thus far the usual
retry behavior is sufficient. I welcome advice on growing or otherwise
improving the project, if there's interest.
Please let me know if you try it! Feel free to submit issues, or reach
me on Telegram: https://t.me/andykluger , as I'm awful at noticing
emails from real humans.
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Essex: A simple command line interface for managing s6 services, using the s6 toolset
2019-01-28 2:43 Essex: A simple command line interface for managing s6 services, using the s6 toolset Andy Kluger
@ 2019-01-28 10:54 ` Jonathan de Boyne Pollard
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan de Boyne Pollard @ 2019-01-28 10:54 UTC (permalink / raw)
To: Supervision
[-- Attachment #1: Type: text/plain, Size: 7243 bytes --]
The |cat| subcommand is the one that seems to get most people. I have
seen more objections to that in systemd's |systemctl| than to any of the
others, because it really isn't concatenation as people are used to. I
provide it in my toolset because I provide migration paths for people
familiar with systemd. I would not have chosen |cat| myself, if I had
had the choice. (It is actually |grep| under the covers, not |cat|, for
starters.) If you are /not/ looking to have similar commands as a
systemd migration path, which seems to be the case from the other
subcommands that you have, you would probably do well to come up with a
better name than |cat|.
I went with |reset| rather than |sync|. |preset| sets the /enable/ state
from configuration information. |reset| sets the /start/ state from
configuration information, and as the manual says can be thought of as
"reset to however the service is configured to be at bootstrap" with
respect to start/stop. |sync| is not a bad name, but |system-control|
<http://jdebp.eu./Softwares/nosh/guide/commands/system-control.xml> can
do /system/-level stuff (e.g. |poweroff|) as well as /service/-level
stuff, and there is a definite quite different meaning to |sync| when
one is operating at system level which would not be a good idea to
overlap. You're providing service management and not system management,
and contrastingly are probably alright here.
Your |reload| is not what people have come to know and to think of by
that name, and will probably confuse people. What people have come to
know by that name is sending a "reload" signal (of some kind, the exact
signal varies) to the service telling the service to /keep running/ but
reload stuff. What you have is more akin to what people know as
|condrestart| or |try-restart|, although it is not quite those either,
because (for one thing) they do not have the side-effect of starting
currently stopped services as your |reload| subcommand does. See the
Debian /Policy Manual/
<https://www.debian.org/doc/debian-policy/ch-opersys.html#writing-the-scripts>
and the Fedora wiki
<https://fedoraproject.org/wiki/EPEL:SysVInitScripts?rd=Packaging:SysVInitScript#Required_Actions>
for the long standing meanings of the |try-restart| and |reload|
subcommands.
Placing the generation of the information that your |reload| operates on
actually in the |run| script itself is a bit of a layering violation.
Really, a framework to detect changes to |run| scripts should have no
effect on the |run| scripts contents themselves, certainly not the
requirement that they be modified to inject special extra commands. You
end up with user problems, with users setting up vanilla |run| scripts
that they get from elsewhere
<http://jdebp.eu./Softwares/nosh/guide/creating-bundles.html#collections>
and then not being able to successfully employ your tools on top of
that. You end up with mechanism problems, with a /single change/ to a
|run| script resulting in potentially /repeated/ termination signals (if
|reload| is called more than once, which people inevitably /will/ do)
until the part of the |run| script that regenerates the signature
actually re-runs, and takes.
Observe how I designed service bundles. They are layered on top of
|supervise/| and |service/| directories. Before/after orderings,
wants/conflicts dependencies, and the rest are all /outwith/ the
scripts, and do not require modifying them. Only |system-control| has
dealings in them. The scripts, the lower-level |service-control|
<http://jdebp.eu./Softwares/nosh/guide/commands/service-control.xml>/|svc|,
and indeed the |service-manager|
<http://jdebp.eu./Softwares/nosh/guide/commands/service-manager.xml>
itself, have no notion of /any/ of that. Indeed, it is one of /two/
ways of deciding what services to run, the other of which would be
adversely affected if all of the scripts had to incorporate tooling for
the first mechanism. Maintaining layering allows drop-in replacement,
and the administrator a choice of the |system-control| way or a
daemontools-style |service-dt-scanner|
<http://jdebp.eu./Softwares/nosh/guide/commands/service-dt-scanner.xml>/|svscan|
way.
Maintaining layering allows further forms of drop-in replacement, too.
My nosh toolset does not require that |run| scripts use the toolset's
own chain-loading utilities. It is just as happy with |run| scripts
that use execline, or the perp tools, or runit's |chpst|. The service
manager only cares that it's a program that it can |fexecve()|. Whereas
your tooling forces execline for everything, because you've built it
around having a snippet of execline code embedded in an execline script
as a part of the mechanism.
For a restart-if-the-|run|-script-has-changed framework, I suggest a
similar approach. The simplest approach is surely to have a per-service
|Makefile.essex|, or a set of redo |.do| scripts, that embodies the
if-file-X-changed-take-action-Y logic. That is after all what those
tools do. Then it is a matter of running |make -f Makefile.essex
restart-if-changed|, or |redo ||restart-if-changed|, against each
service. Or (alternatively) make a tool that knows about the extra
|.md5| files and like |make| and |redo| does the whole of the job in one
place, i.e. put all of the /(re-)generation/ logic into |EssexReload|
/as well//as/ the testing logic.
Then when you fix it to also take into account changes to environment
directories, which it does not at the moment (and so does not really
restart /all/ services whose definitions have changed), your users will
not have to go and laboriously fix all of their own |run| scripts to
include even more extra commands. Rather, your tooling fixes the
|Makefile.essex| or the |restart-if-changed.do| file (or the
|EssexReload| logic) that /belongs to it/, and the improvements happen
as a matter of course.
You also should think about what happens if someone makes two services
that share a single |service/| directory (but have their own
|supervise/| directories), and about whether making all services write
to files (with no precautionary checking that they are regular files)
before they drop superuser privileges has introduced an exploitable
security hole. (One has to at least do the analysis, even if the answer
turns out to be no. I've been musing on the idea of a |--write-new|
option to |fdredir|
<http://jdebp.eu./Softwares/nosh/guide/commands/fdredir.xml> for this;
although in 601 services as of version 1.39 only two even use it to
write, they both write to files in |/run/| where only the superuser
could place malicious links anyway, and one of them is obsoleted by the
klogd-read service. If the other were to become a problem, giving the
dynamic Message Of The Day its own user account, that could only update
that one file, would be an alternative solution. Although a better
solution yet is /not/ to have this as a service at all, consider it also
obsolete, and use |/etc/system-control/convert/motd|. The regeneration
point for the Debian-style dynamic Message Of The Day is when a file has
changed in |/etc/update-motd.d/| or the operating system has been
upgraded, not bootstrap.)
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-01-28 10:54 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-28 2:43 Essex: A simple command line interface for managing s6 services, using the s6 toolset Andy Kluger
2019-01-28 10:54 ` Jonathan de Boyne Pollard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).