/riffol

Initialization system in Rust

Primary LanguageRust

Riffol

Riffol is a supervising process that can run as a traditional daemon on Unix-like systems or as an init system for containers (such as tini).

Riffol can be configured by creating application groups that consist of applications, health checks and dependency checks.

Riffol uses the unified configuration model from https://github.com/riboseinc/event-configuration-models for its configuration syntax definition, startup configuration and also runtime configuration.

Riffol is implemented in Rust.

Components

   +--------+
   | Riffol |
   +----+---+
        |
        |
        |
 +------v------+
 | Application |
 |    Group    +-------+--------------+---------------+
 +------+------+       |              |               |
        |              |              |               |
        |              |              |               |
        |              |              |               |
 +------v------+   +---v----+   +-----v------+   +----v-----+
 | Application |   | Health |   | Dependency |   | Resource |
 +-------------+   | Check  |   +------------+   |  Limits  |
                   +--------+                    +----------+

Configuration

Init

The main configuration to create application groups:

init "name" {
  application_groups = [
    "applicationgroup.name"
  ]
}

E.g.:

init "web" {
  application_groups = [
    "applicationgroup.webstack"
  ]
}

Application Group

The entered entries in the applications[] list is also the order in which applications should be started.

application_group "name" {
  applications = [
    "application.name"
  ]
  dependencies = [
    "dependency.name"
  ]
}

E.g.:

application_group "webstack" {
  applications = [
    "application.db",
    "application.www"
  ]
  dependencies = [
    "dependency.webstackdependencies"
  ]
}

Application

application "name" {
  exec = "string"
  dir = "string"
  env = {
    "string" = "string"
    "string" = "string"
  }
  env_file = "string"
  start = "string"
  stop = "string"
  restart = "string"
  stdout = "string"
  stderr = "string"
  uid = int
  gid = int
  healthchecks = [
    "healthcheck.name"
  ]
  healthcheckfail = "string"
}

E.g.:

application "www" {
  exec = "/etc/init.d/http"
  dir = "/var/www"
  env = {
    var1key = var1value
    var2key = var2value
  }
  env_file = "/etc/httpd/morevars"
  start = "start"
  stop = "stop"
  restart = "restart"
  stdout = ""
  stderr = ""
  uid = 0
  gid = 0
  healthchecks = [
    "healthcheck.www"
  ]
  healthcheckfail = "restart"
}

Health Check

healthcheck "name" {
  checks = [
    "key://value"
  ]
  interval = int
  timeout = int
}

There are several checks classes:

  1. df, disk free space

  2. proc, process name

  3. tcp, TCP connection

  4. udp, UDP connection

  5. http, establish a http connection

  6. https, establish a https connection

Parameters:

  1. interval, the interval of the check defined in seconds

  2. timeout, the timeout of network connections defined in seconds

E.g.:

healthcheck "db" {
  checks = [
    "df:///var/lib/mysql:512"
    "proc://mysqld",
    "tcp://127.0.0.1:3306"
  ]
  interval = 60
  timeout = 10
}

Dependency

A packages[] dependency is checked via an operating system specific method.

e.g.: on RHEL/CentOS Riffol will execute rpm -q ${name}

dependency "name" {
  packages = [
    "string"
  ]
}

E.g.:

dependency "webstack" {
  packages = [
    "httpd",
    "mariadb"
  ]
}

Resource Limits

limits "name" {
  max_procs = int
  max_mem = int
}

e.g.:

limits "db" {
  max_procs = 4
  max_mem = 1024
}

Redirection and stream destination

stream_destination "rsyslog" {
  encoding = "UTF"
  host = "192.168.1.3"
  port = 514
  protocol = "udp"
}

stream_destination "logfile" {
  encoding = "UTF"
  file = "/var/log/mylogs"
}

application "www" {
  ...
  stdout = "${stream_desination.logfile}"
  stderr = "${stream_desination.rsyslog}"
  ...
}

…​ Riffol?

The eggs of a female salmon are called her roe. To lay her roe, the female salmon builds a spawning nest, called a redd, in a riffle with gravel as its streambed. A riffle is a relatively shallow length of stream where the water is turbulent and flows faster.

By spelling "riffol" with an O, we are putting the chemical symbol for oxygen in the word: we are oxidising Riffol. Which makes sense, since Riffol is in Rust.