make s6-init-files into a module

This commit is contained in:
Daniel Barlow 2022-09-27 10:19:44 +01:00
parent 85f7f7293d
commit 797aa30c47
10 changed files with 161 additions and 172 deletions

158
modules/s6/default.nix Normal file
View file

@ -0,0 +1,158 @@
{ config, pkgs, ... }:
let
inherit (pkgs)
busybox
execline
s6
s6-init-bin
s6-linux-init
stdenvNoCC;
inherit (pkgs.pseudofile) dir symlink;
s6-rc-db = pkgs.s6-rc-database.override {
services = builtins.attrValues config.services;
};
s6-init-scripts = stdenvNoCC.mkDerivation {
name = "s6-scripts";
src = ./scripts;
phases = ["unpackPhase" "installPhase" ];
buildInputs = [busybox];
installPhase = ''
mkdir $out
cp -r $src $out/scripts
chmod -R +w $out
patchShebangs $out/scripts
'';
};
service = dir {
s6-linux-init-runleveld = dir {
notification-fd = { file = "3"; };
run = {
file = ''
#!${execline}/bin/execlineb -P
${execline}/bin/fdmove -c 2 1
${execline}/bin/fdmove 1 3
${s6}/bin/s6-ipcserver -1 -a 0700 -c 1 -- s
${s6}/bin/s6-sudod -dt30000 -- "/etc/s6-linux-init/current"/scripts/runlevel
'';
mode = "0755";
};
};
s6-linux-init-shutdownd = dir {
fifo = {
type = "i";
subtype = "f";
mode = "0600";
};
run = {
file = ''
#!${execline}/bin/execlineb -P
${s6-linux-init}/bin/s6-linux-init-shutdownd -c "/etc/s6-linux-init/current" -g 3000
'';
mode = "0755";
};
};
s6-svscan-log = dir {
fifo = {
type = "i";
subtype = "f";
mode = "0600";
};
notification-fd = { file = "3"; };
run = {
file = ''
#!${execline}/bin/execlineb -P
${execline}/bin/redirfd -w 1 /dev/null
${execline}/bin/redirfd -rnb 0 fifo
${s6}/bin/s6-log -bpd3 -- t /run/uncaught-logs
'';
mode = "0755";
};
};
getty = dir {
run = {
file = ''
#!${execline}/bin/execlineb -P
${busybox}/bin/getty -l ${busybox}/bin/login 38400 /dev/console
'';
mode = "0755";
};
};
".s6-svscan" =
let
quit = message: ''
#!${execline}/bin/execlineb -P
${execline}/bin/redirfd -w 2 /dev/console
${execline}/bin/fdmove -c 1 2
${execline}/bin/foreground { ${s6-linux-init}/bin/s6-linux-init-echo -- ${message} }
${s6-linux-init}/bin/s6-linux-init-hpr -fr
'';
shutdown = action: ''
#!${execline}/bin/execlineb -P
${s6-linux-init}/bin/s6-linux-init-hpr -a #{action} -- now
'';
empty = "#!${execline}/bin/execlineb -P\n";
in dir {
crash = {
file = quit "s6-svscan crashed. Rebooting.";
mode = "0755";
};
finish = {
file = quit "s6-svscan exited. Rebooting.";
mode = "0755";
};
SIGINT = {
file = shutdown "-r";
mode = "0755";
};
SIGPWR = {
file = shutdown "-p";
mode = "0755";
};
SIGQUIT = {
file = empty;
mode = "0755";
};
SIGTERM = {
file = empty;
mode = "0755";
};
SIGUSR1 = {
file = shutdown "-p";
mode = "0755";
};
SIGUSR2 = {
file = shutdown "-h";
mode = "0755";
};
SIGWINCH = {
file = empty;
mode = "0755";
};
};
};
in {
config = {
environment = dir {
etc = dir {
s6-rc = dir {
compiled = symlink "${s6-rc-db}/compiled";
};
s6-linux-init = dir {
current = dir {
scripts = symlink "${s6-init-scripts}/scripts";
env = dir {};
run-image = dir {
uncaught-logs = (dir {}) // {mode = "2750";};
inherit service;
};
};
};
};
bin = dir {
init = symlink "${s6-init-bin}/bin/init";
};
};
};
}

45
modules/s6/scripts/rc.init Executable file
View file

@ -0,0 +1,45 @@
#!/usr/bin/env sh
rl="$1"
shift
### argv now contains the arguments of the kernel command line that are
### not of the form key=value. (The key=value arguments were stored by
### s6-linux-init into an envdir, if instructed so via the -s option.)
### Normally this argv remains unused because programs that need the
### kernel command line usually read it later on from /proc/cmdline -
### but just in case, it's available here.
### 1. Early preparation
### This is done only once at boot time.
### Ideally, this phase should just initialize the service manager.
mount -t proc none /proc
mount -t sysfs none /sys
### If your services are managed by s6-rc:
### (replace /run/service with your scandir)
s6-rc-init /run/service -d -c /etc/s6-rc/compiled
### 2. Starting the wanted set of services
### This is also called every time you change runlevels with telinit.
### (edit the location to suit your installation)
### By default, $rl is the string "default", unless you changed it
### via the -D option to s6-linux-init-maker.
### Numeric arguments from 1 to 5 on the kernel command line will
### override the default.
exec /etc/s6-linux-init/current/scripts/runlevel "$rl"
### If this script is run in a container, then 1. and 2. above do not
### apply and you should just call your CMD, if any, or let your
### services run.
### Something like this:
# if test -z "$*" ; then return 0 ; fi
# $@
# echo $? > /run/s6-linux-init-container-results/exitcode
# halt

19
modules/s6/scripts/rc.shutdown Executable file
View file

@ -0,0 +1,19 @@
#!/usr/bin/env sh
### Things to do before hardware halt/reboot/poweroff.
### Ideally, it should be a single call to the service manager,
### telling it to bring all the services down.
### If your s6-linux-init-maker invocation was made with the -1
### option, messages from rc.shutdown will appear on /dev/console
### as well as be logged by the catch-all logger.
### If your s6-linux-init-maker invocation did NOT include the -1
### option, messages from rc.shutdown will only be logged by the
### catch-all logger and will NOT appear on /dev/console. In order
### to print them to /dev/console instead, you may want to
### uncomment the following line:
exec >/dev/console 2>&1
### If your services are managed by s6-rc:
exec s6-rc -v2 -bDa change

View file

@ -0,0 +1,18 @@
#!/nix/store/xbdqbi2mscmhl5wcpbgpjdwxbsrvpkil-bash-5.1-p16/bin/sh -e
### Things to do *right before* the machine gets rebooted or
### powered off, at the very end of the shutdown sequence,
### when all the filesystems are unmounted.
### This is a last resort hook; normally nothing should be
### done here (your rc.shutdown script should have taken care
### of everything) and you should leave this script empty.
### Some distributions, however, may need to perform some
### actions after unmounting the filesystems: typically if
### an additional teardown action is required on a filesystem
### after unmounting it, or if the system needs to be
### pivot_rooted before it can be shut down, etc.
### Those are all exceptional cases. If you don't know for
### certain that you need to do something here, you don't.

12
modules/s6/scripts/runlevel Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env sh -e
### This script is called once at boot time by rc.init, and is
### also called by the runleveld service every time the user
### requests a machine state change via telinit.
### Ideally, it should just be a call to the service manager.
test "$#" -gt 0 || { echo 'runlevel: fatal: too few arguments' 1>&2 ; exit 100 ; }
### If your services are managed by s6-rc:
exec s6-rc -v2 -up change "$1"