234 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
#!/bin/bash
 | 
						|
#
 | 
						|
 | 
						|
 | 
						|
### BEGIN INIT INFO
 | 
						|
# Provides:          ${pkg.name}
 | 
						|
# Required-Start:    $remote_fs $syslog $network
 | 
						|
# Required-Stop:     $remote_fs $syslog $network
 | 
						|
# Default-Start:     2 3 4 5
 | 
						|
# Default-Stop:      0 1 6
 | 
						|
# Short-Description: ${project.name}
 | 
						|
# Description:       ${project.description}
 | 
						|
# chkconfig:         2345 99 01
 | 
						|
### END INIT INFO
 | 
						|
 | 
						|
[[ -n "$DEBUG" ]] && set -x
 | 
						|
 | 
						|
# Initialize variables that cannot be provided by a .conf file
 | 
						|
WORKING_DIR="$(pwd)"
 | 
						|
# shellcheck disable=SC2153
 | 
						|
 | 
						|
mainfile=${pkg.installFolder}/bin/${pkg.name}
 | 
						|
configfile=${pkg.name}.conf
 | 
						|
 | 
						|
# Follow symlinks to find the real script and detect init.d script
 | 
						|
cd "$(dirname "$0")" || exit 1
 | 
						|
[[ -z "$initfile" ]] && initfile=$(pwd)/$(basename "$0")
 | 
						|
while [[ -L "$initfile" ]]; do
 | 
						|
  [[ "$initfile" =~ init\.d ]] && init_script=$(basename "$initfile")
 | 
						|
  initfile=$(readlink "$initfile")
 | 
						|
  cd "$(dirname "$initfile")" || exit 1
 | 
						|
  initfile=$(pwd)/$(basename "$initfile")
 | 
						|
done
 | 
						|
initfolder="$( (cd "$(dirname "initfile")" && pwd -P) )"
 | 
						|
cd "$WORKING_DIR" || exit 1
 | 
						|
 | 
						|
# Initialize CONF_FOLDER location
 | 
						|
[[ -z "$CONF_FOLDER" ]] && CONF_FOLDER="${pkg.installFolder}/conf"
 | 
						|
 | 
						|
# shellcheck source=/dev/null
 | 
						|
[[ -r "${CONF_FOLDER}/${configfile}" ]] && source "${CONF_FOLDER}/${configfile}"
 | 
						|
 | 
						|
# Initialize PID/LOG locations if they weren't provided by the config file
 | 
						|
[[ -z "$PID_FOLDER" ]] && PID_FOLDER="/var/run"
 | 
						|
[[ -z "$LOG_FOLDER" ]] && LOG_FOLDER="${pkg.unixLogFolder}"
 | 
						|
! [[ "$PID_FOLDER" == /* ]] && PID_FOLDER="$(dirname "$mainfile")"/"$PID_FOLDER"
 | 
						|
! [[ "$LOG_FOLDER" == /* ]] && LOG_FOLDER="$(dirname "$mainfile")"/"$LOG_FOLDER"
 | 
						|
! [[ -x "$PID_FOLDER" ]] && PID_FOLDER="/tmp"
 | 
						|
! [[ -x "$LOG_FOLDER" ]] && LOG_FOLDER="/tmp"
 | 
						|
 | 
						|
# Set up defaults
 | 
						|
[[ -z "$MODE" ]] && MODE="auto" # modes are "auto", "service" or "run"
 | 
						|
[[ -z "$USE_START_STOP_DAEMON" ]] && USE_START_STOP_DAEMON="true"
 | 
						|
 | 
						|
# Create an identity for log/pid files
 | 
						|
if [[ -z "$identity" ]]; then
 | 
						|
  if [[ -n "$init_script" ]]; then
 | 
						|
    identity="${init_script}"
 | 
						|
  else
 | 
						|
    identity=$(basename "${initfile%.*}")_${initfolder//\//}
 | 
						|
  fi
 | 
						|
fi
 | 
						|
 | 
						|
# Initialize log file name if not provided by the config file
 | 
						|
[[ -z "$LOG_FILENAME" ]] && LOG_FILENAME="${identity}.log"
 | 
						|
 | 
						|
# ANSI Colors
 | 
						|
echoRed() { echo $'\e[0;31m'"$1"$'\e[0m'; }
 | 
						|
echoGreen() { echo $'\e[0;32m'"$1"$'\e[0m'; }
 | 
						|
echoYellow() { echo $'\e[0;33m'"$1"$'\e[0m'; }
 | 
						|
 | 
						|
# Utility functions
 | 
						|
checkPermissions() {
 | 
						|
  touch "$pid_file" &> /dev/null || { echoRed "Operation not permitted (cannot access pid file)"; return 4; }
 | 
						|
  touch "$log_file" &> /dev/null || { echoRed "Operation not permitted (cannot access log file)"; return 4; }
 | 
						|
}
 | 
						|
 | 
						|
isRunning() {
 | 
						|
  ps -p "$1" &> /dev/null
 | 
						|
}
 | 
						|
 | 
						|
await_file() {
 | 
						|
  end=$(date +%s)
 | 
						|
  let "end+=10"
 | 
						|
  while [[ ! -s "$1" ]]
 | 
						|
  do
 | 
						|
    now=$(date +%s)
 | 
						|
    if [[ $now -ge $end ]]; then
 | 
						|
      break
 | 
						|
    fi
 | 
						|
    sleep 1
 | 
						|
  done
 | 
						|
}
 | 
						|
 | 
						|
# Determine the script mode
 | 
						|
action="run"
 | 
						|
if [[ "$MODE" == "auto" && -n "$init_script" ]] || [[ "$MODE" == "service" ]]; then
 | 
						|
  action="$1"
 | 
						|
  shift
 | 
						|
fi
 | 
						|
 | 
						|
# Build the pid and log filenames
 | 
						|
if [[ "$identity" == "$init_script" ]] || [[ "$identity" == "$APP_NAME" ]]; then
 | 
						|
  PID_FOLDER="$PID_FOLDER/${identity}"
 | 
						|
  pid_subfolder=$PID_FOLDER
 | 
						|
fi
 | 
						|
pid_file="$PID_FOLDER/${identity}.pid"
 | 
						|
log_file="$LOG_FOLDER/$LOG_FILENAME"
 | 
						|
 | 
						|
# Determine the user to run as if we are root
 | 
						|
# shellcheck disable=SC2012
 | 
						|
[[ $(id -u) == "0" ]] && run_user=$(ls -ld "$mainfile" | awk '{print $3}')
 | 
						|
 | 
						|
arguments=($RUN_ARGS "$@")
 | 
						|
 | 
						|
# Action functions
 | 
						|
start() {
 | 
						|
  if [[ -f "$pid_file" ]]; then
 | 
						|
    pid=$(cat "$pid_file")
 | 
						|
    isRunning "$pid" && { echoYellow "Already running [$pid]"; return 0; }
 | 
						|
  fi
 | 
						|
  do_start "$@"
 | 
						|
}
 | 
						|
 | 
						|
do_start() {
 | 
						|
  working_dir=$(dirname "$mainfile")
 | 
						|
  pushd "$working_dir" > /dev/null
 | 
						|
  mkdir -p "$PID_FOLDER" &> /dev/null
 | 
						|
  if [[ -n "$run_user" ]]; then
 | 
						|
    checkPermissions || return $?
 | 
						|
    if [[ -z "$pid_subfolder" ]]; then
 | 
						|
      chown "$run_user" "$pid_subfolder"
 | 
						|
    fi
 | 
						|
    chown "$run_user" "$pid_file"
 | 
						|
    chown "$run_user" "$log_file"
 | 
						|
    if [ $USE_START_STOP_DAEMON = true ] && type start-stop-daemon > /dev/null 2>&1; then
 | 
						|
      start-stop-daemon --start --quiet \
 | 
						|
        --chuid "$run_user" \
 | 
						|
        --name "$identity" \
 | 
						|
        --make-pidfile --pidfile "$pid_file" \
 | 
						|
        --background --no-close \
 | 
						|
        --startas "$mainfile" \
 | 
						|
        --chdir "$working_dir" \
 | 
						|
        -- "${arguments[@]}" \
 | 
						|
        >> "$log_file" 2>&1
 | 
						|
      await_file "$pid_file"
 | 
						|
    else
 | 
						|
      su -s /bin/sh -c "$mainfile $(printf "\"%s\" " "${arguments[@]}") >> \"$log_file\" 2>&1 & echo \$!" "$run_user" > "$pid_file"
 | 
						|
    fi
 | 
						|
    pid=$(cat "$pid_file")
 | 
						|
  else
 | 
						|
    checkPermissions || return $?
 | 
						|
    "$mainfile" "${arguments[@]}" >> "$log_file" 2>&1 &
 | 
						|
    pid=$!
 | 
						|
    disown $pid
 | 
						|
    echo "$pid" > "$pid_file"
 | 
						|
  fi
 | 
						|
  [[ -z $pid ]] && { echoRed "Failed to start"; return 1; }
 | 
						|
  echoGreen "Started [$pid]"
 | 
						|
}
 | 
						|
 | 
						|
stop() {
 | 
						|
  working_dir=$(dirname "$mainfile")
 | 
						|
  pushd "$working_dir" > /dev/null
 | 
						|
  [[ -f $pid_file ]] || { echoYellow "Not running (pidfile not found)"; return 0; }
 | 
						|
  pid=$(cat "$pid_file")
 | 
						|
  isRunning "$pid" || { echoYellow "Not running (process ${pid}). Removing stale pid file."; rm -f "$pid_file"; return 0; }
 | 
						|
  do_stop "$pid" "$pid_file"
 | 
						|
}
 | 
						|
 | 
						|
do_stop() {
 | 
						|
  kill -2 "$1" &> /dev/null || { echoRed "Unable to kill process $1"; return 1; }
 | 
						|
  for i in $(seq 1 60); do
 | 
						|
    isRunning "$1" || { echoGreen "Stopped [$1]"; rm -f "$2"; return 0; }
 | 
						|
    [[ $i -eq 30 ]] && kill -9 "$1" &> /dev/null
 | 
						|
    sleep 1
 | 
						|
  done
 | 
						|
  echoRed "Unable to kill process $1";
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
restart() {
 | 
						|
  stop && start
 | 
						|
}
 | 
						|
 | 
						|
force_reload() {
 | 
						|
  working_dir=$(dirname "$mainfile")
 | 
						|
  pushd "$working_dir" > /dev/null
 | 
						|
  [[ -f $pid_file ]] || { echoRed "Not running (pidfile not found)"; return 7; }
 | 
						|
  pid=$(cat "$pid_file")
 | 
						|
  rm -f "$pid_file"
 | 
						|
  isRunning "$pid" || { echoRed "Not running (process ${pid} not found)"; return 7; }
 | 
						|
  do_stop "$pid" "$pid_file"
 | 
						|
  do_start
 | 
						|
}
 | 
						|
 | 
						|
status() {
 | 
						|
  working_dir=$(dirname "$mainfile")
 | 
						|
  pushd "$working_dir" > /dev/null
 | 
						|
  [[ -f "$pid_file" ]] || { echoRed "Not running"; return 3; }
 | 
						|
  pid=$(cat "$pid_file")
 | 
						|
  isRunning "$pid" || { echoRed "Not running (process ${pid} not found)"; return 1; }
 | 
						|
  echoGreen "Running [$pid]"
 | 
						|
  return 0
 | 
						|
}
 | 
						|
 | 
						|
run() {
 | 
						|
  pushd "$(dirname "$mainfile")" > /dev/null
 | 
						|
  "$mainfile" "${arguments[@]}"
 | 
						|
  result=$?
 | 
						|
  popd > /dev/null
 | 
						|
  return "$result"
 | 
						|
}
 | 
						|
 | 
						|
# Call the appropriate action function
 | 
						|
case "$action" in
 | 
						|
start)
 | 
						|
  start "$@"; exit $?;;
 | 
						|
stop)
 | 
						|
  stop "$@"; exit $?;;
 | 
						|
restart)
 | 
						|
  restart "$@"; exit $?;;
 | 
						|
force-reload)
 | 
						|
  force_reload "$@"; exit $?;;
 | 
						|
status)
 | 
						|
  status "$@"; exit $?;;
 | 
						|
run)
 | 
						|
  run "$@"; exit $?;;
 | 
						|
*)
 | 
						|
  echo "Usage: $0 {start|stop|restart|force-reload|status|run}"; exit 1;
 | 
						|
esac
 | 
						|
 | 
						|
exit 0
 |