Difference between revisions of "Add a custom service"

From SME Server
Jump to navigationJump to search
 
(31 intermediate revisions by 3 users not shown)
Line 1: Line 1:
==Start a boot a custom service==
+
===Start at the boot time  a custom service===
  
 
If you want to start a custom service on the SME Server, you will have to follow some steps.
 
If you want to start a custom service on the SME Server, you will have to follow some steps.
The init script below is just a wrapper, a launcher that will start the real script which will do the job for you (see SCRIPT=<COMMAND> to give the path to your job script). Of course the init script is here only if you want to add a service by hand and thus not installed by a rpm.<br />
+
The init script below is just a wrapper, a launcher that will start the real script which will do the job for you '''(see SCRIPT=<COMMAND> to give the path to your job script)'''. Of course the init script is here only if you want to add a service by hand and thus not installed by a rpm.<br />
  
In the case of you have installed a service which comes from a rpm, but without init scripts in the runlevel 7, you have to follow from this  [[Add_a_custom_service#allow_a_service_to_start_for_a_particular_time |section]]
+
'''In the case of you have installed a service which comes from a rpm, but without init scripts in the runlevel 7, you have to follow from this  [[Add_a_custom_service#allow_a_service_to_start_for_a_particular_time |section]]'''
  
 
add a script to /etc/rc.d/init.d like the script below
 
add a script to /etc/rc.d/init.d like the script below
Line 20: Line 20:
 
  ### END INIT INFO
 
  ### END INIT INFO
 
   
 
   
  SCRIPT=<COMMAND>
+
  '''SCRIPT=<COMMAND>'''
  RUNAS=<USERNAME>
+
  '''RUNAS=<USERNAME>'''
  NAME=<SERVICE_NAME>
+
  '''NAME=<SERVICE_NAME>'''
 
   
 
   
 
  PIDFILE=/var/run/$NAME.pid
 
  PIDFILE=/var/run/$NAME.pid
Line 34: Line 34:
 
  echo 'Starting service…' >&2
 
  echo 'Starting service…' >&2
 
   local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
 
   local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
   su -c "$CMD" $RUNAS > "$PIDFILE"
+
   su -s /bin/sh $RUNAS -c "$CMD" > "$PIDFILE"
   echo 'Service started' >&2
+
 +
# Try with this command line instead of above if not workable
 +
# su -c "$CMD" $RUNAS > "$PIDFILE"
 +
 +
   sleep 2
 +
  PID=$(cat $PIDFILE)
 +
    if pgrep -u $RUNAS -f $NAME > /dev/null
 +
    then
 +
      echo "$NAME is now running, the PID is $PID"
 +
    else
 +
      echo "Error! Could not start $NAME!"
 +
    fi
 +
 
  }
 
  }
 
   
 
   
Line 48: Line 60:
 
  }
 
  }
 
   
 
   
uninstall() {
+
   status() {
   echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
 
  local SURE
 
  read SURE
 
  if [ "$SURE" = "yes" ]; then
 
stop
 
    rm -f "$PIDFILE"
 
    echo "Notice: log file is not be removed: '$LOGFILE'" >&2
 
    update-rc.d -f <NAME> remove
 
    rm -fv "$0"
 
  fi
 
}
 
 
status() {
 
 
         printf "%-50s" "Checking $NAME..."
 
         printf "%-50s" "Checking $NAME..."
 
     if [ -f $PIDFILE ]; then
 
     if [ -f $PIDFILE ]; then
PID=$(cat $PIDFILE)
+
        PID=$(cat $PIDFILE)
 
             if [ -z "$(ps axf | grep ${PID} | grep -v grep)" ]; then
 
             if [ -z "$(ps axf | grep ${PID} | grep -v grep)" ]; then
printf "%s\n" "The process appears to be dead but pidfile still exists"
+
                printf "%s\n" "The process appears to be dead but pidfile still exists"
 
             else
 
             else
echo "Running, the PID is $PID"
+
                echo "Running, the PID is $PID"
 
             fi
 
             fi
else
+
    else
printf "%s\n" "Service not running"
+
        printf "%s\n" "Service not running"
 
     fi
 
     fi
 
  }
 
  }
Line 85: Line 84:
 
   status)
 
   status)
 
     status
 
     status
    ;;
 
  uninstall)
 
    uninstall
 
 
     ;;
 
     ;;
 
   restart)
 
   restart)
Line 94: Line 90:
 
     ;;
 
     ;;
 
   *)
 
   *)
     echo "Usage: $0 {start|stop|status|restart|uninstall}"
+
     echo "Usage: $0 {start|stop|status|restart}"
 
  esac
 
  esac
  
Line 111: Line 107:
 
  chmod u+x /etc/rc.d/init.d/YOUR_SERVICE_NAME
 
  chmod u+x /etc/rc.d/init.d/YOUR_SERVICE_NAME
  
 +
====optional chkconfig====
 
You need to say to SME Server to add the script to each run level you have specified at the top of your init script( Default-Start: 2 3 4 5 and Default-Stop: 0 1 6 ). For Linux using rpm as centos or redhat, you can use
 
You need to say to SME Server to add the script to each run level you have specified at the top of your init script( Default-Start: 2 3 4 5 and Default-Stop: 0 1 6 ). For Linux using rpm as centos or redhat, you can use
  
 
  chkconfig YOUR_SERVICE_NAME --add
 
  chkconfig YOUR_SERVICE_NAME --add
 +
 +
You can set the levels where the initscript has to start
 +
chkconfig YOUR_SERVICE_NAME --level 2345 on
  
 
If you want to see which runlevel your script will run in
 
If you want to see which runlevel your script will run in
Line 124: Line 124:
  
  
However it is not enough for SME server since we have to add service to rc7.d and to say to our distro to start the service at boot, therefore let's go to the section below
+
{{Note box|However it is not enough for SME server since we have to add service to rc7.d to say to our distro to start the service at boot, therefore let's go to the section below}}
 
 
 
 
  
 
===allow a service to start for a particular time===
 
===allow a service to start for a particular time===
Line 145: Line 143:
 
  config set '''YOUR_SERVICE_NAME''' service status enabled
 
  config set '''YOUR_SERVICE_NAME''' service status enabled
  
if your init script is not already in etc/rc.d/init.d you can do a link to you the init script
+
:* IF your init script is not ALREADY in etc/rc.d/init.d you can do a link to the init script
 
  cd /etc/rc.d/init.d
 
  cd /etc/rc.d/init.d
 
  ln -s /path/to/myinitscript '''YOUR_SERVICE_NAME'''
 
  ln -s /path/to/myinitscript '''YOUR_SERVICE_NAME'''
Line 151: Line 149:
 
'''We are creating a symlink of the original startup script with a new name (the point is that '''YOUR_SERVICE_NAME''' must be identical to the service name above)'''
 
'''We are creating a symlink of the original startup script with a new name (the point is that '''YOUR_SERVICE_NAME''' must be identical to the service name above)'''
  
then in /etc/rc7.d we do a link to the wrapper e-smith-service
+
* In /etc/rc7.d we do a link to the wrapper e-smith-service
  
 
  cd /etc/rc7.d
 
  cd /etc/rc7.d
Line 194: Line 192:
 
  db configuration setprop <servicename> UDPPorts <portnumbers> # Ranges of ports are defined with a : not a -
 
  db configuration setprop <servicename> UDPPorts <portnumbers> # Ranges of ports are defined with a : not a -
 
  db configuration setprop <servicename> status enabled|disabled
 
  db configuration setprop <servicename> status enabled|disabled
  db configuration setprop <servicename> access public|private
+
  db configuration setprop <servicename> access public|private|localhost
 
  db configuration setprop <servicename> AllowHosts a.b.c.d,x.y.z.0/24
 
  db configuration setprop <servicename> AllowHosts a.b.c.d,x.y.z.0/24
 
  db configuration setprop <servicename> DenyHosts e.f.g.h,l.m.n.0/24
 
  db configuration setprop <servicename> DenyHosts e.f.g.h,l.m.n.0/24
Line 203: Line 201:
  
 
=== General Service Handling ===
 
=== General Service Handling ===
 +
SME Server uses [http://smarden.org/runit/ runit], a UNIX init scheme with service supervision. See the man page of [http://smarden.org/runit/sv.8.html the 'sv' command]
 +
 +
All other linux common way to start or stop services are also valuable
 +
 +
/etc/init.d/servicename start/stop/status
 +
service servicename start/stop/status
  
 
*start
 
*start
Line 210: Line 214:
 
*restart
 
*restart
 
  sv t /service/servicename
 
  sv t /service/servicename
 
+
* status
 +
sv s /service/servicename
 
{{tip box|you may use TAB to auto-complete your command line}}
 
{{tip box|you may use TAB to auto-complete your command line}}
  
All other linux common way to start or stop services are also valuable
+
you have some shortcuts
 
+
down => 'd',
  /etc/init.d/servicename start/stop/status
+
stop => 'd',
  service servicename start/stop/status
+
up => 'u',
 +
  start => 'u',
 +
restart => 't',
 +
sigterm => 't',
 +
adjust => 'h',
 +
reload => 'h',
 +
sighup => 'h',
 +
sigusr1 => '1',
 +
sigusr2 => '2',
 +
once => 'o',
 +
pause => 'p',
 +
alarm => 'a',
 +
interrupt => 'i',
 +
quit => 'q',
 +
kill => 'k',
 +
  exit => 'x',
  
 
====Example====  
 
====Example====  
Line 223: Line 243:
  
 
  sv t /service/httpd-e-smith
 
  sv t /service/httpd-e-smith
 
 
[[category:developer]]
 
[[category:developer]]

Latest revision as of 21:49, 19 July 2016

Start at the boot time a custom service

If you want to start a custom service on the SME Server, you will have to follow some steps. The init script below is just a wrapper, a launcher that will start the real script which will do the job for you (see SCRIPT=<COMMAND> to give the path to your job script). Of course the init script is here only if you want to add a service by hand and thus not installed by a rpm.

In the case of you have installed a service which comes from a rpm, but without init scripts in the runlevel 7, you have to follow from this section

add a script to /etc/rc.d/init.d like the script below

nano /etc/rc.d/init.d/YOUR_SERVICE_NAME
#!/bin/sh
### BEGIN INIT INFO
# Provides: <NAME>
# Required-Start: $local_fs $network $named $time $syslog
# Required-Stop: $local_fs $network $named $time $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: <DESCRIPTION>
### END INIT INFO

SCRIPT=<COMMAND>
RUNAS=<USERNAME>
NAME=<SERVICE_NAME>

PIDFILE=/var/run/$NAME.pid
LOGFILE=/var/log/$NAME.log

start() {
 if [ -f $PIDFILE ] && kill -0 $(cat $PIDFILE); then
echo 'Service already running' >&2
   return 1
 fi
echo 'Starting service…' >&2
 local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
 su -s /bin/sh $RUNAS -c "$CMD" > "$PIDFILE"

# Try with this command line instead of above if not workable
# su -c "$CMD" $RUNAS > "$PIDFILE"

 sleep 2
 PID=$(cat $PIDFILE)
   if pgrep -u $RUNAS -f $NAME > /dev/null
   then
     echo "$NAME is now running, the PID is $PID"
   else
     echo "Error! Could not start $NAME!"
   fi

}

stop() {
 if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
echo 'Service not running' >&2
   return 1
 fi
echo 'Stopping service…' >&2
 kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
 echo 'Service stopped' >&2
}

 status() {
       printf "%-50s" "Checking $NAME..."
   if [ -f $PIDFILE ]; then
       PID=$(cat $PIDFILE)
           if [ -z "$(ps axf | grep ${PID} | grep -v grep)" ]; then
               printf "%s\n" "The process appears to be dead but pidfile still exists"
           else
               echo "Running, the PID is $PID"
           fi
   else
       printf "%s\n" "Service not running"
   fi
}


case "$1" in
 start)
   start
   ;;
 stop)
   stop
   ;;
 status)
   status
   ;;
 restart)
   stop
   start
   ;;
 *)
   echo "Usage: $0 {start|stop|status|restart}"
esac

you have to fill these fields with the relevant values

# Provides: <NAME>
..
# Description: <DESCRIPTION>
..
SCRIPT=<COMMAND> #path to the script you want to start automatically at boot
RUNAS=<USERNAME> #user who run the script (can be root or other choice)
NAME=<YOUR_SERVICE_NAME> #name of the service.

make that script executable

chmod u+x /etc/rc.d/init.d/YOUR_SERVICE_NAME

optional chkconfig

You need to say to SME Server to add the script to each run level you have specified at the top of your init script( Default-Start: 2 3 4 5 and Default-Stop: 0 1 6 ). For Linux using rpm as centos or redhat, you can use

chkconfig YOUR_SERVICE_NAME --add

You can set the levels where the initscript has to start

chkconfig YOUR_SERVICE_NAME --level 2345 on

If you want to see which runlevel your script will run in

chkconfig YOUR_SERVICE_NAME --list

example :

# chkconfig dhcp-dns --list
dhcp-dns       	0:arrêt	1:arrêt	2:marche	3:marche	4:marche	5:marche	6:arrêt


Important.png Note:
However it is not enough for SME server since we have to add service to rc7.d to say to our distro to start the service at boot, therefore let's go to the section below


allow a service to start for a particular time

If your package implements a server or daemon, you will probably want it to be started automatically when the system boots. The SME Server boots in runlevel 7, so you can get an idea of the startup processes by listing the contents of /etc/rc.d/rc7.d.

These are similar to the init scripts you may be familiar with from other Linux systems, with one important difference. Instead of pointing to scripts within /etc/rc.d/init.d, all of those init entries are links to /etc/rc.d/init.d/e-smith-service. This is a wrapper which checks the configuration database to see if the service is supposed to be running and if so, starts the service from /etc/rc.d/init.d/whatever.

So for example, you might have:

S90squid -> /etc/rc.d/init.d/e-smith-service

The e-smith-service script looks up the name it was invoked with (S90squid), drops the prefix (leaving squid), checks the configuration database for the "squid" service, then if it's supposed to run, does:

/etc/rc.d/init.d/squid start
  • with this way SME's knows how to/if start the service at startup
config set YOUR_SERVICE_NAME service status enabled
  • IF your init script is not ALREADY in etc/rc.d/init.d you can do a link to the init script
cd /etc/rc.d/init.d
ln -s /path/to/myinitscript YOUR_SERVICE_NAME

We are creating a symlink of the original startup script with a new name (the point is that YOUR_SERVICE_NAME must be identical to the service name above)

  • In /etc/rc7.d we do a link to the wrapper e-smith-service
cd /etc/rc7.d
ln -s  /etc/rc.d/init.d/e-smith-service SXXYOUR_SERVICE_NAME

we create a symlink to e-smith-service startup script with a name where: S tells SME to start XX are numbers

You can decide when to start the service YOUR_SERVICE_NAME, but you should not start something that need the network before the network itself is up and running. Therefore you can see the content of /etc/rc7.d and see which scripts are needed to execute your new startup script

signal-event remoteaccess-update
service YOUR_SERVICE_NAME start

Creating or deleting a service

Some examples

  • Creating and starting service
ln -f -s /etc/rc.d/init.d/e-smith-service /etc/rc7.d/S98popfile
/sbin/e-smith/db configuration set popfile service status enabled
/sbin/e-smith/signal-event remoteaccess-update
service popfile start
  • Deleting and unregistering service
service popfile stop
sleep 3
rm -f /etc/rc7.d/S98popfile
rm -f /etc/rc.d/init.d/popfile
/sbin/e-smith/config delete popfile
/sbin/e-smith/signal-event remoteaccess-update

Create a service with db command and set network access

DB_Variables_Configuration#Additional_information_on_customizing_iptables

Create a custom-named service definition in the configuration database.

db configuration set <servicename> service

Apply your desired firewall restrictions to any existing SME 'service' or to a custom-named service that you have created. Combine a custom-named service with port-forwarding to create customized firewall rules.

db configuration setprop <servicename> TCPPort <portnumber>
db configuration setprop <servicename> TCPPorts <portnumbers> # Ranges of ports are defined with a : not a -
db configuration setprop <servicename> UDPPort <portnumber>
db configuration setprop <servicename> UDPPorts <portnumbers> # Ranges of ports are defined with a : not a -
db configuration setprop <servicename> status enabled|disabled
db configuration setprop <servicename> access public|private|localhost
db configuration setprop <servicename> AllowHosts a.b.c.d,x.y.z.0/24
db configuration setprop <servicename> DenyHosts e.f.g.h,l.m.n.0/24


Effectuate the changes you have made

signal-event remoteaccess-update

General Service Handling

SME Server uses runit, a UNIX init scheme with service supervision. See the man page of the 'sv' command

All other linux common way to start or stop services are also valuable

/etc/init.d/servicename start/stop/status
service servicename start/stop/status
  • start
sv u /service/servicename
  • stop
sv d /service/servicename
  • restart
sv t /service/servicename
  • status
sv s /service/servicename
Information.png Tip:
you may use TAB to auto-complete your command line


you have some shortcuts

down => 'd',
stop => 'd',
up => 'u',
start => 'u',
restart => 't',
sigterm => 't',
adjust => 'h',
reload => 'h',
sighup => 'h',
sigusr1 => '1',
sigusr2 => '2',
once => 'o',
pause => 'p',
alarm => 'a',
interrupt => 'i',
quit => 'q',
kill => 'k',
exit => 'x',

Example

Restarting:

sv t /service/httpd-e-smith