s6-frontend: service files

Like unit files, but without the bad parts

Service files are the place where administrators configure all the services on their system, from the early boot to the top level of late, complex services. They are a critical piece of infrastructure, at the junction of low-level programming and user interaction. This document explains the design principles of the s6-rc service files, as well as their syntax.

Table of contents

Design principles

Service files are used by both human and machine, so they need to cater to two very different set of needs. Like designing a programming language, designing service files is a balancing act, made of choices and compromises. Here are some of the principles guiding the s6-frontend service files.

For humans

  • The syntax should be as declarative as possible. The point of using service files instead of init scripts is to make configuration simpler, more intuitive, and less error-prone. The amount of executable code (as in, command lines) contained in the service files should be kept to the absolute minimum; declarative configuration switches of the key=value form are safer and easier to maintain.
  • Service files should allow users to describe services the way they perceive them, even if it's not exactly the way they're represented internally for s6-rc. For instance, a service which as a daemon, a pre-exec command, and a post-exec command, should be declared as a simple service, even though it will ultimately be compiled into a bundle containing two oneshots and a longrun.
  • It should be possible to include service files, or even whole directories of service files. People naturally want to factor their configurations, and the syntax should make this easier, not harder.
  • No fancy quoting or similar idiosyncratic syntactic whimsy. Every bit of complex or unintuitive syntax makes editing files more difficult, more frustrating and more error-prone.
  • Liberal indentation and whitespace use. Anyone who has written a Netplan yaml file by hand understands why this is important.

For machines

  • The syntax should be unambiguous. Using heuristics is unreliable.
  • The grammar should be simple enough that a set of service files can be parsed in C without external libraries. That means at most a LALR grammar (but likely LL), with a preprocessing step to handle comments and file inclusion. That also precludes the use of something like TOML, which is too difficult to parse because of its float support.
  • It should be possible to read the whole machine configuration from one single entry point, without hardcoding file location policy as e.g. systemd does with its unit files. File location policy can be achieved via strategic includes.
  • The syntax should be liberal, but must also be deterministic. For instance, file inclusion must fail, not succeed, when the included file is missing.

Syntax

The exact syntax of the service files has not been decided upon for now; it will be worked on when the s6-rc project is finished and s6-frontend is underway.