Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Trying to get a init.d/puma to work on Centos 6. It throws error

runuser: user /var/log/puma.log does not exist

I run this from the /srv/books/current folder but it fails. I tried to debug the values but not quite get what is missing and why it throws this error.

#! /bin/sh
# puma - this script starts and stops the puma daemon
#
# chkconfig:    - 85 15
# description:  Puma
# processname:  puma
# config:       /etc/puma.conf
# pidfile:      /srv/books/current/tmp/pids/puma.pid

# Author: Darío Javier Cravero <dario@exordo.com>
#
# Do NOT "set -e"

# Original script https://github.com/puma/puma/blob/master/tools/jungle/puma
# It was modified here by Stanislaw Pankevich <s.pankevich@gmail.com>
# to run on CentOS 5.5 boxes.
# Script works perfectly on CentOS 5: script uses its native daemon().
# Puma is being stopped/restarted by sending signals, control app is not used.

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin
DESC="Puma rack web server"
NAME=puma
DAEMON=$NAME
SCRIPTNAME=/etc/init.d/$NAME
CONFIG=/etc/puma.conf
JUNGLE=`cat $CONFIG`
RUNPUMA=/usr/local/bin/run-puma

# Skipping the following non-CentOS string
# Load the VERBOSE setting and other rcS variables
# . /lib/init/vars.sh

# CentOS does not have these functions natively
log_daemon_msg() { echo "$@"; }
log_end_msg() { [ $1 -eq 0 ] && RES=OK; logger ${RES:=FAIL}; }

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that performs a clean up of puma.* files
#
cleanup() {
  echo "Cleaning up puma temporary files..."
  echo $1;
  PIDFILE=$1/tmp/puma/puma.pid
  STATEFILE=$1/tmp/puma/puma.state
  SOCKFILE=$1/tmp/puma/puma.sock
  rm -f $PIDFILE $STATEFILE $SOCKFILE
}

#
# Function that starts the jungle
#
do_start() {
  log_daemon_msg "=> Running the jungle..."
  for i in $JUNGLE; do
    dir=`echo $i | cut -d , -f 1`
    user=`echo $i | cut -d , -f 2`
    config_file=`echo $i | cut -d , -f 3`
    if [ "$config_file" = "" ]; then
      config_file="$dir/puma/config.rb"
    fi
    log_file=`echo $i | cut -d , -f 4`
    if [ "$log_file" = "" ]; then
      log_file="$dir/puma/puma.log"
    fi
    do_start_one $dir $user $config_file $log_file
  done
}

do_start_one() {
  PIDFILE=$1/puma/puma.pid
  if [ -e $PIDFILE ]; then
    PID=`cat $PIDFILE`
    # If the puma isn't running, run it, otherwise restart it.
    if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
      do_start_one_do $1 $2 $3 $4
    else
      do_restart_one $1
    fi
  else
    do_start_one_do $1 $2 $3 $4
  fi
}

do_start_one_do() {
  log_daemon_msg "--> Woke up puma $1"
  log_daemon_msg "user $2"
  log_daemon_msg "log to $4"
  cleanup $1;
  daemon --user $2 $RUNPUMA $1 $3 $4
}

#
# Function that stops the jungle
#
do_stop() {
  log_daemon_msg "=> Putting all the beasts to bed..."
  for i in $JUNGLE; do
    dir=`echo $i | cut -d , -f 1`
    do_stop_one $dir
  done
}
#
# Function that stops the daemon/service
#
do_stop_one() {
  log_daemon_msg "--> Stopping $1"
  PIDFILE=$1/tmp/puma/puma.pid
  STATEFILE=$1/tmp/puma/puma.state

  echo $PIDFILE

  if [ -e $PIDFILE ]; then
    PID=`cat $PIDFILE`
    echo "Pid:"
    echo $PID
    if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
      log_daemon_msg "---> Puma $1 isn't running."
    else
      log_daemon_msg "---> About to kill PID `cat $PIDFILE`"
      # pumactl --state $STATEFILE stop
      # Many daemons don't delete their pidfiles when they exit.
      kill -9 $PID
    fi
    cleanup $1
  else
    log_daemon_msg "---> No puma here..."
  fi
  return 0
}

#
# Function that restarts the jungle
#
do_restart() {
  for i in $JUNGLE; do
    dir=`echo $i | cut -d , -f 1`
    do_restart_one $dir
  done
}

#
# Function that sends a SIGUSR2 to the daemon/service
#
do_restart_one() {
  PIDFILE=$1/tmp/puma/puma.pid
  i=`grep $1 $CONFIG`
  dir=`echo $i | cut -d , -f 1`

  if [ -e $PIDFILE ]; then
    log_daemon_msg "--> About to restart puma $1"
    # pumactl --state $dir/tmp/puma/state restart
    kill -s USR2 `cat $PIDFILE`
    # TODO Check if process exist
  else
    log_daemon_msg "--> Your puma was never playing... Let's get it out there first"
    user=`echo $i | cut -d , -f 2`
    config_file=`echo $i | cut -d , -f 3`
    if [ "$config_file" = "" ]; then
      config_file="$dir/config/puma.rb"
    fi
    log_file=`echo $i | cut -d , -f 4`
    if [ "$log_file" = "" ]; then
      log_file="$dir/log/puma.log"
    fi
    do_start_one $dir $user $config_file $log_file
  fi
return 0
}

#
# Function that statuss then jungle
#
do_status() {
  for i in $JUNGLE; do
    dir=`echo $i | cut -d , -f 1`
    do_status_one $dir
  done
}

#
# Function that sends a SIGUSR2 to the daemon/service
#
do_status_one() {
  PIDFILE=$1/tmp/puma/pid
  i=`grep $1 $CONFIG`
  dir=`echo $i | cut -d , -f 1`

  if [ -e $PIDFILE ]; then
    log_daemon_msg "--> About to status puma $1"
    pumactl --state $dir/tmp/puma/state stats
    # kill -s USR2 `cat $PIDFILE`
    # TODO Check if process exist
  else
    log_daemon_msg "--> $1 isn't there :(..."
  fi

  return 0
}

do_add() {
  str=""
  # App's directory
  if [ -d "$1" ]; then
    if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then
      str=$1
    else
      echo "The app is already being managed. Remove it if you want to update its config."
      exit 1
    fi
  else
    echo "The directory $1 doesn't exist."
    exit 1
  fi
  # User to run it as
  if [ "`grep -c "^$2:" /etc/passwd`" -eq 0 ]; then
    echo "The user $2 doesn't exist."
    exit 1
  else
    str="$str,$2"
  fi
  # Config file
  if [ "$3" != "" ]; then
    if [ -e $3 ]; then
      str="$str,$3"
    else
      echo "The config file $3 doesn't exist."
      exit 1
    fi
  fi
  # Log file
  if [ "$4" != "" ]; then
    str="$str,$4"
  fi

  # Add it to the jungle
  echo $str >> $CONFIG
  log_daemon_msg "Added a Puma to the jungle: $str. You still have to start it though."
}

do_remove() {
  if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then
    echo "There's no app $1 to remove."
  else
    # Stop it first.
    do_stop_one $1
    # Remove it from the config.
    sed -i "\\:^$1:d" $CONFIG
    log_daemon_msg "Removed a Puma from the jungle: $1."
  fi
}

case "$1" in
  start)
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
    if [ "$#" -eq 1 ]; then
      do_start
    else
      i=`grep $2 $CONFIG`
      dir=`echo $i | cut -d , -f 1`
      user=`echo $i | cut -d , -f 2`
      config_file=`echo $i | cut -d , -f 3`
      if [ "$config_file" = "" ]; then
        config_file="$dir/config/puma.rb"
      fi
      log_file=`echo $i | cut -d , -f 4`
      if [ "$log_file" = "" ]; then
        log_file="$dir/log/puma.log"
      fi
      do_start_one $dir $user $config_file $log_file
    fi
    case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
  ;;
  stop)
    [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
    if [ "$#" -eq 1 ]; then
      do_stop
    else
      i=`grep $2 $CONFIG`
      dir=`echo $i | cut -d , -f 1`
      do_stop_one $dir
    fi
    case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
  ;;
  status)
    # TODO Implement.
    log_daemon_msg "Status $DESC" "$NAME"
    if [ "$#" -eq 1 ]; then
      do_status
    else
      i=`grep $2 $CONFIG`
      dir=`echo $i | cut -d , -f 1`
      do_status_one $dir
    fi
    case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
  ;;
  restart)
    log_daemon_msg "Restarting $DESC" "$NAME"
    if [ "$#" -eq 1 ]; then
      do_restart
    else
      i=`grep $2 $CONFIG`
      dir=`echo $i | cut -d , -f 1`
      do_restart_one $dir
    fi
    case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
  ;;
  add)
    if [ "$#" -lt 3 ]; then
      echo "Please, specifiy the app's directory and the user that will run it at least."
      echo "  Usage: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
      echo "    config and log are optionals."
      exit 1
    else
      do_add $2 $3 $4 $5
    fi
    case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
  ;;
  remove)
    if [ "$#" -lt 2 ]; then
      echo "Please, specifiy the app's directory to remove."
      exit 1
    else
      do_remove $2
    fi
    case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
  ;;
  *)
    echo "Usage:" >&2
    echo "  Run the jungle: $SCRIPTNAME {start|stop|status|restart}" >&2
    echo "  Add a Puma: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
    echo "    config and log are optionals."
    echo "  Remove a Puma: $SCRIPTNAME remove /path/to/app"
    echo "  On a Puma: $SCRIPTNAME {start|stop|status|restart} PUMA-NAME" >&2
    exit 3
  ;;
esac
:

puma.conf

# /etc/init/puma.conf - Puma config

# This example config should work with Ubuntu 12.04+.  It
# allows you to manage multiple Puma instances with
# Upstart, Ubuntu's native service management tool.
#
# See workers.conf for how to manage all Puma instances at once.
#
# Save this config as /etc/init/puma.conf then manage puma with:
#   sudo start puma app=PATH_TO_APP
#   sudo stop puma app=PATH_TO_APP
#   sudo status puma app=PATH_TO_APP
#
# or use the service command:
#   sudo service puma {start,stop,restart,status}
#

description "Puma Background Worker"

# no "start on", we don't want to automatically start
stop on (stopping puma-manager or runlevel [06])

# change apps to match your deployment user if you want to use this as a less privileged user (recommended!)
setuid deploy
setgid deploy

respawn
respawn limit 3 30

instance ${app}

script
# this script runs in /bin/sh by default
# respawn as bash so we can source in rbenv/rvm
# quoted heredoc to tell /bin/sh not to interpret
# variables
exec /bin/bash <<'EOT'
  # set HOME to the setuid user's home, there doesn't seem to be a better, portable way
  export HOME="$(eval echo ~$(id -un))"

  cd $app

  if [ -d "$HOME/.rbenv/bin" ]; then
    export PATH="$HOME/.rbenv/bin:$PATH"
  elif [ -f  /etc/profile.d/rvm.sh ]; then
    source /etc/profile.d/rvm.sh
  elif [ -f /usr/local/rvm/scripts/rvm ]; then
    source /etc/profile.d/rvm.sh
  elif [ -f "$HOME/.rvm/scripts/rvm" ]; then
    source "$HOME/.rvm/scripts/rvm"
  elif [ -f /usr/local/share/chruby/chruby.sh ]; then
    source /usr/local/share/chruby/chruby.sh
    if [ -f /usr/local/share/chruby/auto.sh ]; then
      source /usr/local/share/chruby/auto.sh
    fi
    # if you aren't using auto, set your version here
    # chruby 2.0.0
  fi

  logger -t puma "Starting server: $app"

  exec bundle exec puma -C config/puma.rb
EOT
end script
share|improve this question
    
Can you post your puma.conf as well? –  NickW Nov 8 '13 at 15:55
add comment

1 Answer 1

That puma.conf should be in /etc/init/puma.conf, if that is in /etc/puma.conf it's not surprising have some issues, the init.d script is looking for a much simpler file, $JUNGLE is running cat on the file looking for a comma separated value in it.

You need to find something that isn't an Upstart file for the puma.conf .

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.