Re: nosh version 1.28

From: Jonathan de Boyne Pollard <>
Date: Sun, 21 Aug 2016 12:04:22 +0100

I don't know why you asked about FreeBSD rc.d just on the Debian mailing
list; but I'm going to deal in both of those and others besides, here,
and things that apply across both, so I've re-included the FreeBSD
mailing list. (-:

2016-08-14 15:10, Julian Elischer:

> I don't know if I just missed it, or it isn't there but I have a
> question..
> You give examples of importing systemd service files. What about
> importing rc.d files with all their ability to run arbitrary shell
> commands.
> And once you have the services defined, what is the logical equivalent
> of rc.conf, which can supply parameters for each service and turn them
> on and off? can you import from rc.conf?
You did miss it. (-:

What you missed has grown to be a significant subsystem. It was actually
mentioned a couple of times in the 1.28 announcement. It's the external
configuration import subsystem. You can read about it in the nosh Guide:

xdg-open /usr/local/share/doc/nosh/external-formats.html

As you can see, there's a whole section on importing from rc.conf into
native service management mechanisms. ("rc.conf" covers several
sources, note, including a FreeNAS configuration database and
/etc/defaults/rc.conf .)

The native service mangement mechanisms are the "enable" and "disable"
subcommands to the system-control command, and using the envdir command
in the normal daemontools-family style way. The enable/disable
mechanism in "rc.conf" is treated as if it were a preset (in systemd
nomenclature). You tell service management to "preset" a service, and
it will look at /etc/rc.conf and /etc/rc.conf.local (as well as some
other preset mechanisms) to determine what to set the native
enable/disable state to. The user manual page for the preset subcommand
(of system-control) explains what the preset mechanisms are in detail.

You can set up environment directories how and where you like, but
there's a convention that is shared by the "convert-systemd-units" tool,
the "rcctl" shim, and the external configuration import subsystem as a
whole. This convention is an environment directory named "env" that is
in the service directory. The "rcctl" shim gets and sets variables
there; and the import subsystem places converted "rc.conf", /etc/fstab,
/etc/ttys, /etc/my.cnf, and other stuff there.

One example of this in action, out of many in the import subsystem, is
jails that have been set up the version 9 way in "rc.conf". Those are
turned into service bundles, with "env" environment directories that
contain environment settings such as "hostname", "mount_devfs", and
"interface". The "run" script for the jail service very simply turns
the environment variables into arguments to the "jail" comand. In a
system with an original OpenBSD "rcctl" command, one would expect to be
able to set (version 9) jail control variables by manipulating
/etc/rc.conf with commands like "rcctl set wibble hostname wobble". The
"rcctl" shim and this shared convention mean that one need not stray
that far from this if "rcctl" is one's habit: "rcctl set v9-jail_at_wibble
hostname wobble" does the "native" thing of setting the "hostname"
variable in the (conventional) environment variable directory for the
"v9-jail_at_wibble" service.

Bonus feature for those with other habits: With nosh service management
in place, one can actually import from /etc/rc.conf settings *on Debian*
(as long as one sets up a FreeBSD/PC-BSD-style /etc/defaults/rc.conf
pointing to it with rc_conf_files). One can use /etc/ttys, too.

As for importing scripts that run "arbitrary shell commands", there are
several points.

First, you may not need to. Note that most of what you get out of the
box in /etc/rc.d/ and /usr/local/etc/rc.d/ on FreeBSD and PC-BSD has
already been converted. Remember that project that I had to convert 157
services? Take a look at the nosh roadmap page. It's almost done.

Second, you may not need to. Take a look at what actually comes in the
nosh-bundles package nowadays. Discounting the 'cyclog_at_' service
bundles there are just over 540 service bundles in there, from samba to
ntp, from saned to ossec_at_agentd. (Including the 'cyclog@' service
bundles, it is over a thousand service bundles.) The Debian world
doesn't get left out, either. Although it's a lot more difficult than in
the BSD worlds to come up with a list of "core" Debian services, a lot
of the basics of Debian are also covered by this, from kernel-vt-setfont
through irqbalance to update-binfmts. And those more-than-540 service
bundles cover lots of "non-core" stuff, from (as aforementioned)
OSSEC-HIDS, Salt, and RabbitMQ to publicfile httpd over IPV6.

Third, you may not need to. This was mentioned in the 1.28
announcement, in fact. The external configuration import subsystem
makes *further* service bundles, beyond the pre-made ones that come in a
binary package. It creates service bundles to run (optional) per-user
service management, per-user Desktop Bus brokers, MySQL and MariaDB
servers (according to your my.cnf), PPP and SPPP, md and pefs, jails
(set up with v9 rc.conf or the PC-BSD Warden), tinydns and dnscache
services (not quite ready when 1.28 came out, as the announcement said),
static IP4/IP6/ARP/NDP setup and teardown, and more besides.

Fourth, you may not need to. Out of all of this, there's probably
already an existing service bundle for something similar that one can
copy and adapt.

Fifth, you may not need to. The convert-systemd-units tool exists,
after all. If there's a system service/socket unit around, converting
that may well be simpler starting point than starting with an rc
script. It's usually significantly simpler than starting with a van
Smoorenburg rc script, although Mewburn and OpenBSD rc scripts can
themselves be fairly simple starting points. I did a "make fetch" on
the PC-BSD ports tree a couple of months ago. (As an aside: there are
several broken ports that don't do the right thing here.) There are a
growing number of packages where there's now a systemd service/socket
unit in the fetched source archive.

Sixth, the easy cases are easy. As just noted, Mewburn and OpenBSD rc
scripts can themselves be fairly simple. (They are not *always* so,
though, contrary to popular belief.) If you have an rc script that says
"The command name is this, its arguments are that.", it is very easy
indeed to convert this into something that can execute as a "run"
program. Setting up all of the stuff around the "run" program for a
complete service bundle is merely an exercise in two-line shell scripts
(for things like "start" and "stop") and making directories and symbolic
links (for things like the "before" and "wants" directories).

Seventh, the hard cases require a human being anyway. Parsing a shell
script that runs "arbitrary shell commands" would require creating what
is essentially a full shell script interpreter, that can handle the
Almquist, Bourne Again, and Korn shell syntaxes (because such a
hypothetical *general-case* conversion tool would have to address van
Smoorenburg rc scripts on Debian, Mewburn rc scripts on
FreeBSD/PC-BSD/NetBSD and friends, and OpenBSD rc scripts) that knows
about at least five quite different sets of "helper" commands (from
start-stop-daemon to startproc) and that works out how an entire shell
script translates into the actual acts of executing one or (in really
bad cases) more services. At this point, I defer to a human being
*understanding what is needed* and writing one or more service bundles. (-:

And there is, of course, scads of doco, written over the past two
decades by many people, on how to write daemontools-family-style "run"
Received on Sun Aug 21 2016 - 11:04:22 UTC

This archive was generated by hypermail 2.3.0 : Sun May 09 2021 - 19:44:19 UTC