aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-01-11 02:54:05 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-01-11 02:54:05 +0000
commit5876e2f9e260ef46330edfa6f258c6d88b7e5d50 (patch)
tree4e56a24bdbcfd9bf9bc39cbb1a4d6fc5fec74a74
parente135a92c11f1fe1e13c1c17df6616bae56d215e8 (diff)
downloads6-frontend-5876e2f9e260ef46330edfa6f258c6d88b7e5d50.tar.gz
Add repository_check; add basic documentation
-rw-r--r--NEWS2
-rw-r--r--README14
-rw-r--r--doc/index.html76
-rw-r--r--doc/quickstart.html26
-rw-r--r--doc/s6-frontend-helper-kill.html54
-rw-r--r--doc/s6-frontend.conf.html125
-rw-r--r--doc/s6-frontend.html101
-rw-r--r--doc/s6.html281
-rw-r--r--package/deps.mak3
-rw-r--r--package/targets.mak2
-rw-r--r--src/s6-frontend/deps-exe/s6-frontend1
-rw-r--r--src/s6-frontend/repository.help.txt9
-rw-r--r--src/s6-frontend/repository_check.c53
-rw-r--r--src/s6-frontend/s6-frontend-internal.h2
-rw-r--r--src/s6-frontend/s6.c6
15 files changed, 682 insertions, 73 deletions
diff --git a/NEWS b/NEWS
index b662d60..0dc423a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Changelog for s6-frontend
+Changelog for s6-frontend.
In 0.0.1.0
----------
diff --git a/README b/README
index dba8078..60788e0 100644
--- a/README
+++ b/README
@@ -1,16 +1,10 @@
s6-frontend - a s6-based init system with a friendly UI
-------------------------------------------------------
-!
-! s6-frontend is IN DEVELOPMENT, do not expect anything
-! magical from it for some time!
-!
-
- s6-frontend is a set of programs providing interfaces
-to the s6 family of programs (s6, s6-rc, s6-linux-init)
-for users who are used to different systems. It also
-comes with a full set of init scripts and can be used as
-a turnkey init system.
+ s6-frontend provides the one-stop-shop "s6" command that
+serves as a friendlier user interface to the s6 family of
+programs (s6, s6-rc, s6-linux-init), hiding policy details
+and providing a unified view of the init system.
See https://skarnet.org/software/s6-frontend/ for details.
diff --git a/doc/index.html b/doc/index.html
index 70ca515..d7d20b3 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -20,45 +20,58 @@
<h2> What is it&nbsp;? </h2>
<p>
- <strong><em><red> s6-frontend is still in development. </red></em></strong>
+ s6-frontend is a frontend to the s6 init system. It provides
+the one-stop-shop <a href="s6.html">s6</a> command, that is used
+to address every part of the init system.
</p>
+<h3> Huh? </h3>
+
<p>
- s6-frontend is a frontend to the s6 ecosystem. It is made of
-several parts:
+ The <em>s6 init system</em> is made of several different parts:
</p>
<ul>
- <li> A set of user-friendly commands, making it easier to manage a
-s6-based system for people who are used to other tools. </li>
- <li> An independent configuration file format,
-and tools that automatically analyze a configuration written in that
-format and transform it into a configuration suitable for booting a
-system via
-<a href="//skarnet.org/software/s6/">s6</a>,
-<a href="//skarnet.org/software/s6-linux-init/">s6-linux-init</a> and
-<a href="//skarnet.org/software/s6-rc/">s6-rc</a>. This should help
-users who are not familiar with s6 and s6-rc directory-based configuration
-but are used to, for instance, systemd unit files.</li>
- <li> A prepackaged set of configuration files, implementing <em>policy</em>,
-suitable for booting a large majority of Linux-based systems. This should
-help distributions that want to switch to s6 but do not want to rewrite all
-their init scripts in yet another format. </li>
+ <li> The <a href="//skarnet.org/software/s6/">s6 process supervision suite</a>,
+which is the foundation of the s6 ecosystem. This package is named <em>s6</em>,
+but that name is generally used to mean "the whole thing", so we will refer to it
+as <em>s6-supervision</em> when the context makes it necessary. The goal of a
+process supervision suite is to give administrators an environment to start and
+control daemons in a reliable and flexible way. </li>
+ <li> The <a href="//skarnet.org/software/s6-rc/">s6-rc service manager</a>, that
+works on top of s6-supervision. The goal of a service manager is to start and stop
+services on a system while managing dependencies between services. </li>
+ <li> The <a href="//skarnet.org/software/s6-linux-init">s6-linux-init init package</a>,
+which is an add-on to s6-supervision that makes it usable not only to supervise
+daemons, but also to boot a Linux system and serve as its pid 1. </li>
</ul>
<p>
- These parts are all independent from one another. But when put all together,
-they implement a powerful, fast, turnkey init system that is usable on
-<em>any</em> distribution.
+ The separation in different packages is purposeful: the goal is to keep the
+system entirely modular, and not tie it to a particular use. s6-supervision
+is often used on its own, in environments that already have an init system
+(no need for s6-linux-init) and a service manager (no need for s6-rc).
+For the same purpose of modularity, s6 follows an approach of "one functionality,
+one tool", sometimes to the extreme: the s6-supervision package, as of
+2.14.0.0, hosts 75 binaries.
</p>
-<hr />
+<p>
+ This approach is successful in that it provides comprehensive functionality
+with maximum efficiency: despite its growth, s6 remains extremely
+<em>lightweight</em> in run-time resource usage. However, a recurring
+pattern is that potential users are often rebuked by s6's apparent complexity.
+</p>
-<ul>
- <li> <a href="quickstart.html">Quickstart and FAQ</a> </li>
-</ul>
+<p>
+ s6-frontend is an attempt at managing users' interface expectations. It
+provides <em>one</em> user-facing command, named <strong>s6</strong>, that
+takes intuitively-named subcommands in order to control all the important
+parts of an s6-based system.
+</p>
<hr />
+
<h2> Installation </h2>
<h3> Requirements </h3>
@@ -131,14 +144,17 @@ the previous versions of s6-frontend and the current one. </li>
<h2> Reference </h2>
-<h3> Commands </h3>
+<h3> User-facing commands </h3>
-<p>
- All these commands exit 111 if they encounter a temporary error, and
-100 if they encounter a permanent error - such as a misuse.
-</p>
+<ul>
+<li> <a href="s6.html">The <tt>s6</tt> program</a> </li>
+</ul>
+
+<h3> Internal programs </h3>
<ul>
+<li> <a href="s6-frontend.html">The <tt>s6-frontend</tt> program</a> </li>
+<li> <a href="s6-frontend-helper-kill.html">The <tt>s6-frontend-helper-kill</tt> program</a> </li>
</ul>
<h2> Related resources </h2>
diff --git a/doc/quickstart.html b/doc/quickstart.html
deleted file mode 100644
index 6c99510..0000000
--- a/doc/quickstart.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Language" content="en" />
- <title>s6-frontend: quickstart and FAQ</title>
- <meta name="Description" content="s6-frontend: quickstart and FAQ" />
- <meta name="Keywords" content="s6-frontend installation quickstart faq" />
- <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
- </head>
-<body>
-
-<p>
-<a href="index.html">s6-frontend</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> Quickstart and FAQ for s6-frontend </h1>
-
-<p>
- (To be written.)
-</p>
-
-</body>
-</html>
diff --git a/doc/s6-frontend-helper-kill.html b/doc/s6-frontend-helper-kill.html
new file mode 100644
index 0000000..6c5d2b8
--- /dev/null
+++ b/doc/s6-frontend-helper-kill.html
@@ -0,0 +1,54 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-frontend: the s6-frontend-helper-kill program</title>
+ <meta name="Description" content="s6-frontend: the s6-frontend-helper-kill program" />
+ <meta name="Keywords" content="s6 s6-frontend helper kill" />
+ <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-frontend</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-frontend-helper-kill</tt> internal program </h1>
+
+<p>
+ <tt>s6-frontend-helper-kill</tt> is a small utility to send numerical
+signals to a given list of pids. It is not meant to be called directly,
+although nothing bad will happen if you do. It is used in command lines crafted by
+<a href="s6_process_kill.html">s6 process kill</a> instead of the POSIX
+<a href="https://pubs.opengroup.org/onlinepubs/9799919799/utilities/kill.html">kill</a>
+program, because the latter does not support sending arbitrary numerical signals.
+</p>
+
+<div id="interface">
+<h2> Interface </h2>
+</div>
+
+<pre>
+ s6-frontend-helper-kill <em>sig</em> <em>pids...</em>
+</pre>
+
+<ul>
+ <li> s6-frontend-helper-kill reads an integer, <em>sig</em>, and a list
+of one or more integers, <em>pids...</em>, on its command line. </li>
+ <li> It sends signal number <em>sig</em> to all the processes listed as <em>pids...</em>. </li>
+</ul>
+
+<div id="exitcodes">
+<h2> Exit codes </h2>
+</div>
+
+<dl>
+ <dt> 0 </dt> <dd> Success </dd>
+ <dt> 100 </dt> <dd> Wrong usage </dd>
+</dl>
+
+</body>
+</html>
diff --git a/doc/s6-frontend.conf.html b/doc/s6-frontend.conf.html
new file mode 100644
index 0000000..9a83e2d
--- /dev/null
+++ b/doc/s6-frontend.conf.html
@@ -0,0 +1,125 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-frontend: the s6-frontend.conf configuration file</title>
+ <meta name="Description" content="s6-frontend: the s6-frontend.conf configuration file" />
+ <meta name="Keywords" content="s6-frontend.conf s6-frontend configuration file execline variable" />
+ <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-frontend</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>/etc/s6-frontend.conf</tt> configuration file </h1>
+
+<div id="goal">
+<h2> Goal and usage </h2>
+</div>
+
+<p>
+ <tt>/etc/s6-frontend.conf</tt> is a configuration file provided by the
+distribution, or written by the system administrator, defining various
+settings for the <a href="s6.html">s6</a> commands, as well as the default
+policies of an s6-based system (i.e. where various directories and files
+are located).
+</p>
+
+<p>
+ This is, for instance, what allows the
+<a href="s6_process_restart">s6 process restart foobar</a> command to send
+<a href="//skarnet.org/software/s6/s6-svc.html">s6-svc -r</a> to the
+<em>foobar</em> service without the user needing to type, or even remember,
+what the full path to the <em>foobar</em> service directory is.
+</p>
+
+<div id="description">
+<h2> Description </h2>
+</div>
+
+<p>
+The <tt>/etc/s6-frontend.conf</tt> file follows the syntax of the
+<a href="//skarnet.org/software/execline/envfile.html">envfile</a> command:
+simple <code>key = value</code> lines, comments permitted.
+</p>
+
+<p>
+ If a value is left empty, the compiled-in default is used.
+</p>
+
+<p>
+ The variables that can be set are the following:
+</p>
+
+<table>
+<tr> <th>Name</th> <th>Contents</th> <th>Default</th> </tr>
+
+<tr>
+ <td> scandir </td>
+ <td> The directory where <a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>
+is running. </td>
+ <td> <tt>/run/service</tt> (possibly overridden by the <tt>--scandir</tt> build-time configure option to
+<a href="//skarnet.org/software/s6-linux-init/"></a> or to
+<a href="//skarnet.org/software/s6-frontend/">s6-frontend</a>) </td>
+</tr>
+
+<tr>
+ <td> livedir </td>
+ <td> The directory hosting the live service database managed by
+<a href="//skarnet.org/software/s6-rc/s6-rc.html">s6-rc</a> </td>
+ <td> <tt>/run/s6-rc</tt> (possibly overridden by the <tt>--livedir</tt> build-time configure option to
+<a href="//skarnet.org/software/s6-rc/"></a> or to
+<a href="//skarnet.org/software/s6-frontend/">s6-frontend</a>) </td>
+</tr>
+
+<tr>
+ <td> repodir </td>
+ <td> The directory hosting the repository of service sets managed by the
+<a href="//skarnet.org/software/s6-rc/repodefs.html">s6-rc <em>repo</em> commands</a> </td>
+ <td> <tt>/var/lib/s6-rc/repository</tt> (possibly overridden by the <tt>--repodir</tt> build-time configure option to
+<a href="//skarnet.org/software/s6-rc/"></a> or to
+<a href="//skarnet.org/software/s6-frontend/">s6-frontend</a>) </td>
+</tr>
+
+<tr>
+ <td> bootdb </td>
+ <td> The path to the boot-time compiled service database </td>
+ <td> <tt>/etc/s6-rc/compiled/current</tt> (possibly overridden by the <tt>--bootdb</tt> build-time configure option to
+<a href="//skarnet.org/software/s6-rc/"></a> or to
+<a href="//skarnet.org/software/s6-frontend/">s6-frontend</a>) </td>
+</tr>
+
+<tr>
+ <td> stmpdir </td>
+ <td> A directory suitable for root-only runtime data and temporary files for s6-frontend </td>
+ <td> <tt>/run/s6-frontend</tt> (possibly overridden by the <tt>--stmpdir</tt> build-time configure option to
+<a href="//skarnet.org/software/s6-frontend/">s6-frontend</a>) </td>
+</tr>
+
+<tr>
+ <td> storelist </td>
+ <td> A colon-separated (<tt>:</tt>) list of directories containing the
+<a href="//skarnet.org/software/s6-rc/repodefs.html#store">stores</a> of s6-rc service
+definition directories </td>
+ <td> <tt>/usr/share/s6-frontend/s6-rc/sources:/etc/s6-frontend/s6-rc/sources</tt>
+(possibly overridden by the <tt>--storelist</tt> build-time configure option to
+<a href="//skarnet.org/software/s6-frontend/">s6-frontend</a>) </td>
+</tr>
+
+<tr>
+ <td> verbosity </td>
+ <td> The default verbosity for <a href="s6.html">s6</a> and its invoked commands. 0 is
+terse (only print fatal error messages), 1 is normal (print error messages and warnings),
+over 1 is increasingly verbose (print informational messages, up to tracing and debug
+messages at level 4-5) </td>
+ <td> <strong>1</strong> </td>
+</tr>
+</table>
+
+</body>
+</html>
diff --git a/doc/s6-frontend.html b/doc/s6-frontend.html
new file mode 100644
index 0000000..0f7ff22
--- /dev/null
+++ b/doc/s6-frontend.html
@@ -0,0 +1,101 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-frontend: the s6-frontend program</title>
+ <meta name="Description" content="s6-frontend: the s6-frontend program" />
+ <meta name="Keywords" content="s6-frontend s6 frontend ecosystem interface" />
+ <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-frontend</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-frontend</tt> internal program </h1>
+
+<p>
+ <tt>s6-frontend</tt> is the program that does the real command dispatching behind
+the <a href="s6.html">s6</a> command line. It is not meant to be called directly;
+users should call <a href="s6.html">s6</a> instead.
+</p>
+
+<div id="interface">
+<h2> Interface </h2>
+</div>
+
+<pre>
+ s6-frontend [ <em>global_options...</em> ] <em>commandM/em> <em>subcommand</em> [ <em>subcommand_options...</em> ] [ <em>args...</em> ]
+</pre>
+
+<div id="details">
+<h2> Detailed operation </h2>
+</div>
+
+<p>
+ What really happens when you call <code>s6 <em>args...</em></code> is the following:
+</p>
+
+<ul>
+ <li> <a href="s6.html">s6</a> gets the name of its configuration file from the
+<tt>S6_FRONTEND_CONF</tt> environment variable, or from the compiled-in default if
+this variable is unset. Normally this default is <tt>/etc/s6-frontend.conf</tt>. </li>
+ <li> This configuration file (let's call it <em>conf</em>) contains
+<a href="s6-frontend.conf.html">variable definitions</a> that set the default for
+all the parts of the s6 system. </li>
+ <li> <a href="s6.html">s6</a> rewrites itself into
+<code>envfile -I <em>conf</em> -- s6-frontend <em>args...</em></code> </li>
+ <li> The <a href="//skarnet.org/software/execline/envfile.html">envfile</a> program
+reads and parses <em>conf</em>, and then runs <a href="s6-frontend.html">s6-frontend</a>
+with the additional environment variables defined in <em>conf</em>.
+ <li> s6-frontend sets its defaults according to these environment variables, then
+performs the work described in the documents linked from the <a href="s6.html">s6</a> page. </li>
+</ul>
+
+<p>
+ The separation between <a href="s6.html">s6</a> and s6-frontend is really just a
+trick to avoid writing an additional parser for the <a href="s6-frontend.conf.html">s6-frontend.conf</a>
+configuration file. The <a href="//skarnet.org/software/execline/">execline</a>
+set of tools is a dependency of s6-frontend anyway, because s6-frontend uses
+some if these tools to build complex command lines calling various parts of the
+s6 ecosystem; so using the
+<a href="//skarnet.org/software/execline/envfile.html">envfile</a> tool as well
+to read the configuration was a natural fit.
+</p>
+
+<p>
+ That is why <em>usage</em> messages given by the various <code>s6 foobar help</code>
+commands print <code>Usage: s6 foobar subcommand...</code> but error messages, if
+they happen, print <code>s6-frontend: fatal: error condition</code>, because
+the program where the error occurred is s6-frontend, not s6. </p>
+
+<p>
+Note that most error messages will print the name of <em>another command</em>,
+somewhere in the s6 ecosystem. That is a command invoked by s6-frontend to perform
+the task required by the user; and if it fails, its own error message will be more
+informative than whatever wrapping s6-frontend could do. This might be a little
+confusing at first, but a design decision was made that it was a better trade-off
+to provide accurate error messages at the expense of a little predictability in the
+name of the program that prepends the error messages.
+</p>
+
+<p>
+ In summary:
+</p>
+
+<ul>
+ <li> <a href="s6.html">s6</a> is what the user types </li>
+ <li> s6-frontend is what interprets the user's command into orders to give to
+various parts of the s6 ecosystem </li>
+ <li> Various programs from the <a href="//skarnet.org/software/s6/">s6 supervision
+suite</a> or the <a href="//skarnet.org/software/s6-rc/">s6-rc service manager</a>,
+invoked by s6-frontend, perform the work. When they succeed, it is transparent;
+when they fail, they prepend the error message with their name. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6.html b/doc/s6.html
new file mode 100644
index 0000000..8f1012f
--- /dev/null
+++ b/doc/s6.html
@@ -0,0 +1,281 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-frontend: the s6 program</title>
+ <meta name="Description" content="s6-frontend: the s6 program" />
+ <meta name="Keywords" content="s6 ecosystem supervision service manager user interface init skarnet.org skarnet software" />
+ <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-frontend</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6</tt> program </h1>
+
+<p>
+ <tt>s6</tt> is a generic command-line utility that can be used to
+interact with a system managed by the
+<a href="//skarnet.org/software/s6/">s6 process supervision system</a>, the
+<a href="//skarnet.org/software/s6-rc/">s6-rc service manager</a>, and optionally the
+<a href="//skarnet.org/software/s6-linux-init/">s6-linux-init boot program</a>.
+</p>
+
+<div id="interface">
+<h2> Interface </h2>
+</div>
+
+<pre>
+ s6 [ <em>global_options...</em> ] <em>command</em> <em>subcommand</em> [ <em>subcommand_options...</em> ] [ <em>args...</em> ]
+</pre>
+
+<ul>
+ <li> s6 reads its configuration file. </li>
+ <li> It reads from the command line, in this order: global options,
+a command, a subcommand, potentially subcommand options, and potentially
+arguments to the command and subcommand. </li>
+ <li> It performs various operations, typically invoking binaries from
+various parts of the s6 ecosystem, depending on the given command and
+subcommand. </li>
+</ul>
+
+<div id="commonusage">
+<h2> Common usage </h2>
+</div>
+
+<p>
+</p>
+
+<div id="exitcodes">
+<h2> Exit codes </h2>
+</div>
+
+<p>
+ s6 always exits 0 on success, 100 on bad usage, and 111 on a system call
+failure.
+</p>
+
+<p>
+ Since it can exec into a wide variety of commands belonging to various
+parts of the s6 family of programs, it is difficult to list all its possible
+exit codes exhaustively. However, in case of an error, the name of the
+subprogram where the error occurred is always printed on stderr; you can then
+consult the documentation for said subprogram, which will have the explanation
+for all its exit codes. For instance, if an invocation of <tt>s6</tt> prints
+a message such as <code>s6-rc: fatal: unable to start service foobar</code>,
+it means that s6 invoked the <a href="//skarnet.org/software/s6-rc/s6-rc.html">s6-rc</a>
+command, and on the linked documentation page, you can find the interpretation
+of its various exit codes.
+</p>
+
+<div id="environment">
+<h2> Environment variables </h2>
+</div>
+
+<ul>
+ <li> s6 reads the <code>S6_FRONTEND_CONF</code> environment variable. This
+variable contains the absolute path to the
+<a href="s6-frontend.conf.html">configuration file</a> for the s6 command. </li>
+ <li> If this variable is unset, the default is <tt>/etc/s6-frontend.conf</tt>
+possibly overridden by the <tt>--conffile</tt> build-time configure option to
+s6-frontend. </li>
+</ul>
+
+<div id="options">
+<h2> Global options </h2>
+</div>
+
+<p>
+ <em>global_options...</em> is a list of options that modify s6's behaviour
+and policies. They should generally not be used; instead, the behaviour should
+be set in the <a href="s6-frontend.conf.html">configuration file</a>.
+Nevertheless, if you need to override the configuration file settings for some
+reason, here you go.
+</p>
+
+<dl>
+ <dt> -h, --help </dt>
+ <dd> Run the <a href="#s6_help"><tt>s6 help</tt></aa> command.
+Any given command or subcommand is ignored. </dd>
+
+ <dt> -V, --version </dt>
+ <dd> Run the <a href="#s6_version"><tt>s6 version</tt></aa> command.
+ <dd> Any given command or subcommand is ignored. </dd>
+
+ <dt> -s <em>scandir</em>, --scandir=<em>scandir</em> </dt>
+ <dd> Use <em>scandir</em> as scan directory (i.e. the directory where
+<a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a> runs
+and supervises service directories),
+overriding the value of <em>scandir</em>
+defined in <a href="s6-frontend.conf.html">s6-frontend.conf</a>. </dd>
+
+ <dt> -l <em>livedir</em>, --livedir=<em>livedir</em> </dt>
+ <dd> Use <em>livedir</em> as live directory (i.e. the directory where
+<a href="//skarnet.org/software/s6-rc/s6-rc.html">s6-rc</a> keeps tabs
+on the machine state and stores its runtime information),
+and supervises service directories),
+overriding the value of <em>livedir</em>
+defined in <a href="s6-frontend.conf.html">s6-frontend.conf</a>. </dd>
+
+ <dt> -r <em>repodir</em>, --repodir=<em>repodir</em> </dt>
+ <dd> Use <em>repodir</em> as s6-rc repository (i.e. the directory where
+the <a href="//skarnet.org/software/s6-rc/repodefs.html">repo</a> commands
+of the <a href="//skarnet.org/software/s6-rc/">s6-rc</a> package store
+and manipulate their service sets),
+overriding the value of <em>repodir</em>
+defined in <a href="s6-frontend.conf.html">s6-frontend.conf</a>. </dd>
+
+ <dt> -c <em>bootdb</em>, --bootdb=<em>bootdb</em> </dt>
+ <dd> Use <em>bootdb</em> as the name of the compiled service database
+used by s6-rc at boot time (i.e. the directory where
+the <a href="//skarnet.org/software/s6-rc/s6-rc.html">s6-rc</a> reads
+information on how to start all the wanted services)
+overriding the value of <em>bootdb</em>
+defined in <a href="s6-frontend.conf.html">s6-frontend.conf</a>. </dd>
+
+ <dt> --stmpdir=<em>stmpdir</em> </dt>
+ <dd> Use <em>stmpdir</em> to store runtime s6-frontend data and
+temporary files,
+overriding the value of <em>stmpdir</em>
+defined in <a href="s6-frontend.conf.html">s6-frontend.conf</a>. </dd>
+
+ <dt> --storelist=<em>storelist</em> </dt>
+ <dd> Use <em>storelist</em> as list of
+<a href="//skarnet.org/software/s6-rc/repodefs.html#store">stores</a>,
+overriding the value of <em>storelist</em>
+defined in <a href="s6-frontend.conf.html">s6-frontend.conf</a>. </dd>
+
+ <dt> -v <em>verbosity</em>, --verbosity=<em>verbosity</em> </dt>
+ <dd> Use <em>verbosity</em> as numerical verbosity value,
+overriding the value of <em>verbosity</em>
+defined in <a href="s6-frontend.conf.html">s6-frontend.conf</a>. </dd>
+
+ <dt> --color=yes|no|auto </dt>
+ <dd> Use fancy output (which may or may not involve color): always if
+<tt>yes</tt>, never if <tt>no</tt>, and only when stdout is a terminal
+if <tt>auto</tt>. Not all commands and subcommands will use this
+setting. Also, for pretty-printing of columns, it is recommended to
+have built s6-frontend with util-linux support. </dd>
+</dl>
+
+
+<div id="commands">
+<h2> Commands </h2>
+</div>
+
+<div id="s6_help">
+<h3> help </h3>
+</div>
+
+<p>
+ <tt>s6 help</tt> prints a short help message summarizing the options
+and usage of the s6 command. It is not as detailed as this page.
+</p>
+
+<p>
+ No subcommands are defined.
+</p>
+
+<div id="s6_version">
+<h3> version </h3>
+</div>
+
+<p>
+ <tt>s6 version</tt> prints the current version of s6-frontend, on one line.
+</p>
+
+<p>
+ No subcommands are defined.
+</p>
+
+<div id="s6_process">
+<h3> process </h3>
+</div>
+
+<p>
+ <tt>s6 process</tt> sends commands to long-running processes supervised by the
+<a href="//skarnet.org/software/s6/">s6 supervision suite</a>. The details are
+available <a href="s6_process.html">here</a>.
+</p>
+
+<p>
+ <a href="s6_process.html"><tt>s6 process</tt></a> is typically used when a daemon
+needs to be restarted or otherwise addressed without involvement from the service
+manager, i.e. without having to start or stop dependencies.
+</p>
+
+<div id="s6_live">
+<h3> live </h3>
+</div>
+
+<p>
+ <tt>s6 live</tt> controls the live state of the machine, starting and stopping
+services, installing a new set of services, etc. It is mostly an interface
+around the
+<a href="//skarnet.org/software/s6-rc/">s6-rc service manager</a>. The details are
+available <a href="s6_live.html">here</a>.
+</p>
+
+<div id="s6_repository">
+<h3> repository </h3>
+</div>
+
+<p>
+ <tt>s6 repository</tt> regroups administrative tasks related to the repository
+of service sets, typically synchronization with the service stores when the
+package manager updates service definitions. It is not often directly used by
+sysadmins, but is an essential part of distribution scripts, when they create
+the initial layout, run their package manager, etc.
+</p>
+
+<p>
+The details are available <a href="s6_repository.html">here</a>.
+</p>
+
+<div id="s6_set">
+<h3> set </h3>
+</div>
+
+<p>
+ <tt>s6 set</tt> is the interface to the creation and manipulation of service sets by
+the user. It is how they define what service will be enabled or disabled at boot
+time. This manipulation occurs <em>offline</em>: service sets being worked on are distinct from
+the live state of the machine, accessible via <a href="#s6_live"><tt>s6 live</tt></a> commands.
+
+<p>
+The details are available <a href="s6_set.html">here</a>.
+</p>
+
+<div id="s6_system">
+<h3> system </h3>
+</div>
+
+<p>
+ <tt>s6 system</tt> provides commands to run at boot and, on systems fully managed by s6,
+to shut the system down.
+The details are available <a href="s6_system.html">here</a>.
+</p>
+
+<div id="notes">
+<h2> Notes </h2>
+</div>
+
+<ul>
+ <li> <tt>s6</tt> does not perform real operations itself. Instead, after
+finding the path to its <a href="s6-frontend.conf.html">configuration file</a>
+<em>conf</em>, it rewrites itself into <code>envfile -I <em>conf</em></code> -- s6-frontend
+<em>global_options...</em> <em>command</em> <em>subcommand</em> <em>subcommand_options...</em> <em>args...</em></code>
+ <ul>
+ <li> <a href="//skarnet.org/software/execline/envfile.html">envfile</a> reads and parses <em>conf</em> </li>
+ <li> <a href="s6-frontend.html">s6-frontend</a> is the binary that does the real work of
+parsing options, command, subcommand, etc. and dispatching orders. </li>
+ </ul>
+</ul>
+
+</body>
+</html>
diff --git a/package/deps.mak b/package/deps.mak
index 3293ada..a715f1c 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -22,6 +22,7 @@ src/s6-frontend/process_restart.o src/s6-frontend/process_restart.lo: src/s6-fro
src/s6-frontend/process_startstop.o src/s6-frontend/process_startstop.lo: src/s6-frontend/process_startstop.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/process_status.o src/s6-frontend/process_status.lo: src/s6-frontend/process_status.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/repository.o src/s6-frontend/repository.lo: src/s6-frontend/repository.c src/s6-frontend/s6-frontend-internal.h
+src/s6-frontend/repository_check.o src/s6-frontend/repository_check.lo: src/s6-frontend/repository_check.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
src/s6-frontend/repository_init.o src/s6-frontend/repository_init.lo: src/s6-frontend/repository_init.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h
src/s6-frontend/repository_list.o src/s6-frontend/repository_list.lo: src/s6-frontend/repository_list.c src/s6-frontend/s6-frontend-internal.h
src/s6-frontend/repository_sync.o src/s6-frontend/repository_sync.lo: src/s6-frontend/repository_sync.c src/s6-frontend/s6-frontend-internal.h
@@ -48,5 +49,5 @@ endif
s6: EXTRA_LIBS :=
s6: src/s6-frontend/s6.o -lskarnet
s6-frontend: EXTRA_LIBS := ${MAYBEPTHREAD_LIB}
-s6-frontend: src/s6-frontend/s6-frontend.o src/s6-frontend/live.o src/s6-frontend/live_help.o src/s6-frontend/live_install.o src/s6-frontend/live_startstop.o src/s6-frontend/live_status.o src/s6-frontend/live_start_everything.o src/s6-frontend/live_stop_everything.o src/s6-frontend/main_help.o src/s6-frontend/main_version.o src/s6-frontend/process.o src/s6-frontend/process_help.o src/s6-frontend/process_kill.o src/s6-frontend/process_restart.o src/s6-frontend/process_startstop.o src/s6-frontend/process_status.o src/s6-frontend/repository.o src/s6-frontend/repository_help.o src/s6-frontend/repository_init.o src/s6-frontend/repository_list.o src/s6-frontend/repository_sync.o src/s6-frontend/set.o src/s6-frontend/set_change.o src/s6-frontend/set_check.o src/s6-frontend/set_commit.o src/s6-frontend/set_copy.o src/s6-frontend/set_help.o src/s6-frontend/set_list.o src/s6-frontend/set_status.o src/s6-frontend/system.o src/s6-frontend/system_boot.o src/s6-frontend/system_help.o src/s6-frontend/system_hpr.o libs6f.a.xyzzy ${LIBNSSS} -ls6rc -ls6 -lskarnet
+s6-frontend: src/s6-frontend/s6-frontend.o src/s6-frontend/live.o src/s6-frontend/live_help.o src/s6-frontend/live_install.o src/s6-frontend/live_startstop.o src/s6-frontend/live_status.o src/s6-frontend/live_start_everything.o src/s6-frontend/live_stop_everything.o src/s6-frontend/main_help.o src/s6-frontend/main_version.o src/s6-frontend/process.o src/s6-frontend/process_help.o src/s6-frontend/process_kill.o src/s6-frontend/process_restart.o src/s6-frontend/process_startstop.o src/s6-frontend/process_status.o src/s6-frontend/repository.o src/s6-frontend/repository_check.o src/s6-frontend/repository_help.o src/s6-frontend/repository_init.o src/s6-frontend/repository_list.o src/s6-frontend/repository_sync.o src/s6-frontend/set.o src/s6-frontend/set_change.o src/s6-frontend/set_check.o src/s6-frontend/set_commit.o src/s6-frontend/set_copy.o src/s6-frontend/set_help.o src/s6-frontend/set_list.o src/s6-frontend/set_status.o src/s6-frontend/system.o src/s6-frontend/system_boot.o src/s6-frontend/system_help.o src/s6-frontend/system_hpr.o libs6f.a.xyzzy ${LIBNSSS} -ls6rc -ls6 -lskarnet
INTERNAL_LIBS := libs6f.a.xyzzy
diff --git a/package/targets.mak b/package/targets.mak
index 8b2a86a..bc266f5 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -1,8 +1,8 @@
BIN_TARGETS := \
s6 \
-s6-frontend
LIBEXEC_TARGETS := \
+s6-frontend \
s6-frontend-helper-kill \
EXTRA_TARGETS := \
diff --git a/src/s6-frontend/deps-exe/s6-frontend b/src/s6-frontend/deps-exe/s6-frontend
index 14038f5..9f08747 100644
--- a/src/s6-frontend/deps-exe/s6-frontend
+++ b/src/s6-frontend/deps-exe/s6-frontend
@@ -14,6 +14,7 @@ process_restart.o
process_startstop.o
process_status.o
repository.o
+repository_check.o
repository_help.o
repository_init.o
repository_list.o
diff --git a/src/s6-frontend/repository.help.txt b/src/s6-frontend/repository.help.txt
index 7a07296..3a9ee1e 100644
--- a/src/s6-frontend/repository.help.txt
+++ b/src/s6-frontend/repository.help.txt
@@ -5,6 +5,8 @@ Subcommands:
init initialize a service repository
sync synchronize repository with stores
list list names of saved service sets
+ check check all sets and fix inconsistencies
+
s6 repository init options:
-f --force Overwrite existing repository
@@ -16,3 +18,10 @@ s6 repository sync options:
s6 repository list options: none
+s6 repository check options:
+ -E --no-force-essential do not allow manual changes to essential services (default)
+ -e --force-essential allow manual changes to essential services
+ -f --fix try to fix inconsistencies automatically
+ -d --down fix by disabling or masking services if necessary (default)
+ -u --up fix by enabling services if necessary
+
diff --git a/src/s6-frontend/repository_check.c b/src/s6-frontend/repository_check.c
new file mode 100644
index 0000000..a0e7737
--- /dev/null
+++ b/src/s6-frontend/repository_check.c
@@ -0,0 +1,53 @@
+/* ISC license. */
+
+#include <skalibs/uint64.h>
+#include <skalibs/types.h>
+#include <skalibs/envexec.h>
+
+#include <execline/config.h>
+
+#include <s6-rc/config.h>
+
+#include <s6-frontend/config.h>
+#include "s6-frontend-internal.h"
+
+enum golb_e
+{
+ GOLB_FIXUP = 0x01,
+ GOLB_FORCE_ESSENTIAL = 0x02,
+ GOLB_FIX = 0x04,
+} ;
+
+void repository_check (char const *const *argv)
+{
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'E', .lo = "no-force-essential", .clear = GOLB_FORCE_ESSENTIAL, .set = 0 },
+ { .so = 'e', .lo = "force-essential", .clear = 0, .set = GOLB_FORCE_ESSENTIAL },
+ { .so = 'd', .lo = "down", .clear = GOLB_FIXUP, .set = 0 },
+ { .so = 'u', .lo = "up", .clear = 0, .set = GOLB_FIXUP },
+ { .so = 'f', .lo = "fix", .clear = 0, .set = GOLB_FIX },
+ } ;
+ uint64_t wgolb = 0 ;
+ unsigned int m = 0 ;
+ char const *newargv[9] ;
+ char fmtv[UINT_FMT] = " " ;
+
+ argv += gol_argv(argv, rgolb, 4, 0, 0, &wgolb, 0) ;
+
+ newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-fix" ;
+ if (g->verbosity != 1)
+ {
+ fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
+ newargv[m++] = "-v" ;
+ newargv[m++] = fmtv ;
+ }
+ newargv[m++] = "-r" ;
+ newargv[m++] = g->dirs.repo ;
+ newargv[m++] = wgolb & GOLB_FORCE_ESSENTIAL ? "--force-essential" : "--no-force-essential" ;
+ newargv[m++] = wgolb & GOLB_FIXUP ? "--fix-up" : "--fix-down" ;
+ if (!(wgolb & GOLB_FIX)) newargv[m++] = "--dry-run" ;
+ newargv[m++] = 0 ;
+
+ xmexec_n(newargv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ;
+}
diff --git a/src/s6-frontend/s6-frontend-internal.h b/src/s6-frontend/s6-frontend-internal.h
index ddd3b69..fdacb2b 100644
--- a/src/s6-frontend/s6-frontend-internal.h
+++ b/src/s6-frontend/s6-frontend-internal.h
@@ -61,6 +61,8 @@ extern void repository_init (char const *const *) gccattr_noreturn ;
extern void repository_sync (char const *const *) gccattr_noreturn ;
extern void repository_list (char const *const *) gccattr_noreturn ;
+extern void repository_check (char const *const *) gccattr_noreturn ;
+
/* set */
diff --git a/src/s6-frontend/s6.c b/src/s6-frontend/s6.c
index f19fd56..8777b8d 100644
--- a/src/s6-frontend/s6.c
+++ b/src/s6-frontend/s6.c
@@ -2,9 +2,7 @@
#include <stdlib.h>
-#include <skalibs/prog.h>
-#include <skalibs/strerr.h>
-#include <skalibs/exec.h>
+#include <skalibs/envexec.h>
#include <execline/config.h>
@@ -24,7 +22,7 @@ int main (int argc, char const *const *argv)
newargv[m++] = "-I" ;
newargv[m++] = "--" ;
newargv[m++] = conffile ;
- newargv[m++] = S6_FRONTEND_BINPREFIX "s6-frontend" ;
+ newargv[m++] = S6_FRONTEND_LIBEXECPREFIX "s6-frontend" ;
while (argc--) newargv[m++] = *argv++ ;
newargv[m++] = 0 ;
xexec(newargv) ;