move developer documentation from guide.md to service-script-guide.md

This commit is contained in:
William Hubbs 2018-01-10 13:25:13 -06:00
parent 918d955fd2
commit 14e3359a9e
2 changed files with 117 additions and 117 deletions

125
guide.md
View File

@ -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 graph, then starts the needed service scripts, either serialized (default) or in
parallel. parallel.
When all the init scripts are started openrc terminates. There is no persistent When all the service scripts are started openrc terminates. There is no
daemon. (Integration with tools like monit, runit or s6 can be done) persistent daemon. (Integration with tools like monit, runit or s6 can be done)
# Shutdown # Shutdown
@ -63,7 +63,7 @@ own if needed. This allows, for example, to have a default runlevel with
disabled. disabled.
The `rc-status` helper will print all currently active runlevels and the state The `rc-status` helper will print all currently active runlevels and the state
of init scripts in them: of services in them:
``` ```
# rc-status # rc-status
@ -74,7 +74,7 @@ Runlevel: default
``` ```
All runlevels are represented as folders in `/etc/runlevels/` with symlinks to 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 Calling openrc with an argument (`openrc default`) will switch to that
runlevel; this will start and stop services as needed. 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. course be done by hand if desired.
e.g. `rc-update add nginx default` - add nginx to the default runlevel 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 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 FIXME: Document stacked runlevels
The default startup uses the runlevels `boot`, `sysinit` and `default`, in that The default startup uses the runlevels `boot`, `sysinit` and `default`, in that
order. Shutdown uses the `shutdown` runlevel. 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` # The Magic of `conf.d`
Most service scripts need default values. It would be fragile to 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. script can be avoided.
# Start-Stop-Daemon # Start-Stop-Daemon
@ -271,7 +162,7 @@ happen automatically when the service is stopped.
# Caching # 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`. (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 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. OpenRC has wrappers for many common output tasks in libeinfo.
This allows to print colour-coded status notices and other things. 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. print nice messages.

View File

@ -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 start-stop-daemon to manage a fairly typical long-running UNIX
process. 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 ## Don't write your own start/stop functions
OpenRC is capable of stopping and starting most daemons based on the OpenRC is capable of stopping and starting most daemons based on the