From 14e3359a9e4174da3e422957d9de56907f025875 Mon Sep 17 00:00:00 2001 From: William Hubbs Date: Wed, 10 Jan 2018 13:25:13 -0600 Subject: [PATCH] move developer documentation from guide.md to service-script-guide.md --- guide.md | 125 +++------------------------------------- service-script-guide.md | 109 +++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 117 deletions(-) diff --git a/guide.md b/guide.md index f8c23194..80c8a7d3 100644 --- a/guide.md +++ b/guide.md @@ -27,8 +27,8 @@ openrc scans the runlevels (default: `/etc/runlevels`) and builds a dependency graph, then starts the needed service scripts, either serialized (default) or in parallel. -When all the init scripts are started openrc terminates. There is no persistent -daemon. (Integration with tools like monit, runit or s6 can be done) +When all the service scripts are started openrc terminates. There is no +persistent daemon. (Integration with tools like monit, runit or s6 can be done) # Shutdown @@ -63,7 +63,7 @@ own if needed. This allows, for example, to have a default runlevel with disabled. The `rc-status` helper will print all currently active runlevels and the state -of init scripts in them: +of services in them: ``` # rc-status @@ -74,7 +74,7 @@ Runlevel: default ``` All runlevels are represented as folders in `/etc/runlevels/` with symlinks to -the actual init scripts. +the actual service scripts. Calling openrc with an argument (`openrc default`) will switch to that runlevel; this will start and stop services as needed. @@ -83,122 +83,13 @@ Managing runlevels is usually done through the `rc-update` helper, but could of course be done by hand if desired. e.g. `rc-update add nginx default` - add nginx to the default runlevel Note: This will not auto-start nginx! You'd still have to trigger `rc` or run -the initscript by hand. +the service script by hand. FIXME: Document stacked runlevels The default startup uses the runlevels `boot`, `sysinit` and `default`, in that order. Shutdown uses the `shutdown` runlevel. - -# Syntax of Service Scripts - -Service scripts are shell scripts. OpenRC aims at using only the standardized -POSIX sh subset for portability reasons. The default interpreter (build-time -toggle) is `/bin/sh`, so using for example mksh is not a problem. - -OpenRC has been tested with busybox sh, ash, dash, bash, mksh, zsh and possibly -others. Using busybox sh has been difficult as it replaces commands with -builtins that don't offer the expected features. - -The interpreter for initscripts is `#!/sbin/openrc-run`. -Not using this interpreter will break the use of dependencies and is not -supported. (iow: if you insist on using `#!/bin/sh` you're on your own) - -A `depend` function declares the dependencies of this service script. -All scripts must have start/stop/status functions, but defaults are provided. -Extra functions can be added easily: - -``` -extra_commands="checkconfig" -checkconfig() { - doSomething -} -``` - -This exports the checkconfig function so that `/etc/init.d/someservice -checkconfig` will be available, and it "just" runs this function. - -While commands defined in `extra_commands` are always available, commands -defined in `extra_started_commands` will only work when the service is started -and those defined in `extra_stopped_commands` will only work when the service is -stopped. This can be used for implementing graceful reload and similar -behaviour. - -Adding a restart function will not work, this is a design decision within -OpenRC. Since there may be dependencies involved (e.g. network -> apache) a -restart function is in general not going to work. -restart is internally mapped to `stop()` + `start()` (plus handling dependencies). -If a service needs to behave differently when it is being restarted vs -started or stopped, it should test the `$RC_CMD` variable, for example: - -``` -[ "$RC_CMD" = restart ] && do_something -``` - -# The Depend Function - -This function declares the dependencies for a service script. This -determines the order the service scripts start. - -``` -depend() { - need net - use dns logger netmount - want coolservice -} -``` - -`need` declares a hard dependency - net always needs to be started before this - service does - -`use` is a soft dependency - if dns, logger or netmount is in this runlevel - start it before, but we don't care if it's not in this runlevel. - `want` is between need and use - try to start coolservice if it is - installed on the system, regardless of whether it is in the - runlevel, but we don't care if it starts. - -`before` declares that we need to be started before another service - -`after` declares that we need to be started after another service, without - creating a dependency (so on calling stop the two are independent) - -`provide` allows multiple implementations to provide one service type, e.g.: - `provide cron` is set in all cron-daemons, so any one of them started - satisfies a cron dependency - -`keyword` allows platform-specific overrides, e.g. `keyword -lxc` makes this - service script a noop in lxc containers. Useful for things like keymaps, - module loading etc. that are either platform-specific or not available - in containers/virtualization/... - -FIXME: Anything missing in this list? - -# The Default Functions - -All service scripts are assumed to have the following functions: - -``` -start() -stop() -status() -``` - -There are default implementations in `lib/rc/sh/openrc-run.sh` - this allows very -compact service scripts. These functions can be overridden per service script as -needed. - -The default functions assume the following variables to be set in the service -script: - -``` -command= -command_args= -pidfile= -``` - -Thus the 'smallest' service scripts can be half a dozen lines long - # The Magic of `conf.d` Most service scripts need default values. It would be fragile to @@ -217,7 +108,7 @@ start() { } ``` -The big advantage of this split is that most of the time editing of the init +The big advantage of this split is that most of the time editing of the service script can be avoided. # Start-Stop-Daemon @@ -271,7 +162,7 @@ happen automatically when the service is stopped. # Caching -For performance reasons OpenRC keeps a cache of pre-parsed initscript metadata +For performance reasons OpenRC keeps a cache of pre-parsed service metadata (e.g. `depend`). The default location for this is `/${RC_SVCDIR}/cache`. The cache uses `mtime` to check for file staleness. Should any service script @@ -281,5 +172,5 @@ change it'll re-source the relevant files and update the cache OpenRC has wrappers for many common output tasks in libeinfo. This allows to print colour-coded status notices and other things. -To make the output consistent the bundled initscripts all use ebegin/eend to +To make the output consistent the bundled service scripts all use ebegin/eend to print nice messages. diff --git a/service-script-guide.md b/service-script-guide.md index 668d05d4..4839e1b4 100644 --- a/service-script-guide.md +++ b/service-script-guide.md @@ -13,6 +13,115 @@ don't consider anything exotic, and assume that you will use start-stop-daemon to manage a fairly typical long-running UNIX process. +## Syntax of Service Scripts + +Service scripts are shell scripts. OpenRC aims at using only the standardized +POSIX sh subset for portability reasons. The default interpreter (build-time +toggle) is `/bin/sh`, so using for example mksh is not a problem. + +OpenRC has been tested with busybox sh, ash, dash, bash, mksh, zsh and possibly +others. Using busybox sh has been difficult as it replaces commands with +builtins that don't offer the expected features. + +The interpreter for service scripts is `#!/sbin/openrc-run`. +Not using this interpreter will break the use of dependencies and is not +supported. (iow: if you insist on using `#!/bin/sh` you're on your own) + +A `depend` function declares the dependencies of this service script. +All scripts must have start/stop/status functions, but defaults are provided and should be used unless you have a very strong reason not to use them. + +Extra functions can be added easily: + +``` +extra_commands="checkconfig" +checkconfig() { + doSomething +} +``` + +This exports the checkconfig function so that `/etc/init.d/someservice +checkconfig` will be available, and it "just" runs this function. + +While commands defined in `extra_commands` are always available, commands +defined in `extra_started_commands` will only work when the service is started +and those defined in `extra_stopped_commands` will only work when the service is +stopped. This can be used for implementing graceful reload and similar +behaviour. + +Adding a restart function will not work, this is a design decision within +OpenRC. Since there may be dependencies involved (e.g. network -> apache) a +restart function is in general not going to work. +restart is internally mapped to `stop()` + `start()` (plus handling dependencies). +If a service needs to behave differently when it is being restarted vs +started or stopped, it should test the `$RC_CMD` variable, for example: + +``` +[ "$RC_CMD" = restart ] && do_something +``` + +## The Depend Function + +This function declares the dependencies for a service script. This +determines the order the service scripts start. + +``` +depend() { + need net + use dns logger netmount + want coolservice +} +``` + +`need` declares a hard dependency - net always needs to be started before this + service does + +`use` is a soft dependency - if dns, logger or netmount is in this runlevel + start it before, but we don't care if it's not in this runlevel. + `want` is between need and use - try to start coolservice if it is + installed on the system, regardless of whether it is in the + runlevel, but we don't care if it starts. + +`before` declares that we need to be started before another service + +`after` declares that we need to be started after another service, without + creating a dependency (so on calling stop the two are independent) + +`provide` allows multiple implementations to provide one service type, e.g.: + `provide cron` is set in all cron-daemons, so any one of them started + satisfies a cron dependency + +`keyword` allows platform-specific overrides, e.g. `keyword -lxc` makes this + service script a noop in lxc containers. Useful for things like keymaps, + module loading etc. that are either platform-specific or not available + in containers/virtualization/... + +FIXME: Anything missing in this list? + +## The Default Functions + +All service scripts are assumed to have the following functions: + +``` +start() +stop() +status() +``` + +There are default implementations in `lib/rc/sh/openrc-run.sh` - this allows very +compact service scripts. These functions can be overridden per service script as +needed. + +The default functions assume the following variables to be set in the service +script: + +``` +command= +command_args= +pidfile= +``` + +Thus the 'smallest' service scripts can be half a dozen lines long + ## Don't write your own start/stop functions OpenRC is capable of stopping and starting most daemons based on the