Переделать скрипт установки демона под Debian

Knoppix

Модераторы: Warderer, Модераторы разделов

lordtao
Сообщения: 6

Переделать скрипт установки демона под Debian

Сообщение lordtao »

Добрый день всем!

Помогите новичку переделать скрипт инсталляции, запуска и остановки демона под Debian. Программа написана мною на Java и с ней проблем нет. Скрипт я нашел, но он не работает под Debian. Не работает из-за различий SUSE Linux. Помогите разобраться плиз.

Код: Выделить всё

#!/bin/sh
#
# A SUSE Linux start/stop script for Java daemons.
#
# Home page: [url="http://www.source-code.biz"]http://www.source-code.biz[/url]
# License:   GNU/LGPL V2.1 (http://www.gnu.org/licenses/lgpl.html)
# Copyright 2006 Christian d'Heureuse, Inventec Informatik AG, Switzerland.
#
# History:
# 2006-06-27 Christian d'Heureuse: Script created.
# 2006-07-02 chdh: Minor improvements.
# 2006-07-10 chdh: Changes for SUSE 10.0.
# 2009-08-21 chdh: Changes for SUSE 11.1.
#   (The name of the Java binary reported by "ps -o comm" may be "java.bin" instead of "java")
# 2009-09-16 chdh: nohup replaced by setsid.

### BEGIN INIT INFO
# Provides:                   javaDaemonTest
# Required-Start:             $network $local_fs $remote_fs
# X-UnitedLinux-Should-Start: $named sendmail
# Required-Stop:              $network $local_fs $remote_fs
# X-UnitedLinux-Should-Stop:  $named sendmail
# Default-Start:              3 5
# Default-Stop:               0 1 2 6
# Short-Description:          JavaDaemonTest
# Description:                A Java daemon for testing.
### END INIT INFO

. /etc/rc.status                                           # load start/stop script "rc" definitions
if [ -z "$JAVA_HOME" ]; then                               # if JAVA_HOME is undefined
   if [ -f /usr/share/java-utils/java-functions ]; then
      . /usr/share/java-utils/java-functions; set_jvm      # JPackage standard method to set JAVA_HOME
    elif [ -n "$(type -t setJava)" ]; then
      . setJava ""; fi                                     # old SUSE method to set JAVA_HOME
   if [ -z "$JAVA_HOME" ]; then echo Unable to set JAVA_HOME environment variable; exit 1; fi
   fi

scriptFile=$(readlink -fn $(type -p $0))                   # the absolute, dereferenced path of this script file
scriptDir=$(dirname $scriptFile)                           # absolute path of the script directory
applDir="$scriptDir"                                       # home directory of the service application
serviceName="JavaDaemonTest"                               # service name
serviceNameLo="javaDaemonTest"                             # service name with the first letter in lowercase
serviceUser="jdmntest"                                     # OS user name for the service
serviceUserHome="$applDir"                                 # home directory of the service user
serviceGroup="jdmntest"                                    # OS group name for the service
serviceLogFile="/var/log/$serviceNameLo.log"               # log file for StdOut/StdErr
maxShutdownTime=15                                         # maximum number of seconds to wait for the daemon to terminate normally
pidFile="/var/run/$serviceNameLo.pid"                      # name of PID file (PID = process ID number)
javaCommand="java"                                         # name of the Java launcher without the path
javaExe="$JAVA_HOME/bin/$javaCommand"                      # file name of the Java application launcher executable
javaArgs="JavaDaemonTest"                                  # arguments for Java launcher
javaCommandLine="$javaExe $javaArgs"                       # command line to start the Java service application
javaCommandLineKeyword="JavaDaemonTest"                    # a keyword that occurs on the commandline, used to detect an already running service process and to distinguish it from others
rcFileBaseName="rc$serviceNameLo"                          # basename of the "rc" symlink file for this script
rcFileName="/usr/local/sbin/$rcFileBaseName"               # full path of the "rc" symlink file for this script
etcInitDFile="/etc/init.d/$serviceNameLo"                  # symlink to this script from /etc/init.d

# Makes the file $1 writable by the group $serviceGroup.
function makeFileWritable {
   local filename="$1"
   touch $filename || return 1
   chgrp $serviceGroup $filename || return 1
   chmod g+w $filename || return 1
   return 0; }

# Returns 0 if the process with PID $1 is running.
function checkProcessIsRunning {
   local pid="$1"
   if [ -z "$pid" -o "$pid" == " " ]; then return 1; fi
   if [ ! -e /proc/$pid ]; then return 1; fi
   return 0; }

# Returns 0 if the process with PID $1 is our Java service process.
function checkProcessIsOurService {
   local pid="$1"
   local cmd="$(ps -p $pid --no-headers -o comm)"
   if [ "$cmd" != "$javaCommand" -a "$cmd" != "$javaCommand.bin" ]; then return 1; fi
   grep -q --binary -F "$javaCommandLineKeyword" /proc/$pid/cmdline
   if [ $? -ne 0 ]; then return 1; fi
   return 0; }

# Returns 0 when the service is running and sets the variable $servicePid to the PID.
function getServicePid {
   if [ ! -f $pidFile ]; then return 1; fi
   servicePid="$(<$pidFile)"
   checkProcessIsRunning $servicePid || return 1
   checkProcessIsOurService $servicePid || return 1
   return 0; }

function startServiceProcess {
   cd $applDir || return 1
   rm -f $pidFile
   makeFileWritable $pidFile || return 1
   makeFileWritable $serviceLogFile || return 1
   local cmd="setsid $javaCommandLine >>$serviceLogFile 2>&1 & echo \$! >$pidFile"
   sudo -u $serviceUser $SHELL -c "$cmd" || return 1
   sleep 0.1
   servicePid="$(<$pidFile)"
   if checkProcessIsRunning $servicePid; then :; else
      echo -ne "\n$serviceName start failed, see logfile."
      return 1
      fi
   return 0; }

function stopServiceProcess {
   kill $servicePid || return 1
   for ((i=0; i<maxShutdownTime*10; i++)); do
      checkProcessIsRunning $servicePid
      if [ $? -ne 0 ]; then
         rm -f $pidFile
         return 0
         fi
      sleep 0.1
      done
   echo -e "\n$serviceName did not terminate within $maxShutdownTime seconds, sending SIGKILL..."
   kill -s KILL $servicePid || return 1
   local killWaitTime=15
   for ((i=0; i<killWaitTime*10; i++)); do
      checkProcessIsRunning $servicePid
      if [ $? -ne 0 ]; then
         rm -f $pidFile
         return 0
         fi
      sleep 0.1
      done
   echo "Error: $serviceName could not be stopped within $maxShutdownTime+$killWaitTime seconds!"
   return 1; }

function runInConsoleMode {
   getServicePid
   if [ $? -eq 0 ]; then echo "$serviceName is already running"; return 1; fi
   cd $applDir || return 1
   sudo -u $serviceUser $javaCommandLine || return 1
   if [ $? -eq 0 ]; then return 1; fi
   return 0; }

function startService {
   getServicePid
   if [ $? -eq 0 ]; then echo -n "$serviceName is already running"; rc_failed 0; rc_status -v; return 0; fi
   echo -n "Starting $serviceName   "
   startServiceProcess
   if [ $? -ne 0 ]; then rc_failed 1; rc_status -v; return 1; fi
   rc_failed 0
   rc_status -v
   return 0; }

function stopService {
   getServicePid
   if [ $? -ne 0 ]; then echo -n "$serviceName is not running"; rc_failed 0; rc_status -v; return 0; fi
   echo -n "Stopping $serviceName   "
   stopServiceProcess
   if [ $? -ne 0 ]; then rc_failed 1; rc_status -v; return 1; fi
   rc_failed 0
   rc_status -v
   return 0; }

function checkServiceStatus {
   echo -n "Checking for $serviceName:   "
   if getServicePid; then
      rc_failed 0
    else
      rc_failed 3
      fi
   rc_status -v
   return 0; }

function installService {
   getent group $serviceGroup >/dev/null 2>&1
   if [ $? -ne 0 ]; then
      echo Creating group $serviceGroup
      groupadd -r $serviceGroup || return 1
      fi
   id -u $serviceUser >/dev/null 2>&1
   if [ $? -ne 0 ]; then
      echo Creating user $serviceUser
      useradd -r -c "user for $serviceName service" -g $serviceGroup -G users -d $serviceUserHome $serviceUser
      fi
   ln -s $scriptFile $rcFileName || return 1
   ln -s $scriptFile $etcInitDFile || return 1
   insserv $serviceNameLo || return 1
   echo $serviceName installed.
   echo You may now use $rcFileBaseName to call this script.
   return 0; }

function uninstallService {
   insserv -r $serviceNameLo || return 1
   rm -f $rcFileName
   rm -f $etcInitDFile
   echo $serviceName uninstalled.
   return 0; }

function main {
   rc_reset
   case "$1" in
      console)                                             # runs the Java program in console mode
         runInConsoleMode
        ;;
      start)                                               # starts the Java program as a Linux service
         startService
        ;;
      stop)                                                # stops the Java program service
         stopService
        ;;
      restart)                                             # stops and restarts the service
         stopService && startService
        ;;
      status)                                              # displays the service status
         checkServiceStatus
        ;;
      install)                                             # installs the service in the OS
         installService
        ;;
      uninstall)                                           # uninstalls the service in the OS
         uninstallService
        ;;
      *)
         echo "Usage: $0 {console|start|stop|restart|status|install|uninstall}"
         exit 1
        ;;
      esac
   rc_exit; }

main $1
Спасибо сказали:
Аватара пользователя
Uzix
Сообщения: 45
ОС: Debian Sid

Re: Переделать скрипт установки демона под Debian

Сообщение Uzix »

Выложите сюда вывод скрипта при попытке запуска
Runtime error 200 at 0708:07C7
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Переделать скрипт установки демона под Debian

Сообщение IMB »

Используйте как основу /etc/init.d/skeleton и напишите свой.
Спасибо сказали:
lordtao
Сообщения: 6

Re: Переделать скрипт установки демона под Debian

Сообщение lordtao »

Uzix писал(а):
05.02.2010 14:33
Выложите сюда вывод скрипта при попытке запуска

После попытки инсталляции при запуске пишет:
s:/usr/local/msrv# sh jd.sh start
readlink: missing operand
Try `readlink --help' for more information.
dirname: missing operand
Try `dirname --help' for more information.
Starting JavaMobileServer
JavaMobileServer start failed, see logfile. failed
s:/usr/local/msrv#


в лог файл записывается следующее:

execvp: No such file or directory
execvp: No such file or directory
execvp: No such file or directory
execvp: No such file or directory
Спасибо сказали:
Аватара пользователя
Uzix
Сообщения: 45
ОС: Debian Sid

Re: Переделать скрипт установки демона под Debian

Сообщение Uzix »

После попытки инсталляции при запуске пишет:
s:/usr/local/msrv# sh jd.sh start
readlink: missing operand
Try `readlink --help' for more information.
dirname: missing operand
Try `dirname --help' for more information.
Starting JavaMobileServer
JavaMobileServer start failed, see logfile. failed
s:/usr/local/msrv#

Странно, что ругается на readlink - а на rc.status не ругается

в лог файл записывается следующее:

execvp: No such file or directory
execvp: No such file or directory
execvp: No such file or directory
execvp: No such file or directory

По всей видимости это происходит в функции startServiceProcess:

Код: Выделить всё

   local cmd="setsid $javaCommandLine >>$serviceLogFile 2>&1 & echo \$! >$pidFile"
   sudo -u $serviceUser $SHELL -c "$cmd" || return 1

Раскрывая переменные, получим:

Код: Выделить всё

sudo -u jdmntest /bin/bash -c "setsid java JavaDaemonTest >>/var/log/JavaDaemonTest.log 2>&1 & echo \$! >/var/run/JavaDaemonTest.pid"

Попробуйте запустить это
Runtime error 200 at 0708:07C7
Спасибо сказали:
lordtao
Сообщения: 6

Re: Переделать скрипт установки демона под Debian

Сообщение lordtao »

Uzix писал(а):
05.02.2010 22:42
После попытки инсталляции при запуске пишет:
s:/usr/local/msrv# sh jd.sh start
readlink: missing operand
Try `readlink --help' for more information.
dirname: missing operand
Try `dirname --help' for more information.
Starting JavaMobileServer
JavaMobileServer start failed, see logfile. failed
s:/usr/local/msrv#

Странно, что ругается на readlink - а на rc.status не ругается

в лог файл записывается следующее:

execvp: No such file or directory
execvp: No such file or directory
execvp: No such file or directory
execvp: No such file or directory

По всей видимости это происходит в функции startServiceProcess:

Код: Выделить всё

   local cmd="setsid $javaCommandLine >>$serviceLogFile 2>&1 & echo \$! >$pidFile"
   sudo -u $serviceUser $SHELL -c "$cmd" || return 1

Раскрывая переменные, получим:

Код: Выделить всё

sudo -u jdmntest /bin/bash -c "setsid java JavaDaemonTest >>/var/log/JavaDaemonTest.log 2>&1 & echo \$! >/var/run/JavaDaemonTest.pid"

Попробуйте запустить это

В ответ получаю
s:/usr/local/msrv# sh jd.sh start
readlink: missing operand
Try `readlink --help' for more information.
dirname: missing operand
Try `dirname --help' for more information.
Starting JavaMobileServer /bin/bash: /var/run/JavaMobileServer.pid: Permission
denied

JavaMobileServer start failed, see logfile. failed
Спасибо сказали:
Аватара пользователя
Uzix
Сообщения: 45
ОС: Debian Sid

Re: Переделать скрипт установки демона под Debian

Сообщение Uzix »

Starting JavaMobileServer /bin/bash: /var/run/JavaMobileServer.pid: Permission denied

Очевидно, не хватает прав для записи в /var/run/.
Набросал скрипт, пробуйте....

Код: Выделить всё

#!/bin/sh

### BEGIN INIT INFO
# Provides:          javaDaemonTest
# Required-Start:    $network $remote_fs $syslog
# Required-Stop:     $network $remote_fs $syslog
# Should-Start:
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: JavaDaemonTest
# Description:       A Java daemon for testing.
### END INIT INFO

. /lib/lsb/init-functions

PIDFILE="/var/run/JavaDaemonTest.pid"
LOGFILE="/var/log/JavaDaemonTest.log"
NAME=java
DESC="A Java daemon for testing"
DAEMON="/usr/bin/java"
OPTS="-classpath ./ JavaDaemonTest"
USER="jdmntest"
GROUP="jdmntest"

test -x "$DAEMON" ] || exit 2

do_start () {
    log_daemon_msg "Starting $DESC" "$NAME"
    start-stop-daemon --start --quiet --oknodo --pidfile "$PIDFILE" \
        --user "$USER" --group "$GROUP" --exec "$DAEMON" -- $OPTS >> "$LOGFILE"
    log_end_msg $?
}

do_stop () {
    log_daemon_msg "Stopping $DESC" "$NAME"
    start-stop-daemon --stop --quiet --oknodo --retry 5 --pidfile "$PIDFILE" \
        --exec "$DAEMON"
    log_end_msg $?
}


case "$1" in
  start)
     do_start || exit 1
;;
  stop)
     do_stop || exit 1
;;
  force-reload|restart)
     do_stop && sleep 1
     do_start || exit 1
;;
  *)
     echo "Usage: $0 {start|stop|restart}"
     exit 1
esac

exit 0

в строке "OPTS="-classpath ./ JavaDaemonTest"" вместо ./ подставьте полный путь до папки с программой
Runtime error 200 at 0708:07C7
Спасибо сказали:
lordtao
Сообщения: 6

Re: Переделать скрипт установки демона под Debian

Сообщение lordtao »

Yе запускается. Пишет:

Starting Java Daemon for mobile server: javastart-stop-daemon: stat java: No such file or directory (No such file or directory)
failed!

У меня есть сомненья в самой строке запуске программы. Запускаться java приложение в обычном режиме должно так:
java -jar msrv.jar
Поэтому я немного переделал скрипт и подставил реальные названия. Может в этом ошибка? В аттаче я добавил простую
java программку которая висит и слушает 8090 порт (для тестирования если нужно).

Код: Выделить всё

#!/bin/sh

### BEGIN INIT INFO
# Provides:          msrv
# Required-Start:    $network $remote_fs $syslog
# Required-Stop:     $network $remote_fs $syslog
# Should-Start:
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: msrv
# Description:       Mobile service.
### END INIT INFO

. /lib/lsb/init-functions

PNAME="msrv"
PIDFILE="/var/run/$PNAME.pid"
LOGFILE="/var/log/$PNAME.log"
NAME=java
DESC="Java Daemon for mobile server"
DAEMON="java"
OPTS=" -jar $PNAME.java"
USER="jmsrv"
GROUP="jmsrv"

#test -x "$DAEMON" ] || exit 2

do_check () {
    getent group $serviceGroup >/dev/null 2>&1
   if [ $? -ne 0 ]; then
      echo Creating group $serviceGroup
      groupadd -r $serviceGroup || return 1
      fi
   id -u $serviceUser >/dev/null 2>&1
   if [ $? -ne 0 ]; then
      echo Creating user $serviceUser
      useradd -r -c "user for $serviceName service" -g $serviceGroup -G users -d $serviceUserHome $serviceUser
      fi
}

do_start () {
    log_daemon_msg "Starting $DESC" "$NAME"
    start-stop-daemon --start --quiet --oknodo --pidfile "$PIDFILE" \
        --user "$USER" --group "$GROUP" --exec "$DAEMON" -- $OPTS >> "$LOGFILE"
    log_end_msg $?
}

do_stop () {
    log_daemon_msg "Stopping $DESC" "$NAME"
    start-stop-daemon --stop --quiet --oknodo --retry 5 --pidfile "$PIDFILE" \
        --exec "$DAEMON"
    log_end_msg $?
}

do_check

case "$1" in
  start)
     do_start || exit 1
;;
  stop)
     do_stop || exit 1
;;
  force-reload|restart)
     do_stop && sleep 1
     do_start || exit 1
;;
  *)
     echo "Usage: $0 {start|stop|restart}"
     exit 1
esac

exit 0
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
Аватара пользователя
Uzix
Сообщения: 45
ОС: Debian Sid

Re: Переделать скрипт установки демона под Debian

Сообщение Uzix »

Starting Java Daemon for mobile server: javastart-stop-daemon: stat java: No such file or directory (No such file or directory)
failed!

DAEMON="java" заменить на DAEMON=/usr/bin/java
У меня есть сомненья в самой строке запуске программы. Запускаться java приложение в обычном режиме должно так:
java -jar msrv.jar

Вам виднее - если приложение скомпоновано в jar - то да. Иначе, как в исходном OpenSuse-скрипте - через указание запускаемого класса и директорий поиска этих классов.
Runtime error 200 at 0708:07C7
Спасибо сказали:
lordtao
Сообщения: 6

Re: Переделать скрипт установки демона под Debian

Сообщение lordtao »

Uzix писал(а):
08.02.2010 19:53
Starting Java Daemon for mobile server: javastart-stop-daemon: stat java: No such file or directory (No such file or directory)
failed!

DAEMON="java" заменить на DAEMON=/usr/bin/java
У меня есть сомненья в самой строке запуске программы. Запускаться java приложение в обычном режиме должно так:
java -jar msrv.jar

Вам виднее - если приложение скомпоновано в jar - то да. Иначе, как в исходном OpenSuse-скрипте - через указание запускаемого класса и директорий поиска этих классов.


DAEMON заменил. Кроме того нашел ошибку и исправил
OPTS=" -jar $PNAME.jar"

Вот что у меня получается - это попытка скрипт запустить:

s:/usr/local/msrv# ./msrv.sh start
Starting Java Daemon for mobile server: javaUnable to access jarfile msrv.jar
failed!

Это запуск без скрипта (все работает):

s:/usr/local/msrv# java -jar msrv.jar
2010-02-09 16:52:59 JavaDaemonTest started
2010-02-09 16:52:59 This is output to StdErr...
2010-02-09 16:53:00 running...
Feb 9, 2010 4:53:00 PM msrv.Server run
INFO: Start
Спасибо сказали:
Аватара пользователя
Uzix
Сообщения: 45
ОС: Debian Sid

Re: Переделать скрипт установки демона под Debian

Сообщение Uzix »

s:/usr/local/msrv# ./msrv.sh start
Starting Java Daemon for mobile server: javaUnable to access jarfile msrv.jar
failed!

Убедитесь, что у группы или пользователя jmsrv есть права на чтение.
Runtime error 200 at 0708:07C7
Спасибо сказали:
lordtao
Сообщения: 6

Re: Переделать скрипт установки демона под Debian

Сообщение lordtao »

Uzix писал(а):
09.02.2010 20:54
s:/usr/local/msrv# ./msrv.sh start
Starting Java Daemon for mobile server: javaUnable to access jarfile msrv.jar
failed!

Убедитесь, что у группы или пользователя jmsrv есть права на чтение.


s:/usr/local/msrv# ls -li
total 16
4982349 -rwxr-xr-x 1 root staff 8469 Feb 9 17:27 msrv.jar
4983720 -rwxr-xr-x 1 root staff 1711 Feb 9 17:01 msrv.sh
s:/usr/local/msrv#
Спасибо сказали: