注意:

The Funtoo Linux project has transitioned to "Hobby Mode" and this wiki is now read-only.

Difference between revisions of "Openrc"

From Funtoo
Jump to navigation Jump to search
m
 
(14 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(<code>/etc/init.d/mydaemon</code>). The first line is:
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 18: Line 19:
description="super essential service"
description="super essential service"
</pre>
</pre>
And <code>/etc/init.d/mydaemon describe</code> now shows us:
And {{c|/etc/init.d/mydaemon describe}} now shows us:
<pre>
<pre>
  * super essential service
  * super essential service
Line 43: Line 44:
</pre>
</pre>


Next add some checks
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 55: 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 62: 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 by itself.
* <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">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).
* <code><span style="color: #026d45; font-weight: bold">start_stop_daemon_args</span>="EXTRA ARGS"</code> - pass extra arguments to start-stop-daemon.


==== 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:
* /usr/share/doc/openrc-*/*
* /lib/rc/sh/openrc-run.sh
* /lib/rc/sh/start-stop-daemon.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 to RC_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 service
  • start_pre() - actions to do before a service start
  • start() - actions to start a service
  • start_post() - actions to do after a service start
  • stop_pre() - actions to do before a service stop
  • stop() - actions to stop a service
  • stop_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 message
  • eerrorn "MSG" - output error message without newline at the end
  • einfo "MSG" - output info message
  • einfon "MSG" - output info message without newline at the end
  • ewarn "MSG" - output warning message
  • ewarnn "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/*