ZSH-based service monitoring
============================

Generates service descriptions for runit according to single service
description file (/etc/svtab).

Services are currently defined by run function, log function, check function
(to see whether service should be up or down) and miscellaneous flags.

ZSV does not manage dependencies between services. Instead it uses arbitrary
shell function to determine if specific service should be up or not. Service
starting may change the state so that other services will start, but this
requires calling the ``zsvgen`` executable to re-evaluate the dependencies.

Hook script ``zsv_ifupd`` is provided for netplugd and wpa_supplicant to trigger
on network interface changes. It should be symlinked or copied to
``/etc/netplug.d/netplug`` and called using ``wpa_cli -a`` (bundled function
for wpa_cli does this).

Format of the svtab file is as follows::

  # comment
  service1:flags:shell code
  service2:flags:shell
    code spanning several lines
  ...

Both flags and shell code are optional and can be left out. Flags are sequence
of ASCII letters. Lowercase letters turn specific feature off while uppercase
turn it on. The default is defined in ``zsv_config`` and possibly overriden by
``/etc/zsvrc``. Currently following flags are recognised:

* E: redirect stderr to stdout, so they are both logged

* M: manual operation - don't start or stop the service, just create it

* N: redirect the output to /dev/null

Shell code may set the variables runf, logf and checkf to override the
defaults. It's also possible to define custom check() function there instead
of setting checkf.

Name of the service has special meaning in a sense that it can change default
values. Service name is first stripped of any text right of and including
first ``.`` (dot) character and functions ``zsv_defaults_foo`` and
``zsv_run_foo`` (where foo is the stripped name) are looked for. The former is
executed to fill in default values and the latter is set as default runf if
found. The function setting defaults may use the rest of the service name to
fill in values, so eg.: ``dhcpcd.eth0`` sets the default run function to run
dhcpcd and preconfigures it to use eth0 iface.

Example files
-------------

TBD

* /etc/inittab

::

  # System initialization, mount local filesystems, etc.
  si::sysinit:/sbin/rc sysinit

  # Further system initialization, brings up the boot runlevel.
  rc::bootwait:/sbin/rc boot
  zsv::bootwait:/usr/local/bzr/zsv/sbin/zsvgen /run/zsv.log

  ru:2345:respawn:/usr/bin/runsvdir -P /run/service ................................................................................


* /etc/svtab

::

  syslog-ng
  sshd
  openntpd
  vixie-cron
  netplugd
  wpa_supplicant.wlan0:M
  wpa_cli.wlan0:M
  dhcpcd.wlan0
  dhcpcd.eth0
  example_echo::checkf=zsv_check_route; run=( tcpserver 0.0.0.0 1234 cat )

TODO
----

* interface for unprivileged users to manage their runit instances

* service generators (eg. foo.* instead of listing foo.1, foo.2,...)

* *DONE* more checks and event listeners (eg. rfkill, dhcpcd hook)

* *DONE* pluggable hooks

* *WIP* export better information what and when changed in configuration of
  each service so they can be reloaded/restarted as needed