Puma 配方在 CentOS 上失败

puma recipe failing on CentOS

我正在尝试创建一个在 centos6 上使用 puma 的厨师独奏食谱。我看到的所有指南都针对 Ubuntu 使用 Upstart。我已经尝试进行修改以使用 init 但它仍然失败并显示错误 * /etc/init.d/puma-manager does not exist!.

/recipes/puma.rb

# add puma init conf
template '/etc/init/puma.conf' do
  source 'puma-init.conf.erb'
  mode 0644
end

# add puma manager conf
template '/etc/init/puma-manager.conf' do
  source 'puma-manager.conf.erb'
  mode 0644
end

# add puma conf
template '/etc/puma.conf' do
  source 'puma.conf.erb'
  mode 0644
end

cookbook_file '/etc/init.d/puma' do
  source 'puma'
  owner 'deploy'
  group 'deploy'
  mode '0755'
  action :create
end

cookbook_file '/usr/local/bin/run-puma' do
  source 'run-puma'
  owner 'deploy'
  group 'deploy'
  mode '0755'
  action :create
end

# add puma app conf
template "#{node['app_shared_path']}/config/puma.rb" do
  source 'puma.rb.erb'
  mode 0644
  # notifies :restart, 'service[puma]', :delayed
end

service 'puma-manager' do
  provider Chef::Provider::Service::Init
  supports ['start', 'stop', 'restart', 'status']
  action :start
end

/files/default/puma

#! /bin/sh
### BEGIN INIT INFO
# Provides:          puma
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO

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

# 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
USE_LOCAL_BUNDLE=0

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

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

#
# 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/config/puma.rb"
    fi
    log_file=`echo $i | cut -d , -f 4`
    if [ "$log_file" = "" ]; then
      log_file="$dir/log/puma.log"
    fi
    environment=`echo $i | cut -d , -f 5`
    do_start_one $dir $user $config_file $log_file $environment
  done
}

do_start_one() {
  PIDFILE=/tmp/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     
    else
      do_restart_one 
    fi
  else
    do_start_one_do     
  fi
}

do_start_one_do() {
  log_daemon_msg "--> Woke up puma "
  log_daemon_msg "user "
  log_daemon_msg "log to "

  if [ ! -z "" ]; then
    for e in $(echo "" | tr ';' '\n'); do
        log_daemon_msg "environment $e"
        v=${e%%\=*} ;  eval "$e" ; export $v
    done
  fi

  start-stop-daemon --verbose --start --chdir  --chuid  --background --exec $RUNPUMA --   
}

#
# 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 "
  PIDFILE=/tmp/puma/pid
  STATEFILE=/tmp/puma/state
  if [ -e $PIDFILE ]; then
    PID=`cat $PIDFILE`
    if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
      log_daemon_msg "---> Puma  isn't running."
    else
      log_daemon_msg "---> About to kill PID `cat $PIDFILE`"
      if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
        cd  && bundle exec pumactl --state $STATEFILE stop
      else
        pumactl --state $STATEFILE stop
      fi
      # Many daemons don't delete their pidfiles when they exit.
      rm -f $PIDFILE $STATEFILE
    fi
  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=/tmp/puma/pid
  i=`grep  $CONFIG`
  dir=`echo $i | cut -d , -f 1`

  if [ -e $PIDFILE ]; then
    log_daemon_msg "--> About to restart puma "
    if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
      cd  && bundle exec pumactl --state $dir/tmp/puma/state restart
    else
      pumactl --state $dir/tmp/puma/state restart
    fi
    # 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
    environment=`echo $i | cut -d , -f 5`
    do_start_one $dir $user $config_file $log_file $environment
  fi
    return 0
}

#
# Function that statuss the 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=/tmp/puma/pid
  i=`grep  $CONFIG`
  dir=`echo $i | cut -d , -f 1`

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

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

  # Environment variables
  if [ "" != "" ]; then
    str="$str,"
  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 "^" $CONFIG`" -eq 0 ]; then
    echo "There's no app  to remove."
  else
    # Stop it first.
    do_stop_one 
    # Remove it from the config.
    sed -i "\:^:d" $CONFIG
    log_daemon_msg "Removed a Puma from the jungle: ."
  fi
}

config_bundler() {
  HOME="$(eval echo ~$(id -un))"
  if [ -d "/usr/local/rbenv/bin" ]; then
    PATH="/usr/local/rbenv/bin:/usr/local/rbenv/shims:$PATH"
    eval "$(rbenv init -)"
    USE_LOCAL_BUNDLE=1
    return 0
  elif [ -d "$HOME/.rbenv/bin" ]; then
    PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
    eval "$(rbenv init -)"
    USE_LOCAL_BUNDLE=1
    return 0
  # TODO: test rvm
  # 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"
  # TODO: don't know what to do with chruby
  # 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

  return 1
}

config_bundler

case "" in
  start)
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
    if [ "$#" -eq 1 ]; then
      do_start
    else
      i=`grep  $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  $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  $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  $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    
    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 
    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
:

/files/default/run-puma

#!/bin/bash
app=; config=; log=;
cd $app && exec bundle exec puma -C $config 2>&1 >> $log

首先,您的服务名称似乎有误。它似乎应该被称为 service 'puma' 而不是 puma-manager.

除此之外,来自 Debian/Ubuntu 的初始化脚本未经修改将无法在 CentOS 上运行。 CentOS 上不存在一些必需的文件,例如来自 init-functions 的辅助方法。

根据脚本的不同,这些修改可能非常复杂,有时最好从头开始编写新脚本。

无论如何,这里有一个 non-official Puma 的 CentOS 初始化脚本示例:

https://github.com/puma/puma/issues/178

但它有点 old/untested,我不确定它是否可以在不修改的情况下工作。