#!/bin/bash set -e set -u export APPSH_HOME=$(cd $(dirname "$0")/.. && pwd) . $APPSH_HOME/lib/common # HEADER END do_status() { if [ -z "$PID" ] then echo stopped else if [ `ps -p "$PID" 2>/dev/null | wc -l` -gt 1 ] then echo running else echo crashed fi fi } find_launcher() { local launcher=`app-conf get app.launcher` if [ ! -z "$launcher" ] then if [ ! -r "$launcher" ] then fatal "No such file: $launcher" >&2 fi else # Search for the launcher if [ -d bin ] then launcher=`grep_path ".*" bin` # This will happen if grep_path returns multiple files. # As we don't know which to choose, we'll fail. if [ ! -x "$launcher" ] then launcher="" fi fi fi if [[ $launcher == "" ]] then fatal "No launcher configured (app.launcher), could not find a single executable to run." >&2 fi if [[ ! -x $launcher ]] then fatal "Launcher not executable: $launcher" >&2 fi echo $launcher } find_pid_management() { pid_management=`app-conf get app.pid_management` if [[ $pid_management == "" ]] then echo "appsh" return fi case "$pid_management" in launcher) echo "$pid_management" ;; *) fatal "Invalid app.pid_management: $pid_management" ;; esac } command_start() { launcher=`find_launcher` pid_management=`find_pid_management` debug "launcher=$launcher" debug "pid_management=$pid_management" debug "pwd=`pwd`" case `do_status` in running) echo "The application is already running as $PID." exit 1 ;; esac export APPSH_HOME debug "Starting app..." $launcher <&- 1>&- 2>&- & PID=$! case "$pid_management" in appsh) echo "Application launched as $PID" echo $PID > $pid_file ;; launcher) launch_timeout=`app conf get app.launch_timeout` if [[ ! $launch_timeout =~ [0-9] ]] then launch_timeout=10 fi # the PID file is managed by the launcher, so wait for it to show up for ((x = 0; x < "$launch_timeout"; x++)) do echo "Waiting for PID to show up..." sleep 1 if [ -r $pid_file ] then return 0 fi done echo "Appliation failed to start" return 1 ;; esac return 0 } command_stop() { case `do_status` in stopped) echo "The application not running." return 1 ;; crashed) echo "The application crashed. Was running as $PID" # TODO: should this remove the PID file? That makes it # possible to run "stop" to stop "status" from showing # "crashed". Perhaps just a "clear" goal to clear the pid file. return 1 ;; esac echo -n "Sending TERM to $PID, waiting for shutdown" kill -TERM $PID for i in {1..10} do if [ "`do_status`" != "running" ] then PID= break fi sleep 1 echo -n . done if [[ $PID != "" ]] then echo "This is taking too long, sending KILL to $PID " kill -KILL $PID while [ "`do_status`" == "running" ] do sleep 1 echo -n . done fi echo " OK" rm -f $pid_file return 0 } command_status() { case `do_status` in running) echo "Running as $PID" ;; stopped) echo "Not running" ;; crashed) echo "Crashed. Was running as $PID" ;; esac } command_restart() { set +e command_stop set -e command_start } APP_HOME=${APP_HOME-} if [[ $APP_HOME == "" ]] then fatal "\$APP_HOME has to be set." fi pid_file=$APP_HOME/.app/pid PID= if [ -r $pid_file ] then PID="`cat $pid_file`" fi command="$1" case "$command" in start|stop|status|restart) command_$command ret=$? exit $ret ;; *) fatal "Invalid command: $command" ;; esac exit $?