Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Assuming I have a shell script like this:-

#!/bin/sh
# cherrypy_server.sh

PROCESSES=10
THREADS=1 # threads per process
BASE_PORT=3035 # the first port used
# you need to make the PIDFILE dir and insure it has the right permissions
PIDFILE="/var/run/cherrypy/myproject.pid"
WORKDIR=`dirname "$0"`
cd "$WORKDIR"

cp_start_proc()
{
 N=$1
 P=$(( $BASE_PORT + $N - 1 ))
 ./manage.py runcpserver daemonize=1 port=$P pidfile="$PIDFILE-$N" threads=$THREADS request_queue_size=0 verbose=0
}

cp_start()
{
 for N in `seq 1 $PROCESSES`; do
  cp_start_proc $N
 done
}

cp_stop_proc()
{
 N=$1
 #[ -f "$PIDFILE-$N" ] && kill `cat "$PIDFILE-$N"`
 [ -f "$PIDFILE-$N" ] && ./manage.py runcpserver pidfile="$PIDFILE-$N" stop
 rm -f "$PIDFILE-$N"
}

cp_stop()
{
 for N in `seq 1 $PROCESSES`; do
  cp_stop_proc $N
 done
}

cp_restart_proc()
{
 N=$1
 cp_stop_proc $N
 #sleep 1
 cp_start_proc $N
}

cp_restart()
{
 for N in `seq 1 $PROCESSES`; do
  cp_restart_proc $N
 done
}

case "$1" in
 "start")
  cp_start
 ;;
 "stop")
  cp_stop
 ;;
 "restart")
  cp_restart
 ;;
 *)
  "$@"
 ;;
esac

From the bash script, we can essentially do 3 things:

  1. start the cherrypy server by calling ./cherrypy_server.sh start
  2. stop the cherrypy server by calling ./cherrypy_server.sh stop
  3. restart the cherrypy server by calling ./cherrypy_server.sh restart

How would I place this shell script under systemd's control as a cherrypy.service file (with the obvious goal of having systemd start up the cherrypy server when a machine has been rebooted)?

Reference systemd service file example here - https://wiki.archlinux.org/index.php/Systemd#Using_service_file

share|improve this question

1 Answer 1

up vote 3 down vote accepted

I use those for Sick Beard and SabNZBd, two python/cherrypy apps. The difference is knowing when to use 'forking'. That basically tells systemd that the main binary will fork stuff so it has to guess the PID from a file. WantedBy is just to define the target that will require this to start, think it as runlevel. You will notice also that the second definition uses a directory to keep run information, that's because it creates a $process-$port for each started daemon (you may have many daemons spawned by the main one on different ports).

IMO you can add the script on ExecStart and make sure that it is forking and add a way for it to find the main PIDfile, or at least a PIDfile that means 'if this is dead, restart the service'.

Maybe the ideal is to create 1 service file with 'simple' for each daemon?

[Unit]
Description=Internet PVR for your TV Shows
After=cryptsetup.target

[Service]
ExecStart=/usr/bin/python2 /path/to/Sick-Beard/SickBeard.py
Type=simple
User=<user under which to run>
Group=<group of said user>

[Install]
WantedBy=multi-user.target

And this one is the forking one

[Unit]
Description=Binary Newsreader
After=cryptsetup.target

[Service]
ExecStart=/usr/bin/python2 /path/to/sabnzbd/SABnzbd.py -d -f /path/to/inifile --pid /run/sabnzbd
Type=forking
PIDFile=/run/sabnzbd/sabnzbd-8080.pid
User=<user to run the process>
Group=<group of said user>

[Install]
WantedBy=multi-user.target
share|improve this answer
    
Thank you @coredump your code, configuration snippet/example really helps me understand systemd docs a lot better. Appreciate it! –  Calvin Cheng May 13 '12 at 4:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.