colocando o shell script sob o controle systemd

5

Supondo que eu tenha um script de shell como este: -

#!/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

A partir do script bash, podemos essencialmente fazer 3 coisas:

  1. inicie o servidor cherrypy chamando ./cherrypy_server.sh start
  2. pare o servidor cherrypy chamando ./cherrypy_server.sh stop
  3. reinicie o servidor cherrypy chamando ./cherrypy_server.sh restart

Como colocaria esse script de shell sob o controle systemd como um arquivo cherrypy.service (com o objetivo óbvio de ter o systemd inicializado o servidor cherrypy quando uma máquina foi reinicializada)?

Exemplo de arquivo de referência systemd service aqui - link

    
por Calvin Cheng 09.05.2012 / 10:11

1 resposta

6

Eu uso aqueles para Sick Beard e SabNZBd, dois aplicativos python / cherrypy. A diferença é saber quando usar 'forking'. Isso basicamente diz ao systemd que o binário principal irá bifurcar coisas, então ele tem que adivinhar o PID de um arquivo. WantedBy é apenas para definir o alvo que irá requerer isto para iniciar, pense nele como runlevel. Você também notará que a segunda definição usa um diretório para manter as informações de execução, isso porque cria um $process-$port para cada daemon iniciado (você pode ter muitos daemons gerados pelo principal em portas diferentes).

IMO você pode adicionar o script no ExecStart e certificar-se de que ele é forking e adicionar uma maneira de encontrar o arquivo PID principal, ou pelo menos um arquivo PID que significa "se estiver morto, reinicie o serviço".

Talvez o ideal seja criar um arquivo de serviço com 'simples' para cada 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

E este é o bifurcado

[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
    
por 12.05.2012 / 13:22