The Funtoo Linux project has transitioned to "Hobby Mode" and this wiki is now read-only.
Difference between revisions of "Openrc"
m |
|||
(10 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== Service script == | == Service script == | ||
=== Mini howto === | === Mini howto === | ||
Let's start to write our openrc service script( | Let's start to write our openrc service script({{f|/etc/init.d/mydaemon}}). The first line is: | ||
<pre> | <pre> | ||
#!/sbin/openrc-run | #!/sbin/openrc-run | ||
Line 20: | Line 19: | ||
description="super essential service" | description="super essential service" | ||
</pre> | </pre> | ||
And | And {{c|/etc/init.d/mydaemon describe}} now shows us: | ||
<pre> | <pre> | ||
* super essential service | * super essential service | ||
Line 45: | Line 44: | ||
</pre> | </pre> | ||
Next add | Next add dependencies to our service script: | ||
<pre> | |||
depend() { | |||
need localmount | |||
use logger | |||
} | |||
</pre> | |||
If we need more services, for example, with need keyword, we can use several lines: | |||
<pre> | |||
need localmount | |||
need net | |||
</pre> | |||
or place they separated with spaces on a single line: | |||
<pre> | |||
need localmount net | |||
</pre> | |||
Where we can use the next keywords with service names separated with spaces: | |||
* '''need''' - a hard dependency - localmount always needs to be started before this service does(if this service is restarted, then our service will be restarted too); | |||
* '''use''' - a soft dependency - if logger is in this runlevel start it before, but we don't care if it's not in this runlevel; | |||
* '''want''' - between need and use - try to start specified services if they are installed on the system, regardless of whether they are in the runlevel, but we don't care if they don't exist; | |||
* '''before''' - our service need to be started before another services(if this service isn't exist or is placed to other runlevel, this settings has no effect); | |||
* '''after''' - our service need to be started after another services(if this service isn't exist or is placed to other runlevel, this settings has no effect); | |||
* '''provide''' - allows multiple implementations to provide one service type(e.g. "provide logger" - thus, any syslogd implementation satisties logger dependency); | |||
* '''keyword''' - platform-specific overrides; see openrc docs for details. | |||
Next add checking of a config file before daemon start: | |||
<pre> | |||
checkconfig() { | |||
... | |||
} | |||
start_pre() { | |||
checkconfig || return $? | |||
} | |||
</pre> | |||
Also, we should check a config file on restart to prevent of restarting a running service with a broken config: | |||
<pre> | |||
start_pre() { | |||
# Prevent of double check | |||
if [ "${RC_CMD}" != "restart" ] ; then | |||
checkconfig || return $? | |||
fi | |||
} | |||
stop_pre() { | |||
if [ "${RC_CMD}" = "restart" ] ; then | |||
checkconfig || return $? | |||
fi | |||
} | |||
</pre> | |||
We done this check with help of start_pre()/stop_pre() because openrc convert restart action to a sequence of stop-start actions. | |||
The complete service script is: | |||
<pre> | |||
#!/sbin/openrc-run | |||
command="/usr/sbin/mydaemon" | |||
command_args="-c /etc/mydaemon.conf" | |||
command_user="user:group" | |||
description="super essential service" | |||
pidfile="/var/run/mydaemon.pid" | |||
depend() { | |||
need localmount | |||
use logger | |||
} | |||
checkconfig() { | |||
... | |||
} | |||
start_pre() { | |||
# Prevent of double check | |||
if [ "${RC_CMD}" != "restart" ] ; then | |||
checkconfig || return $? | |||
fi | |||
} | |||
stop_pre() { | |||
if [ "${RC_CMD}" = "restart" ] ; then | |||
checkconfig || return $? | |||
fi | |||
} | |||
</pre> | |||
=== Extra commands === | === Extra commands === | ||
Line 57: | Line 137: | ||
} | } | ||
</pre> | </pre> | ||
=== Debug mode === | |||
To turn on a debug output of a service script set RC_DEBUG variable like this: | |||
<pre> | |||
~# RC_DEBUG=yes /etc/init.d/ourdaemon start | |||
</pre> | |||
This makes "set -x" for us. | |||
=== Variables reference === | === Variables reference === | ||
Line 64: | Line 151: | ||
* <code><span style="color: #026d45; font-weight: bold">command_args</span>="COMMAND LINE ARGUMENTS"</code> - command line arguments for our daemon. | * <code><span style="color: #026d45; font-weight: bold">command_args</span>="COMMAND LINE ARGUMENTS"</code> - command line arguments for our daemon. | ||
* <code><span style="color: #026d45; font-weight: bold">command_args_background</span>="COMMAND LINE ARGUMENTS"</code> - command line arguments for our daemon to background itself and/or to create a pid file. | * <code><span style="color: #026d45; font-weight: bold">command_args_background</span>="COMMAND LINE ARGUMENTS"</code> - command line arguments for our daemon to background itself and/or to create a pid file. | ||
* <code><span style="color: #026d45; font-weight: bold">command_background</span>=true</code> - tell start-stop-daemon to create a pid file and force a daemon into the background | * <code><span style="color: #026d45; font-weight: bold">command_background</span>=true</code> - tell start-stop-daemon to create a pid file and force a daemon into the background(if daemon can't do it itself). | ||
* <code><span style="color: #026d45; font-weight: bold">command_user</span>="USER:GROUP"</code> - tell start-stop-daemon to launch our daemon as specified user and group(:GROUP can be ommited). | * <code><span style="color: #026d45; font-weight: bold">command_user</span>="USER:GROUP"</code> - tell start-stop-daemon to launch our daemon as specified user and group(:GROUP can be ommited). | ||
* <code><span style="color: #026d45; font-weight: bold">description</span>="DESC TEXT"</code> - a text which is outputed on <code>/etc/init.d/SCRIPT describe</code> command. | * <code><span style="color: #026d45; font-weight: bold">description</span>="DESC TEXT"</code> - a text which is outputed on <code>/etc/init.d/SCRIPT describe</code> command. | ||
* <code><span style="color: #026d45; font-weight: bold">description_CMD</span>="CMD DESC TEXT"</code> - a text which is outputed on <code>/etc/init.d/SCRIPT describe</code> command as CMD extra command description. | * <code><span style="color: #026d45; font-weight: bold">description_CMD</span>="CMD DESC TEXT"</code> - a text which is outputed on <code>/etc/init.d/SCRIPT describe</code> command as CMD extra command description. | ||
* <code><span style="color: #026d45; font-weight: bold">directory</span>="PATH"</code> - a value is passed to start-stop-daemon --chdir option. | |||
* <code><span style="color: #026d45; font-weight: bold">extra_commands</span>="cmd1 cmd2 ..."</code> - add specified additional actions to a service script. | * <code><span style="color: #026d45; font-weight: bold">extra_commands</span>="cmd1 cmd2 ..."</code> - add specified additional actions to a service script. | ||
* <code><span style="color: #026d45; font-weight: bold">extra_started_commands</span>="cmd1 cmd2 ..."</code> - add specified additional actions to a service script, which are only valid while a daemon is running(started). | * <code><span style="color: #026d45; font-weight: bold">extra_started_commands</span>="cmd1 cmd2 ..."</code> - add specified additional actions to a service script, which are only valid while a daemon is running(started). | ||
* <code><span style="color: #026d45; font-weight: bold">extra_stopped_commands</span>="cmd1 cmd2 ..."</code> - add specified additional actions to a service script, which are only valid while a daemon is not running(stopped). | |||
* <code><span style="color: #026d45; font-weight: bold">name</span>="SERVICE_NAME"</code> - a service name used in messages that openrc output. By default equal to <code>RC_SVCNAME</code>. | * <code><span style="color: #026d45; font-weight: bold">name</span>="SERVICE_NAME"</code> - a service name used in messages that openrc output. By default equal to <code>RC_SVCNAME</code>. | ||
* <code><span style="color: #026d45; font-weight: bold">pidfile</span>="PATH_TO_PID"</code> - a full path to a pid file created by our daemon or start-stop-daemon(see command_background). | * <code><span style="color: #026d45; font-weight: bold">pidfile</span>="PATH_TO_PID"</code> - a full path to a pid file created by our daemon or start-stop-daemon(see command_background). | ||
Line 75: | Line 164: | ||
==== Openrc set for us ==== | ==== Openrc set for us ==== | ||
* <code>RC_CMD</code> - a command/action name(e.g. start/stop/status/etc). | * <code>RC_CMD</code> - a command/action name(e.g. start/stop/restart/status/etc). | ||
* <code>RC_RUNLEVEL</code> - a current runlevel. | |||
* <code>RC_SVCNAME</code> - a service script name(e.g. mydaemon.local). | * <code>RC_SVCNAME</code> - a service script name(e.g. mydaemon.local). | ||
* <code>RC_SERVICE</code> - a service script full path(e.g. /etc/init.d/mydaemon.local). | |||
=== Function reference === | |||
==== We set for openrc ==== | |||
* <code>'''depend()'''</code> - declare dependencies of a service | |||
* <code>'''start_pre()'''</code> - actions to do before a service start | |||
* <code>'''start()'''</code> - actions to start a service | |||
* <code>'''start_post()'''</code> - actions to do after a service start | |||
* <code>'''stop_pre()'''</code> - actions to do before a service stop | |||
* <code>'''stop()'''</code> - actions to stop a service | |||
* <code>'''stop_post()'''</code> - actions to do after a service stop | |||
==== Openrc set for us ==== | |||
* <code>'''ebegin''' "MSG"</code> - output an action message. | |||
* <code>'''eend''' EXIT_CODE</code> - output an action status (0 exit code is interpreted as success, !0 - as fail); a companion of ebegin. | |||
* <code>'''eerror''' "MSG"</code> - output error message | |||
* <code>'''eerrorn''' "MSG"</code> - output error message without newline at the end | |||
* <code>'''einfo''' "MSG"</code> - output info message | |||
* <code>'''einfon''' "MSG"</code> - output info message without newline at the end | |||
* <code>'''ewarn''' "MSG"</code> - output warning message | |||
* <code>'''ewarnn''' "MSG"</code> - output warning message without newline at the end | |||
== References == | |||
You can get more info about openrc internals from: | You can get more info about openrc internals from: | ||
* /usr/share/doc/openrc-*/* | |||
* /lib/rc/sh/openrc-run.sh | * /lib/rc/sh/openrc-run.sh | ||
* /lib/rc/sh/start-stop-daemon.sh | * /lib/rc/sh/start-stop-daemon.sh | ||
* /lib/rc/sh/* | * /lib/rc/sh/* |
Latest revision as of 09:45, November 20, 2020
Service script
Mini howto
Let's start to write our openrc service script(/etc/init.d/mydaemon
). The first line is:
#!/sbin/openrc-run
If we use another interpreter, then we may have troubles.
Next we add command
variable with our binary full path and the file is as follows:
#!/sbin/openrc-run command="/usr/sbin/mydaemon"
That's all. Now our binary specified in command
variable can be started with help of start-stop-daemon.
Next add description
variable to supply a user some info about the service:
description="super essential service"
And /etc/init.d/mydaemon describe
now shows us:
* super essential service * healthcheck: no description * unhealthy: no description * cgroup_cleanup: Kill all processes in the cgroup
Great. If our service create a pid file, then we should specify it full path with pidfile
variable:
pidfile="/var/run/mydaemon.pid"
This helps start-stop-daemon to detect an already running instance of mydaemon.
Next add additional arguments for our daemon with help of command_args
variable:
command_args="-c /etc/mydaemon.conf"
If we have special arguments to place the our daemon into the background(and/or force pidfile creation),
then we should place it in command_args_background
variable.
Next we can tell start-stop-daemon to launch our daemon as an unprivileged user/group with:
command_user="user:group"
Next add dependencies to our service script:
depend() { need localmount use logger }
If we need more services, for example, with need keyword, we can use several lines:
need localmount need net
or place they separated with spaces on a single line:
need localmount net
Where we can use the next keywords with service names separated with spaces:
- need - a hard dependency - localmount always needs to be started before this service does(if this service is restarted, then our service will be restarted too);
- use - a soft dependency - if logger is in this runlevel start it before, but we don't care if it's not in this runlevel;
- want - between need and use - try to start specified services if they are installed on the system, regardless of whether they are in the runlevel, but we don't care if they don't exist;
- before - our service need to be started before another services(if this service isn't exist or is placed to other runlevel, this settings has no effect);
- after - our service need to be started after another services(if this service isn't exist or is placed to other runlevel, this settings has no effect);
- provide - allows multiple implementations to provide one service type(e.g. "provide logger" - thus, any syslogd implementation satisties logger dependency);
- keyword - platform-specific overrides; see openrc docs for details.
Next add checking of a config file before daemon start:
checkconfig() { ... } start_pre() { checkconfig || return $? }
Also, we should check a config file on restart to prevent of restarting a running service with a broken config:
start_pre() { # Prevent of double check if [ "${RC_CMD}" != "restart" ] ; then checkconfig || return $? fi } stop_pre() { if [ "${RC_CMD}" = "restart" ] ; then checkconfig || return $? fi }
We done this check with help of start_pre()/stop_pre() because openrc convert restart action to a sequence of stop-start actions.
The complete service script is:
#!/sbin/openrc-run command="/usr/sbin/mydaemon" command_args="-c /etc/mydaemon.conf" command_user="user:group" description="super essential service" pidfile="/var/run/mydaemon.pid" depend() { need localmount use logger } checkconfig() { ... } start_pre() { # Prevent of double check if [ "${RC_CMD}" != "restart" ] ; then checkconfig || return $? fi } stop_pre() { if [ "${RC_CMD}" = "restart" ] ; then checkconfig || return $? fi }
Extra commands
To add additional commands we must tell openrc about it and define a function with such name:
extra_commands="cmd1" description_cmd1="do some additional action" cmd1() { ... }
Debug mode
To turn on a debug output of a service script set RC_DEBUG variable like this:
~# RC_DEBUG=yes /etc/init.d/ourdaemon start
This makes "set -x" for us.
Variables reference
We set for openrc
command="PATH_TO_BIN"
- a full path to binary we want to start/stop.command_args="COMMAND LINE ARGUMENTS"
- command line arguments for our daemon.command_args_background="COMMAND LINE ARGUMENTS"
- command line arguments for our daemon to background itself and/or to create a pid file.command_background=true
- tell start-stop-daemon to create a pid file and force a daemon into the background(if daemon can't do it itself).command_user="USER:GROUP"
- tell start-stop-daemon to launch our daemon as specified user and group(:GROUP can be ommited).description="DESC TEXT"
- a text which is outputed on/etc/init.d/SCRIPT describe
command.description_CMD="CMD DESC TEXT"
- a text which is outputed on/etc/init.d/SCRIPT describe
command as CMD extra command description.directory="PATH"
- a value is passed to start-stop-daemon --chdir option.extra_commands="cmd1 cmd2 ..."
- add specified additional actions to a service script.extra_started_commands="cmd1 cmd2 ..."
- add specified additional actions to a service script, which are only valid while a daemon is running(started).extra_stopped_commands="cmd1 cmd2 ..."
- add specified additional actions to a service script, which are only valid while a daemon is not running(stopped).name="SERVICE_NAME"
- a service name used in messages that openrc output. By default equal toRC_SVCNAME
.pidfile="PATH_TO_PID"
- a full path to a pid file created by our daemon or start-stop-daemon(see command_background).start_stop_daemon_args="EXTRA ARGS"
- pass extra arguments to start-stop-daemon.
Openrc set for us
RC_CMD
- a command/action name(e.g. start/stop/restart/status/etc).RC_RUNLEVEL
- a current runlevel.RC_SVCNAME
- a service script name(e.g. mydaemon.local).RC_SERVICE
- a service script full path(e.g. /etc/init.d/mydaemon.local).
Function reference
We set for openrc
depend()
- declare dependencies of a servicestart_pre()
- actions to do before a service startstart()
- actions to start a servicestart_post()
- actions to do after a service startstop_pre()
- actions to do before a service stopstop()
- actions to stop a servicestop_post()
- actions to do after a service stop
Openrc set for us
ebegin "MSG"
- output an action message.eend EXIT_CODE
- output an action status (0 exit code is interpreted as success, !0 - as fail); a companion of ebegin.eerror "MSG"
- output error messageeerrorn "MSG"
- output error message without newline at the endeinfo "MSG"
- output info messageeinfon "MSG"
- output info message without newline at the endewarn "MSG"
- output warning messageewarnn "MSG"
- output warning message without newline at the end
References
You can get more info about openrc internals from:
- /usr/share/doc/openrc-*/*
- /lib/rc/sh/openrc-run.sh
- /lib/rc/sh/start-stop-daemon.sh
- /lib/rc/sh/*