s6-frontend

A high-level interface for system administrators

s6-frontend is the high-level interface to the other components of the s6 init system. This document addresses the various elements that go into its design.

Table of contents

The need for such an interface

Historically, the s6 ecosystem has always been designed for maximum flexibility and adaptability. It follows a generic principle of software design: mechanism, not policy. This is a good principle, that ensures that no arbitrary limitations are placed upon the user; the software can be used in a variety of situations and configurations, including ones that the author of the software has not necessarily thought about.

A typical example of flexible design is the s6-ioconnect program. It was initially designed to perform full-duplex data transmission across the network; but it was written with the least possible amount of assumptions, so it became a core element of s6-supervision to perform full-duplex data transmission over Unix domain sockets as well - and nowadays it is also used in various pieces of software such as smtpd-starttls-proxy, to maintain data transmission between two local processes, even though the IPC mechanisms connecting those processes are pipes and not socket. This reusability of s6-ioconnect in unforeseen situations saves a lot of coding time and avoids a lot of code duplication.

However, the extreme flexibility of s6 tools is also a limitation to s6 adoption. While beloved by technical people who invest the time to get into it, understand its philosophy and get familiar with all the bits and pieces it has to offer, s6 is often seen by newcomers and non-specialists as arduous to approach, with a shallow (which means difficult) learning curve, because of the sheer amount of moving parts. Every part is small, clean, efficient and reusable, but it is not always obvious how to assemble them in the proper way; some criticism that has been aimed at s6 says that the complexity that has been removed from the software has not disappeared, but been transferred to the integrators.

And so, in order to make it easier for distributions to adopt and use s6, the ecosystem needs a capstone project: a piece of software that aims to provide the glue for all the other parts of s6, that assembles them in a meaningful and immediately usable way, and that mimics interfaces that system administrators are familiar with — interfaces that have contributed to the success of projects like systemd or OpenRC.

s6-frontend is this project, and is planned to be developed right after s6-rc is finished. Here is an overview of the features that s6-frontend will provide:

Service files

In s6-rc as well as in s6-supervision, the definition of a service includes at least one executable file, most often a script: the user ultimately needs to provide a command line that will start the service. That command line isn't always obvious to assemble; in particular, in s6-supervision, process state changes are implemented by a set of chainloading binaries that can be composed in a command line to achieve the desired process state and eventually execute into the binary providing the actual service. This achieves extreme versatility, but requires users to come up with long, complex command lines themselves; and modifying service parameters requires modifying the script that launches the service, which is an error-prone practice.

systemd uses a completely different approach: all the service configuration, including process state changes, is stored in unit files, which are purely declarative except for rather minimal command line bits that execute service binaries themselves, and that are included as strings in the unit file. (The way these strings are parsed and turned into command lines is both badly designed and badly implemented, as can be expected from systemd, but at least the idea is sensical.) All the configuration knobs are written in a human-friendly, well-known format: sequences of key=value lines.

OpenRC's service files are hybrids: ultimately, they're preprocessed shell scripts, and users can always provide shell script functions to override defaults, but in common cases OpenRC supplies implicit code snippets and a declarative key=value line is enough to yield the wanted behaviour. Over time, OpenRC has evolved in the direction of abstracting more and more shell functions and making its service files more and more declarative.

From a user interface point of view, systemd and OpenRC have the right idea. Declarative configuration files are easier to understand and modify than shell scripts or long command lines. System administrators intuitively understand the format; they don't have to undergo a complete paradigm shift when switching from an init system to another.

And so, in order to make things as easy as possible for sysadmins, s6-frontend will also provide declarative service files, in a format somewhat similar to systemd's unit files. As the package name says, these files will be a frontend: service configuration information will not be read directly from these files, but instead the declarative files will be processed and output in a format suitable for use with s6-rc. The service files are a human-friendly expression of the machine configuration, which is processed into their program-friendly expression used by the s6 tools.

Details on s6-frontend's service files are given in this document.

The s6 command

The variety of s6 tools is sometimes cause of confusion among novices; it is not always immediately obvious what command to use to perform a run-time operation. In particular, the distinction between the process supervisor layer and the service manager layer seems difficult to understand for people who are used to integrated init systems such as systemd, which do not make such a distinction. If I want to stop a service, should I send an s6-svc -d or an an s6-rc -d change command?

There is a lot to learn and remember, and the documentation for the s6 tools is necessarily scattered; there isn't a central manual page that users can refer to and learn everything there is to know about s6 usage. This contrasts with systemd, which has the one-stop-shop systemctl command, and to a lesser extent with OpenRC, which uses the service command in a similar, albeit much less developed, fashion.

Just like familiarity with configuration file format styles, ease of use and intuitiveness of run-time commands is a major factor for the adoption of a service manager by system administrators. systemctl restart foobar or service foobar restart are friendlier interfaces to humans than s6-svc -r /run/service/foobar or s6-rc -d change foobar && s6-rc -u change foobar.

Consequently, s6-frontend will provide a one-stop shop command with a similar high-level interface to service management. With s6-frontend installed, s6 service restart foobar should do exactly what people intuitively expect it should do. The details of what exact parts of the s6 ecosystem are leveraged and what sequence of operations will be hidden from users who choose to use the high-level s6 command. However, unlike with systemd and OpenRC, advanced users will still be able to benefit from s6's flexibility, because the low-level command will remain accessible to them.

Details on the s6 command are given in this document.

Turnkey default policy

Sysadmins who like systemd underline its declarative interface, and sysadmins who like OpenRC underline the easily understandable nature of its commands. But these service managers also provided something else that was a major factor in their adoption, something that does not target system administrators but distributions: a complete default policy.

In this context, by policy we mean: a complete set of service files handling basic services, device management, filesystem mounts, networking, etc. etc. so that a default boot sequence is already provided by upstream, and distributions only have to tweak service files and make minor additions in order to adapt that boot sequence to their own distro policies instead of having to come up with everything from scratch. Maintaining a distribution is a thankless job, maintainers are often overworked, and few are interested in learning the details of booting a Unix machine; although creating and providing a boot sequence in accordance with the distro's policies lies squarely in the middle of a maintainer's duties, systemd and OpenRC actually do a large part of the work for maintainers by providing a practically drop-in generic boot sequence — and that undoubtedly helped them become popular among numerous distributions.

By contrast, s6 has always followed the mechanism, not policy principle: all the tools to build a stable, reliable, fast and efficient boot sequence are there, but writing the actual boot scripts is still left to distributions. That represents a huge amount of work, which has probably been the main limiting factor in s6 adoption. Even the new version of s6-rc, which is being worked on, only provides binaries and documentation with a few examples; it sticks to mechanism, and does not implement policy at all. This is a principled approach we would like to keep, but making it easier for distributions to switch to the s6 ecosystem is also a worthy goal.

In that light, it makes sense for the s6-frontend package, aimed at distributions and novice end users, to come with a bundled, easily installable turnkey default policy, a set of service files that works out-of-the-box on a majority of Linux installations. (In order to really work out of the box, it needs to include early boot scripts, which are not portable; the s6-frontend package depends on the s6-linux-init package to manage the early initialization, so it has to be restricted to Linux systems, at least in the first step.)

s6-frontend can get some inspiration from OpenRC's boot scripts and systemd's unit files, but will need to come up with its own set of service files, organized in an s6-idiomatic way, in order to take full advantage of s6-supervision's reliability and s6-rc's guarantees and parallelism. Constructing these service files are an important part of the planned work.

Conclusion

Unlike the other parts of the s6 ecosystem that focuses on clean, efficient functionality, s6-frontend focuses on accessibility and friendliness. It is the last piece of the puzzle, the glue that ties all the other pieces together and makes a coherent whole. With s6-frontend, the s6 ecosystem will finally be a fully viable alternative to integrated init systems, and distributions will be able to embrace it without drawbacks.