commit da00d998b1fbceaa02e424e2610af8014f16ee07
parent 4dba9ca858fae896c3851ae9ae8ea740219f2944
Author: Jan Pobříslo <ccx@te2000.cz>
Date: Sat, 29 Oct 2022 03:11:40 +0200
rc-builder functions for stateful service definition (DRY)
Diffstat:
M | Makefile | | | 1 | + |
A | rc-builder.include.awk | | | 122 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | s6-rc.aat | | | 344 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
3 files changed, 284 insertions(+), 183 deletions(-)
diff --git a/Makefile b/Makefile
@@ -28,6 +28,7 @@ build/%.awk: %.aat common.aat
mv "$@.new" "$@"
build/s6-rc-mount.awk: s6-rc-mount.aat parse_fs.include.awk rc-common.aat
+build/s6-rc.awk: s6-rc.aat parse_fs.include.awk rc-common.aat rc-builder.include.awk
build/fstab.awk: fstab.aat parse_fs.include.awk rc-common.aat
s6-rc.fileset: build/s6-rc.qawk build/s6-rc-mount.awk fs build/config
diff --git a/rc-builder.include.awk b/rc-builder.include.awk
@@ -0,0 +1,122 @@
+function error(message) {
+ print "error: " message >"/dev/stderr"
+ exit 1
+}
+function start_service(svc_name, type) {
+ if(length(current_service_name)) {
+ error("start_service(\""svc_name"\", \""type"\", \""deps"\"): service \"" current_service_name "\" not terminated")
+ }
+ if(type !~ /^(oneshot|longrun)$/) {
+ error("start_service(\""svc_name"\", \""type"\", \""deps"\"): invalid service type")
+ }
+ current_service_name = svc_name
+ current_service_type = type
+}
+function start_oneshot(svc_name, deps) {
+ start_service(svc_name, "oneshot")
+ oneshot(svc_name, deps)
+}
+function start_longrun(svc_name, deps) {
+ start_service(svc_name, "longrun")
+ longrun(svc_name, deps)
+}
+function start_longrun_with_logger(svc_name, deps) {
+ start_service(svc_name, "longrun")
+ longrun_with_logger(svc_name, deps)
+}
+function in_bundle(name) {
+ if(!length(current_service_name)) {
+ error("in_bundle(\""name"\"): not in service context")
+ }
+ add_to_bundle(name, current_service_name)
+}
+function flush_current_file() {
+ if(length(current_file_mode)) {
+ print "m" current_file_mode
+ current_file_mode = ""
+ }
+}
+function end() {
+ if(!length(current_service_name)) {
+ error("end(): not in service context")
+ }
+ flush_current_file()
+ current_service_name = ""
+ current_service_type = ""
+}
+function file_line(name, content, mode) {
+ if(!length(current_service_name)) {
+ error("start_file(\""name"\", \""mode"\"): not in service context")
+ }
+ flush_current_file()
+ print "/" current_service_name "/" name "\tcN\t" content "\tm" mode
+}
+function start_file(name, mode) {
+ if(!length(current_service_name)) {
+ error("start_file(\""name"\", \""mode"\"): not in service context")
+ }
+ flush_current_file()
+ print "/" current_service_name "/" name
+ printf("CN")
+ current_file_mode=mode
+}
+function assert_service_type(type, caller_name) {
+ if(!length(current_service_name)) {
+ error("" caller_name ": not in service context")
+ }
+ if(current_service_type != type) {
+ error("" caller_name ": service is of type \"" current_service_type "\" expected \"" type "\"")
+ }
+}
+function up(){
+ assert_service_type("oneshot", "up()")
+ start_file("up", "644")
+}
+function down(){
+ assert_service_type("oneshot", "down()")
+ start_file("down", "644")
+}
+function notification_fd(fd){
+ if(fd !~ /^[0-9]+/ || fd < 3) {
+ error("notification_fd(\"" fd "\"): invalid filedescriptor number")
+ }
+ assert_service_type("longrun", "notification_fd("fd")")
+ file_line("notification-fd", fd, "644")
+}
+function consumer_for(name){
+ if(name ~ /[\t\n ]/) {
+ error("consumer_for(\"" name "\"): invalid service name")
+ }
+ assert_service_type("longrun", "consumer_for(\"" name "\")")
+ file_line("consumer-for", name, "644")
+}
+function producer_for(name){
+ if(name ~ /[\t\n ]/) {
+ error("producer_for(\"" name "\"): invalid service name")
+ }
+ assert_service_type("longrun", "producer_for(\"" name "\")")
+ file_line("producer-for", name, "644")
+}
+function run(){
+ assert_service_type("longrun", "run()")
+ start_file("run", "755")
+}
+function finish(){
+ assert_service_type("longrun", "finish()")
+ start_file("finish", "755")
+}
+function finish_el(){
+ finish()
+ print "\t#!/command/execlineb -P"
+}
+function run_arg(cmd){
+ assert_service_type("longrun", "run_arg(\"" cmd "\")")
+ flush_current_file()
+ runscript_simple(current_service_name, cmd)
+}
+function run_el(){
+ assert_service_type("longrun", "run_el()")
+ flush_current_file()
+ runscript_el_cgroup2(current_service_name)
+ current_file_mode = "755"
+}
diff --git a/s6-rc.aat b/s6-rc.aat
@@ -1,5 +1,6 @@
@include common.aat
@include rc-common.aat
+@awk rc-builder.include.awk
|END{
/ d m755
@@ -23,137 +24,137 @@ m644
|add_to_bundle("ok-mount", "ok-localmount")
|### Networking ###
-|add_to_bundle("net-all", "loopback")
-|oneshot("loopback")
-/loopback/up
-CN if { ip link set lo up }
+|start_oneshot("loopback")
+|in_bundle("net-all")
+|up()
+ if { ip link set lo up }
if -nt { ip addr add 127.0.0.1/8 dev lo brd + }
pipeline { ip addr show dev lo } grep -q "inet 127\\.0\\.0\\.1"
-m755
+|end()
@for i in static_ip
-|svc = oneshot(with_counter("net-" get("i.iface") "-ip"))
-|add_to_bundle("net-" get("i.iface"), svc)
+|start_oneshot(with_counter("net-" get("i.iface") "-ip"))
+|in_bundle("net-" get("i.iface"))
|add_to_bundle("net-all", "net-" get("i.iface"))
-/{{svc}}/up
-CN if { ip link set {<i.iface>} up }
+|up()
+ if { ip link set {<i.iface>} up }
if -nt { ip addr add {<i.ip>}/{<i.cidr>} dev {<i.iface>} }
pipeline { ip addr show dev {<i.iface>} } grep -F -q -e "inet {<i.ip>}/{<i.cidr>} "
-/{{svc}}/down
-CN ip addr del {<i.ip>} dev {<i.iface>}
-m755
+|down()
+ ip addr del {<i.ip>} dev {<i.iface>}
+|end()
@endfor
@for i in static_route
-|svc = oneshot(with_counter("net-" get("i.iface") "-route"), list_services_with_counter("net-" get("i.iface") "-ip"))
-|add_to_bundle("net-" get("i.iface"), svc)
-/{{svc}}/up
-CN if { ip link set {<i.iface>} up }
+|start_oneshot(with_counter("net-" get("i.iface") "-route"), list_services_with_counter("net-" get("i.iface") "-ip"))
+|in_bundle("net-" get("i.iface"))
+|up()
+ if { ip link set {<i.iface>} up }
if -nt { ip route add dev {<i.iface>} {<i.spec>} }
pipeline { ip route show dev {<i.iface>} {<i.spec>} } grep -q .
-/{{svc}}/down
-CN ip route del dev {<i.iface>} {<i.spec>}
-m755
+|down()
+ ip route del dev {<i.iface>} {<i.spec>}
+|end()
@endfor
-|add_to_bundle("net-all", "dhcpcd")
-|longrun_with_logger("dhcpcd", "modules ok-mount ok-sysinit")
-|runscript_simple("dhcpcd", "dhcpcd --nobackground")
+|start_longrun_with_logger("dhcpcd", "modules ok-mount ok-sysinit")
+|in_bundle("net-all")
+|run_arg("dhcpcd --nobackground")
+|end()
-|add_to_bundle("net-all", "unbound")
-|longrun_with_logger("unbound", "loopback ok-mount ok-sysinit")
-|runscript_simple("unbound", "unbound -ddp")
+|start_longrun_with_logger("unbound", "loopback ok-mount ok-sysinit")
+|in_bundle("net-all")
+|run_arg("unbound -ddp")
+|end()
-|add_to_bundle("ok-all-but-tty", "hostname")
-/hostname d m755
-/hostname/type cN oneshot m644
-/hostname/up cN hostname -F /etc/hostname m755
+|start_oneshot("hostname")
+|in_bundle("ok-all-but-tty")
+|up()
+ hostname -F /etc/hostname
+|end()
-|add_to_bundle("ok-all-but-tty", "loadkeys")
-/loadkeys d m755
-/loadkeys/dependencies cN kbd_mode m644
-/loadkeys/type cN oneshot m644
-/loadkeys/up cN loadkeys --unicode /root/keymap m644
+|start_oneshot("loadkeys", "kbd_mode")
+|in_bundle("ok-all-but-tty")
+|up()
+ loadkeys --unicode /root/keymap
+|end()
|### per-TTY services ###
|for(tty=1; tty<=(<getty_max>+0); tty++) {
-|add_to_bundle("gettys", "tty" tty)
-|longrun("tty" tty, "ok-sysinit")
-|runscript_el_cgroup2("tty" tty)
+|start_longrun("tty" tty, "ok-sysinit")
+|in_bundle("gettys")
+|run_el()
foreground { /command/issue-gen }
env LOGIN_TTY=/dev/tty{{tty}} /sbin/getty -l login-keepenv 38400 tty{{tty}} linux
-m755
-/tty{{tty}}/finish
-CN #!/command/execlineb -P
+|finish_el()
redirfd -w 1 /dev/tty{{tty}}
fdmove -c 2 1
foreground { s6-echo "\nwaiting for session cleanup" }
flock /run/ttylock/tty{{tty}} true
-m755
+|end()
|}
|for(tty=1; tty<=(<tty_max>+0); tty++) {
-|add_to_bundle("kbd_mode", "kbd_mode-tty" tty)
-/kbd_mode-tty{{tty}} d m755
-/kbd_mode-tty{{tty}}/type cN oneshot m644
-/kbd_mode-tty{{tty}}/up cN kbd_mode -u -C /dev/tty{{tty}} m644
+|start_oneshot("kbd_mode-tty" tty)
+|in_bundle("kbd_mode")
+|up()
+ kbd_mode -u -C /dev/tty{{tty}}
+|end()
|}
|if(get("tty_setfont")) {
|add_to_bundle("ok-all-but-tty", "setfont")
|for(tty=1; tty<=(<tty_max>+0); tty++) {
-|add_to_bundle("setfont", "setfont-tty" tty)
-/setfont-tty{{tty}} d m755
-/setfont-tty{{tty}}/type cN oneshot m644
-/setfont-tty{{tty}}/up cN redirfd -r 0 /dev/tty{{tty}} setfont {<tty_setfont>} m644
+|start_oneshot("setfont-tty" tty)
+|in_bundle("setfont")
+|up()
+ redirfd -r 0 /dev/tty{{tty}} setfont {<tty_setfont>}
+|end()
|}
|}
-|add_to_bundle("ok-all-but-tty", "dmesg")
-/dmesg d m755
-/dmesg/type cN oneshot m644
-/dmesg/up
-CN # description="Set the dmesg level for a cleaner boot"
+|start_oneshot("dmesg")
+|in_bundle("ok-all-but-tty")
+|up()
+ # description="Set the dmesg level for a cleaner boot"
# dmesg_level=1
dmesg -n1
-m755
+|end()
-|add_to_bundle("ok-all-but-tty", "modules")
-/modules d m755
-/modules/dependencies cN dmesg m644
-/modules/type cN oneshot m644
-/modules/up
-|printf "CN"
+|start_oneshot("modules", "dmesg")
+|in_bundle("ok-all-but-tty")
+|up()
@for i in modprobe_modules
foreground { modprobe {<i.module>} }
@endfor
-m755
+|end()
-|oneshot("mdevd-coldplug", "mount-dev\nmount-sys\nmodules\nmdevd")
-/mdevd-coldplug/up c mdevd-coldplug m644
+|start_oneshot("mdevd-coldplug", "mount-dev mount-sys modules mdevd")
+|up()
+ mdevd-coldplug
+|end()
-|oneshot("udev-coldplug", "mount-dev\nmount-sys\nmodules\nudev")
-/udev-coldplug/up c udevadm settle m644
+|start_oneshot("udev-coldplug", "mount-dev mount-sys modules udev")
+|up()
+ udevadm settle
+|end()
|if(get("dev_manager")) {
|service("dev-coldplug", "bundle", (<dev_manager>)"-coldplug")
|add_to_bundle("ok-sysinit", (<dev_manager>))
|}
-/mdevd d m755
-/mdevd/type c longrun m644
-/mdevd/dependencies c mount-dev m644
-/mdevd/notification-fd c 3 m644
-/mdevd/run
-C #!/command/execlineb -P
+|start_longrun("mdevd", "mount-dev") # TODO add "mount-proc mount-sys", add logger
+|notification_fd(3)
+|run() # TODO use run_el() or run_arg()
+ #!/command/execlineb -P
mdevd -D 3 -f /current/conf/etc/mdevd.conf
-m755
+|end()
-|longrun("udev", "mount-sys mount-proc mount-dev")
-m640
-/udev/notification-fd cN 3 m640
-|runscript_el_cgroup2("udev")
+|start_longrun("udev", "mount-sys mount-proc mount-dev") # TODO add logger
+|notification_fd(3)
+|run_el()
background {
sh -xc "until /sbin/udevadm settle --timeout=120; do sleep 0.5; done; echo >&3 settled"
#foreground { loopwhilex -x 0 if -nt { /sbin/udevadm settle --timeout=120 } foreground { sleep 0.1 } exit 1 }
@@ -162,73 +163,55 @@ m640
}
fdclose 3
/sbin/udevd
-m755
-
-|add_to_bundle("ok-all-but-tty", "swapon-vg-swap")
-/swapon-vg-swap d m755
-/swapon-vg-swap/dependencies
-C dev-coldplug
-m644
-/swapon-vg-swap/type c oneshot m644
-/swapon-vg-swap/up c swapon /dev/vg/swap m644
-/swapon-vg-swap/down c swapoff /dev/vg/swap m644
-
-|add_to_bundle("ok-mount", "mount-tmp-X11")
-|oneshot("mount-tmp-X11", "ok-sysinit")
-/mount-tmp-X11/up
-CN if { mkdir -p /tmp/.X11-unix /run/X11 }
+|end()
+
+|start_oneshot("swapon-vg-swap", "dev-coldplug")
+|in_bundle("ok-all-but-tty")
+|up()
+ swapon /dev/vg/swap
+|down()
+ swapoff /dev/vg/swap
+|end()
+
+|start_oneshot("mount-tmp-X11", "ok-sysinit")
+|in_bundle("ok-mount")
+|up()
+ if { mkdir -p /tmp/.X11-unix /run/X11 }
if { chmod 771 /run/X11 }
if { chown root:xorg /run/X11 }
mount --bind /run/X11 /tmp/.X11-unix
-m644
-/mount-tmp-X11/down
-CN foreground { umount /tmp/.X11-unix }
-m644
+|down()
+ foreground { umount /tmp/.X11-unix }
+|end()
-/openrc d m755
-/openrc/type cN oneshot m644
-/openrc/dependencies
-CN ok-sysinit
- ok-mount
- modules
-m644
-/openrc/up
-CN export TERM "linux"
+|start_oneshot("openrc", "ok-sysinit ok-mount modules")
+|up()
+ export TERM "linux"
foreground { /sbin/openrc boot }
/sbin/openrc default
-m644
-/openrc/down
-CN export TERM "linux"
+|down()
+ export TERM "linux"
/sbin/openrc shutdown
-m644
+|end()
/.scripts d m755
-|add_to_bundle("ok-all-but-tty", "sshd")
-|longrun_with_logger("sshd", "ssh_host_ed25519_key ssh_host_rsa_key ok-sysinit")
-|runscript_simple("sshd", "/usr/sbin/sshd -D -e -f /etc/ssh/sshd_config")
+|start_longrun_with_logger("sshd", "ssh_host_ed25519_key ssh_host_rsa_key ok-sysinit")
+|in_bundle("ok-all-but-tty")
+|run_arg("/usr/sbin/sshd -D -e -f /etc/ssh/sshd_config")
+|end()
-/ssh_host_ed25519_key d m755
-/ssh_host_ed25519_key/type cN oneshot m644
-/ssh_host_ed25519_key/dependencies
-CN hostname
- rootfs
-m644
-/ssh_host_ed25519_key/up
-CN if -n -t { s6-test -f /etc/ssh/ssh_host_ed25519_key }
+|start_oneshot("ssh_host_ed25519_key", "hostname rootfs")
+|up()
+ if -n -t { s6-test -f /etc/ssh/ssh_host_ed25519_key }
ssh-keygen -N "" -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
-m644
+|end()
-/ssh_host_rsa_key d m755
-/ssh_host_rsa_key/type cN oneshot m644
-/ssh_host_rsa_key/dependencies
-CN hostname
- rootfs
-m644
-/ssh_host_rsa_key/up
-CN if -n -t { s6-test -f /etc/ssh/ssh_host_rsa_key }
+|start_oneshot("ssh_host_rsa_key", "hostname rootfs")
+|up()
+ if -n -t { s6-test -f /etc/ssh/ssh_host_rsa_key }
ssh-keygen -N "" -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key
-m644
+|end()
|#|add_to_bundle("ok-all-but-tty", "swap")
|#/swap d m755
@@ -236,14 +219,9 @@ m644
|#/swap/up cN swapon -a m644
|#/swap/down cN swapoff -a m644
-/alsa-devices d m750
-/alsa-devices/dependencies
-CN modules
- udev
-m640
-/alsa-devices/type cN oneshot m640
-/alsa-devices/up
-CN sh -c "
+|start_oneshot("alsa-devices", "modules udev")
+|up()
+ sh -c "
retry=true
while $retry; do
retry=false
@@ -255,57 +233,56 @@ CN sh -c "
done
:
"
-m640
+|end()
-|add_to_bundle("ok-all-but-tty", "alsactl-rdaemon")
-|longrun_with_logger("alsactl-rdaemon","alsa-devices")
-|runscript_simple("alsactl-rdaemon", "alsactl rdaemon")
+|start_longrun_with_logger("alsactl-rdaemon","alsa-devices")
+|in_bundle("ok-all-but-tty")
+|run_arg("alsactl rdaemon")
+|end()
-|add_to_bundle("ok-all-but-tty", "brightness")
-|oneshot("brightness", "ok-sysinit")
-/brightness/up
-CN foreground { redirfd -w 1 /sys/class/backlight/intel_backlight/brightness echo 800 }
+|start_oneshot("brightness", "ok-sysinit")
+|in_bundle("ok-all-but-tty")
+|up()
+ foreground { redirfd -w 1 /sys/class/backlight/intel_backlight/brightness echo 800 }
if { chgrp users /sys/class/backlight/intel_backlight/brightness }
chmod g+w /sys/class/backlight/intel_backlight/brightness
-m644
-
-|add_to_bundle("ok-all-but-tty", "tlp")
-|oneshot("tlp", "ok-sysinit")
-/tlp/up
-CN tlp init start
-m644
-/tlp/finish
-CN tlp init stop
-m644
-
-|add_to_bundle("ok-all-but-tty", "containers")
-|oneshot("containers", "ok-mount")
-/containers/up
-CN export TERM "linux"
+|end()
+
+|start_oneshot("tlp", "ok-sysinit")
+|in_bundle("ok-all-but-tty")
+|up()
+ tlp init start
+|down()
+ tlp init stop
+|end()
+
+|start_oneshot("containers", "ok-mount")
+|in_bundle("ok-all-but-tty")
+|up()
+ export TERM "linux"
if {
zsh -lc "quiet=1 confz site_container_services"
}
s6-svscanctl -a /run/service
-m644
+|end()
@for u in user_svscan
-|add_to_bundle("ok-all-but-tty", "svscan-"(<u.name>))
-|longrun("svscan-"(<u.name>)"-log", "ok-sysinit\nrootfs")
-/svscan-{<u.name>}-log/consumer-for cN svscan-{<u.name>} m640
-|runscript_el_cgroup2("svscan-"(<u.name>)"-log")
+|start_longrun("svscan-"(<u.name>)"-log", "ok-sysinit rootfs")
+|consumer_for("svscan-"(<u.name>))
+|run_el()
if { mkdir -p /run/user/{<u.id>}.logs }
if { ln -sf {<u.id>}.logs /run/user/{<u.name>}.logs }
if { chown {<u.name>}: /run/user/{<u.id>}.logs }
if { chmod 700 /run/user/{<u.id>}.logs }
s6-setuidgid {<u.name>}
s6-log -- t /run/user/{<u.id>}.logs
-m755
+|end()
-|longrun("svscan-"(<u.name>), "ok-sysinit\nrootfs")
-/svscan-{<u.name>}/notification-fd cN 3
-m644
-/svscan-{<u.name>}/producer-for cN svscan-{<u.name>}-log m640
-|runscript_el_cgroup2("svscan-"(<u.name>))
+|start_longrun("svscan-"(<u.name>), "ok-sysinit rootfs")
+|in_bundle("ok-all-but-tty")
+|notification_fd(3)
+|producer_for("svscan-"(<u.name>)"-log")
+|run_el()
if { mkdir -p /run/user/{<u.id>} }
if { ln -sf {<u.id>} /run/user/{<u.name>} }
if { chown {<u.name>}: /run/user/{<u.id>} }
@@ -313,28 +290,29 @@ m644
s6-setuidgid {<u.name>}
if { mkdir -p /run/user/{<u.id>}/service }
s6-svscan -d 3 /run/user/{<u.id>}/service
-m755
+|end()
@endfor
-|add_to_bundle("ok-all-but-tty", "syncthing")
-|longrun_with_logger("syncthing", "ok-mount")
-|runscript_el_cgroup2("syncthing")
+|start_longrun_with_logger("syncthing", "ok-mount")
+|in_bundle("ok-all-but-tty")
+|run_el()
/usr/bin/env HOME=/var/lib/syncthing
s6-setuidgid syncthing
syncthing -logflags 0
-m755
+|end()
+|start_longrun_with_logger("tinc.ccx", "net-all")
|add_to_bundle("ok-all-but-tty", "tinc.ccx")
-|longrun_with_logger("tinc.ccx", "net-all")
-|runscript_simple("tinc.ccx", "tincd -n ccx -D -d")
+|run_arg("tincd -n ccx -D -d")
+|end()
-|add_to_bundle("net-all", "wpa_supplicant")
-|longrun_with_logger("wpa_supplicant", "modules\nok-sysinit")
-|runscript_el_cgroup2("wpa_supplicant")
+|start_longrun_with_logger("wpa_supplicant", "modules\nok-sysinit")
+|in_bundle("net-all")
+|run_el()
/sbin/wpa_supplicant
-iwlan0
-c/etc/wpa_supplicant/wpa_supplicant.conf
-m755
+|end()
@for i in X_servers