From capezotte, 4 Months ago, written in Bash.
Embed
  1. #!/bin/execlineb
  2. #
  3. # This is the turnstile s6-rc backend. It accepts the action as its first
  4. # argument, which is either "ready", "run", or "stop". The backend can be
  5. # written in any language, in this case the shebang is used to run it.
  6. #
  7. # It also serves as an example of how to implement such backend in a non
  8. # shell language.
  9. #
  10. # Arguments for "ready":
  11. #
  12. # live:     the path to s6-rc's live dir; it is the string that is
  13. #           written by dinit into ready_fd for the "run" part of the process
  14. #
  15. # Arguments for "run":
  16. #
  17. # ready_p:  path to named pipe (fifo) that should be poked with a string; this
  18. #           will be passed to the "ready" script of the sequence as its sole
  19. #           argument (here this is the path to s6-rc's live state directory)
  20. # srvdir:   an internal directory that can be used by the service manager
  21. #           for any purpose (usually to keep track of its state)
  22. # confdir:  the path where turnstile's configuration data reside, used
  23. #           to source the configuration file
  24. #
  25. # Arguments for "stop":
  26. #
  27. # pid:      the PID of the service manager to stop (gracefully); it should
  28. #           terminate the services it's running and then stop itself
  29. #
  30. # How the script manages its configuration and so on is up to the script.
  31. #
  32. # Note that the script *must* exec the service manager directly, i.e. the
  33. # service manager must fully replace the shell process for this to work.
  34. #
  35. # Copyright 2024 Carlos Eduardo <[email protected]>
  36. # License: BSD-2-Clause
  37. #
  38.  
  39. importas -i directive 1
  40. shift -n 1
  41.  
  42. case $directive {
  43.         run {
  44.                 # source additional arguments.
  45.                 # two subsitution steps are needed because https://skarnet.org/lists/skaware/2049.html
  46.                 multisubstitute {
  47.                         importas -i __confdir 3
  48.                         importas -i __home    HOME
  49.                 }
  50.                 envfile -I -- ${__confdir}/s6-rc.conf
  51.  
  52.                 # despite the above warning, we do want serial substitution on these, so we import it here, before the bigger multisubstitute.
  53.                 multisubstitute {
  54.                         importas -uD "${HOME}/.local/share/s6/compiled" compiled compileddir
  55.                         importas -uD "${statedir}/s6-rc"                live     livestatedir
  56.                         importas -uD "${statedir}/env"                  env      envdir
  57.                 }
  58.                 multisubstitute {
  59.                         importas -i readyfifo 1
  60.                         importas -i statedir 2
  61.                         importas -i confdir 3
  62.                         # not used directly, but might be useful for the config file
  63.                         importas -Si HOME
  64.                         importas -Si USER
  65.                         importas -Si XDG_RUNTIME_DIR
  66.                         importas -Si SHELL
  67.                         importas -Si LOGNAME
  68.                 }
  69.  
  70.                 # Initialize state directory.
  71.                 # confdir/s6 should have the definition for a s6-svscan-log
  72.                 # service that acts as the catch-all loger. See:
  73.                 # /run/service/s6-svscan-log
  74.                 # on a s6-linux-init powered machine for an example.
  75.                 # It should also contain a .s6-svscan/SIGINT file with
  76.                 # foreground { s6-rc -bDa } s6-svscanctl -t .
  77.                 if { cp -a -- ${confdir}/s6 ${statedir}/service }
  78.  
  79.                 pipeline -dw -- {
  80.                         if {
  81.                                 forstdin -x0 _
  82.                                         exit 0
  83.                         }
  84.                         if -nt {
  85.                                 # Create envdir.
  86.                                 if { mkdir -p -- ${env} }
  87.                                 # Init service management layer.
  88.                                 if { s6-rc-init -c $compiled -l $live -- ${statedir}/service }
  89.                                 # Wait for logger to come up.
  90.                                 redirfd -w 2 ${statedir}/service/s6-svscan-log/fifo
  91.                                 # Print string for the ready step.
  92.                                 redirfd -w 1 ${readyfifo}
  93.                                 printf %s $live
  94.                         }
  95.                         # tell s6-svscan to give up if anything goes awry.
  96.                         s6-svscanctl -t -- ${statedir}/service
  97.                 }
  98.                         # turn pipeline output into notification-fd.
  99.                         fdmove -c 3 1
  100.                         # backup stderr for catch-all logger
  101.                         fdmove -c 4 2
  102.                         # fifo trick
  103.                         redirfd -wnb 2 ${statedir}/service/s6-svscan-log/fifo
  104.                         fdmove -c 1 2
  105.                         # avoid leaking script arguments
  106.                         emptyenv -P
  107.                         # export extra info for helper scripts
  108.                         export SVDIR ${statedir}/service
  109.                         export TURNSTILE_S6RC_LIVESTATE_DIR ${live}
  110.                         s6-svscan -d 3 -X 4 -- ${statedir}/service
  111.         }
  112.         ready {
  113.                 importas -i string 1
  114.                 s6-rc -l $string -up change default
  115.         }
  116.         stop {
  117.                 importas -i ! 1
  118.                 # Using INT instead of TERM so the s6-rc -bDa change hook runs
  119.                 kill -s INT $!
  120.         }
  121. }
  122.         exit 32
  123.  
captcha