rats

RAdix iniT Suite
git clone https://git.daat.foo/repos/rats.git
Log | Files | Refs | README | LICENSE

README (11256B)


      1 RAdix iniT Suite
      2 ================
      3 
      4 RATS is an init suite forked from sinit to extend the features
      5 so it could be used standalone.
      6 
      7 Why?
      8 ----
      9 Even though sinit is pretty good, unfortunately, I want service
     10 supervision, dependency management, logging, etc all in one instead
     11 of using separate utilities bootstrapped together. My old setup was
     12 using sinit + nitro with a bunch of shell scripting to handle things
     13 I felt that the init is okay to do.
     14 
     15 General boot process
     16 --------------------
     17 kernel -> init=/sbin/origo
     18     |- origo mounts /proc /sys /dev /dev/pts
     19     |- origo runs /etc/rc.boot (which sources /etc/rc.local)
     20     |- origo spawns serva
     21         |- serva scans /etc/ssv/{boot,default,...}
     22         |- serva starts services in (stage, name) alphabetical order
     23         |- serva listens on /run/serva.sock
     24     |- origo enters signal loop (sigwait)
     25         * SIGCHLD  - reap zombies, respawn serva if dead
     26         * SIGUSR1  - poweroff
     27         * SIGUSR2  - reboot
     28         * SIGINT   - reboot (CtrlAltDel)
     29         * SIGTERM  - single-user (rc.single or /bin/sh)
     30 
     31 
     32 Project Overview
     33 ================
     34 
     35 origo: PID 1 - minimal init.
     36 ----------------------------
     37 Mounts /proc /sys /dev /dev/pts /dev/shm, runs /etc/rc.boot,
     38 spawns+respawns serva, handles poweroff/reboot/single-user.
     39 Signal mapping (same as sinit):
     40     - SIGINT  -> reboot (CtrlAltDel)
     41     - SIGUSR1 -> poweroff
     42     - SIGUSR2 -> reboot
     43     - SIGTERM -> single-user 
     44 
     45 NOTE: origo won't mount `/run` nor `/tmp` to tmpfs because they are 
     46 optional in most setups. For users who want to mount these at boot,
     47 you can edit your `/etc/fstab` to do so: This applies to those who
     48 install the optional example rc.boot script but you can do so yourself
     49 by invoking `mount -a` in your own rc.boot scripts to have your system
     50 respect `/etc/fstab`.
     51 
     52 origo will do the following on shutdown/reboot:
     53     1. stopping serva (which stops all supervised services)
     54     2. kills all remaining processes
     55     3. remount the root read-only
     56     4. syncs the fs
     57 
     58 serva: a simple service supervisor.
     59 -----------------------------------
     60 Scans /etc/ssv/ for stage directories, forks run per service in
     61 (stage, name) alphabetical order, restarts with backoff.
     62 
     63 It is entirely possible to use either numerical or words for stages
     64 if desired.
     65 
     66 Pipes stdout/stderr to log (logger) if present (has to be executable).
     67 Listens on /run/serva.sock for svc control commands.
     68 
     69 Layout:
     70     /etc/ssv/
     71         <stage>/                  stage directory (e.g. boot, default)
     72             <service>/
     73                 run               run executable (required; $1 = @-arg)
     74                 log               logger executable (optional)
     75                 once              touch-file: run once, don't supervise
     76                 noreset           touch-file: run but don't restart on exit
     77                 down              touch-file: don't auto-start; svc -u works
     78                 need/<name>       hard dep: wait for <name> to be running
     79                 after/<name>      soft hint: start after <name> if possible
     80 
     81 Symlink templates (names ending with @ are skipped):
     82         /etc/ssv/boot/tty@/            template directory
     83         /etc/ssv/boot/tty@tty1         symlink -> tty@; "tty1" passed as $1
     84 
     85 Service identifiers for svc:
     86      sshd                 first match across all stages
     87      boot/sshd            specific stage + service 
     88 
     89 
     90 NOTE: to the logger, serva sets the following environment variables:
     91         - SVC_NAME  : Service name (e.g. sshd)
     92         - SVC_STAGE : Stage name (e.g. default)
     93         - SVC_ARG   : @ -arg if applicable (e.g. tty1 if getty@tty1)
     94 
     95 you can use these in the log script:
     96 
     97     #!/bin/sh
     98     exec slog -d "/var/log/$SVC_NAME-$SVC_ARG"
     99 
    100 More information on slog later.
    101 
    102 This design makes serva logger-agnostic, you are free to use whatever you like
    103 as long as you can pipe the output into your logger of choice.
    104 
    105 svc: control client for serva.
    106 ------------------------------
    107 Talks to /run/serva.sock over a Unix socket.
    108 
    109 usage: svc [-udrkts] [-a] [name...]
    110         -u  bring up       -d  bring down      -r  restart
    111         -k  kill (SIGKILL) -t  terminate       -s  status (optionally per-service)
    112         -a  all services (with -u or -d) 
    113 
    114 Multiple names are handled one at a time. svc exits with status 1 if a
    115 request fails or serva returns ERR, and status 2 if closing stdout fails.
    116 
    117 slog: simple logging daemon.
    118 ----------------------------
    119 Reads stdin, writes to <dir>/current, rotates on size. Existing current
    120 file contents count toward the threshold. Rotation happens after a read
    121 chunk is written, so a file may exceed the threshold by up to 4095 bytes.
    122 Rotated files: <dir>/0, <dir>/1, ..., <dir>/<n-1>
    123 
    124 example:
    125     /var/log/sshd/current - active log
    126     /var/log/sshd/0       - most recent rotation
    127     /var/log/sshd/1
    128     ...
    129     /var/log/sshd/9       - oldest, deleted on next rotation
    130 
    131 usage: slog [-d dir] [-s bytes] [-n count]
    132         -d  log directory (default: .)
    133         -s  max size per file in bytes (default: 1048576 = 1MB)
    134         -n  max number of rotated files (default: 10) 
    135 
    136 slog works perfectly fine outside of serva:
    137     
    138     some-daemon 2>&1 | slog -d /var/log/some-daemon -s 524288 -n 5
    139 
    140 What does slog NOT do:
    141     - No syslog protocol. It reads stdin, writes files. If you need syslog
    142       (/dev/log socket), run a real syslogd as a service.
    143     - No timestamps. The service's run script should add them if needed
    144       (e.g. pipe throughts or use a logger that adds timestamps). Or modify
    145       slog to prepend timestamps, it's a 5-line change. Most daemons already
    146       provide timestamps anyways.
    147     - No compression. Rotated files are plain text. Add a cron job to gzip
    148       them if needed.
    149 
    150 
    151 Requirements
    152 ============
    153 
    154     cc       POSIX.1-2008-compliant C compiler (pcc, etc)
    155     make     POSIX make (aruu make, pdpmake, gmake, bmake)
    156 
    157 
    158 Portability across UNIX systems
    159 ==============================
    160 
    161 origo currently uses Linux mount and reboot interfaces. The example rc
    162 scripts also use Linux utilities. serva and svc target POSIX.1-2008;
    163 serva additionally uses XSI realpath(). Other UNIX systems have not been
    164 tested.
    165 
    166 Control socket access currently relies on pathname permissions. Linux
    167 enforces these permissions, but POSIX does not require this. Supporting
    168 another UNIX system requires checking its socket access rules or adding
    169 peer credential checks. See [unix(7)](https://man7.org/linux/man-pages/man7/unix.7.html).
    170 
    171 
    172 Building
    173 ========
    174 
    175 Building this project is trivial, to build the suite:
    176 
    177     make
    178 
    179 Configuration is in config.mk, you can override compile flags via make.
    180 
    181 NOTE: by default RATS will try to build statically, you can override this by passing `LDFLAGS=`.
    182 Basically, just make LDFLAGS empty.
    183 
    184 Run the integration tests with:
    185 
    186     make check
    187 
    188 Tests use a separate directory under tests/sandbox/ for each run and
    189 leave their logs there. The tracked service fixtures are copied into it.
    190 
    191 
    192 Installation
    193 ============
    194 
    195 Follows regular make install conventions ($DESTDIR and $PREFIX). 
    196 Additionally, you are able to set SBIN_DIR and BIN_DIR (/sbin, /bin).
    197 
    198     make install # will install to /usr/local by default
    199 
    200 Install example rc.* files along with poweroff/reboot commands:
    201 
    202     make install-files
    203 
    204 
    205 Installed Files
    206 ===============
    207 
    208 Below are the executables that are installed when invoking `make install`, you are expected
    209 to provide your own rc.* scripts, unless you install the optional example files.
    210 
    211     $(PREFIX)/sbin/origo # PID 1
    212     $(PREFIX)/sbin/serva # supervisor
    213     $(PREFIX)/bin/svc    # control client
    214     $(PREFIX)/bin/slog   # logging daemon
    215 
    216 NOTE: sbin/bin can be changed via the make envs `$BIN_DIR` and `$SBIN_DIR`; these are for
    217 systems (me) that don't have an sbin, or prefer some other binary directory.
    218 
    219 Optional Installed Files
    220 ------------------------
    221 All files below are example files that are installed when invoking `make install-files`,
    222 it's entirely possible to run a system with these example files with little to no changes.
    223 
    224     /etc/rc.boot     # (REQUIRED) first run before serva
    225     /etc/rc.shutdown # (REQUIRED) run before full shutdown
    226 
    227     /etc/rc.local    # (optional) rc.boot should source this
    228     /etc/rc.single   # (optional) single-user script, else origo will run /bin/sh
    229 
    230 NOTE: Below are shell scripts.
    231 
    232      $(PREFIX)/bin/poweroff # sends SIGUSR1 to PID1
    233      $(PREFIX)/bin/reboot   # sends SIGINT to PID1
    234 
    235 
    236 Source Layout
    237 =============
    238 
    239     config.mk                   build configuration
    240     Makefile                    posix (should work with any *competent* make impl)
    241     tests/
    242        run.sh                   run this to test init suite (currently only serva/svc)
    243        Makefile                 build serva/svc test binaries
    244        ssv/*                    dummy ssv
    245        sandbox/                 temporary test state (not tracked)
    246     files/
    247        rc.*                     optional example configurations
    248        bin/*                    optional scripts to use along with RATS
    249     *.c                         c files
    250     *.h                         headers
    251 
    252 
    253 TODO
    254 ====
    255 
    256 manpages - someone else needs to do this or I'm going to die learning troff
    257 serva    -- primarily with handling errors coming from the services itself,
    258          |  or at least returning ERR when that's the case.
    259          |
    260          |- svc -s now reports per-service run count, uptime, and last
    261             exit status/signal; svc -s <name> focuses a single service.
    262             Streaming service logs through svc is still open.
    263 user     - still thinking on this one, I think it would be interesting to
    264            have something like dinit. It might be an overreach for this project
    265            but it can be used for "bloated" setups where users need dbus-session,
    266            pipewire, etc. to run when booted.
    267 
    268 
    269 Contribution
    270 ============
    271 
    272 Sending patches is trivial, the main site of development is on the 
    273 [stagit repo](https://git.daat.foo/rats/log.html).
    274 This means that all patches aren't sent via PRs on any of the mirrors.
    275 
    276 Run a quick `git format-patch HEAD~1` and send to *cowmonk@based.pt* with the
    277 subject head of `[PATCH] RATS`. Consider reading the manpages of `git-send-email`
    278 if you are interested in moving towards email for development.
    279 
    280 I *strongly* suggest pgp encrypting your email, in which case my public keys can be
    281 found on `keys.openpgp.org` or here:
    282 
    283 -----BEGIN PGP PUBLIC KEY BLOCK-----
    284 Comment: 52B0 852C 5A4C 823C FAB7  420A 2F73 9BCA BDD5 B880
    285 Comment: cowmonk@based.pt
    286 
    287 xjMEaSJi8xYJKwYBBAHaRw8BAQdAEVP64bLVXCxZYH5rItmtvThKyTrRZ4HFCZ42
    288 IqFx+crNEGNvd21vbmtAYmFzZWQucHTCiQQTFggAGgQLCQgHAhUIAhYBAhkABYJp
    289 ImLzAp4BApsDACEJEC9zm8q91biAFiEEUrCFLFpMgjz6t0IKL3Obyr3VuIBOEQEA
    290 +gIa9t3yKL3FAHg5VT2xV8M2VdLf1ZqaFlCPyGhXBZsA+QGGstK6+YsUbmP+H6I5
    291 r4AgLawGeB9IH7WC0w4dhTsKzjgEaSJi8xIKKwYBBAGXVQEFAQEHQMsmen1ddl9a
    292 ddXu4ktm8BATTlEy2k4zMzo6RnyRB+d4AwEIB8J4BBgWCAAJBYJpImLzApsMACEJ
    293 EC9zm8q91biAFiEEUrCFLFpMgjz6t0IKL3Obyr3VuIA9AQD/S/EL51hMSBI35Lr3
    294 RjuNFtqnlgYpfkMxgPvp2bWRY60A/2NhDRNUjY2wA4+mESlCIf94FVvqcfclnSZU
    295 A7wM/YAB
    296 =nZZp
    297 -----END PGP PUBLIC KEY BLOCK-----
    298 
    299 
    300 LICENSE
    301 =======
    302 
    303 See ./LICENSE for details.
    304 
    305 Portions of this software are partially based on code written by Aruu authors and
    306 contributors, with portions within itself derived from various BSD/MIT-licensed 
    307 open source projects.