Instalación del servidor CDO como servicio en Linux

De Document Product Lines wiki

Para instalar el servidor de CDO como servicio en Linux al inicio (usando SysV por ejemplo) se proporciona el script /etc/init.d/cdo.

Configuración

En un sistema compatible con Debian/GNU Linux el script abajo proporcionado se debe colocar en /etc/init.d/cdo, con permisos ejecutables.

Una vez el script se ha colocado, el servicio se puede iniciar/parar/reiniciar con los argumentos start/stop/restart. Por ejemplo:

$ /etc/init.d/cdo start
$ service cdo start

Para lanzar y parar el servicio con el arranque y apagado del sistema, se puede hacer uso del comando update-rc.d.

Para instalar el servicio basta ejecutar:

update-rc.d cdo defaults

Y para desinstalarlo:

update-rc.d cdo remove

NOTA: Para poder apagar el servicio de forma segura es necesario enviar el comando close a la consola OSGi del servidor. Al lanzarse el proceso cdo-server en background sólo es posible acceder a dicha consola si se lanza un servicio de escucha mediante telnet.

Atención: El script /etc/init.d/cdo abre un servicio telnet SIN AUTENTICACIÓN en el puerto 23.

Es necesario prohibir todas las conexiones a dicho puerto que no procedan de localhost.

Script: /etc/init.d/cdo

#! /bin/bash
# /etc/init.d/cdo
#

### BEGIN INIT INFO
# Provides:             cdo-server 1.1
# Required-Start:       $all
# Required-Stop:        $all
# Should-Start:         $syslog
# Should-Stop:          $syslog
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    DPLfw CDO server
### END INIT INFO


# This script starts and stops the CDO server in background, and attaches
# the OSGi console to port 23. The OSGi console can be controlled via telnet.

# Must be run after any other services to ensure
# that the server is able to create a connection

# Some things that run always

LOCK=/run/lock/cdo.pid
SVCDIR=/opt/cdo-server/linux.gtk.x86-1.1/eclipse/
FIFO=/run/lock/cdo.fifo

# Error codes
ERUNNING=10
ENORUNNING=20

echoerr() {
  echo "$@" 1>&2;
}

chkrunning() {
  if [ -e $LOCK ]; then
    # LOCK exists, check PID
    # Get saved PID
    PID=$(cat $LOCK)
    # Get nameof the binary running with pid $PID
    PROCPID=$(ps -p $PID -o comm --no-headers)
    # If process with pid $PID is cdo-server, the service is running
    if [ "$PROCPID" == "cdo-server" ]; then
      return $ERUNNING
    else
      return $ENORUNNING
    fi
  else
    # LOCK does not exist, not running
    return $ENORUNNING
  fi
}

dostart() {

  # AL CREATED FILES WIL BE ONLY ACCESIBLE BY ROOT
  umask 077
  ################################################

  cd $SVCDIR

  # Check if server is running
  chkrunning
  if [ $? -eq $ERUNNING  ]; then
    return $ERUNNING
  fi

  # At this point no other live instance of cdo-server
  # should hold the LOCK and the FIFO
  # However, this is not always true if an unexpected error
  # has ocurred.
  # If any other instance of the cdo service is still running,
  # the LOCK file will be reset and the FIFO disconnected

  # Unlink any existing FIFO silently
  # and create a new one
  unlink $FIFO > /dev/null 2>&1
  mkfifo $FIFO

  # Move to server dir (required to resolve config files)
  cd $SVCDIR

  # Start service in background
  $SVCDIR/cdo-server -console 23 > $FIFO 2>&1 &
  NEWPID=$!

  # Save the new PID to LOCK
  echo $NEWPID > $LOCK

  # Monitor server output from FIFO until server is loaded
  awk -v PID=$NEWPID '{
    print $0;
    if ($0 == "[INFO] CDO server started") {
      exit 0;
    } else if ($1 == "[ERROR]") {
      print "An error ocurred, killing process!";
      system("kill -9 " PID);
      exit 1;
    }
  }' $FIFO

  # The AWK command detected an error!
  if [ $? -ne 0 ]; then
    # If there are no instances of cdo-server running
    # (for example, the service failed to start when invoked by
    # rc.d boot scripts), delete the LOCK and the FIFO
    CDOSRVRUNNING=$(ps -C cdo-server)
    if [ $CDOSRVRUNNING ]; then
      rm -f $LOCK
      rm -f $FIFO
    fi
  fi

}

dostop() {

  # Check if server is running
  chkrunning
  if [ $? -eq $ERUNNING ]; then
      echo -e "\nclose" | telnet localhost &> /dev/null &
      cat $FIFO
      rm $LOCK
      unlink $FIFO
  else
    return $ENORUNNING
  fi
}

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    dostart
    if [ $? -eq $ERUNNING ]; then
      echoerr "CDO service already running!"
    fi
    ;;
  stop)
    dostop
    if [ $? -eq $ENORUNNING ]; then
      echoerr "CDO service not running!"
    fi
    ;;
  restart)
    dostop
    dostart
    ;;
  *)
    echo "Usage: /etc/init.d/cdo {start|stop|restart}"
    exit 1
    ;;
esac

exit 0