blob: 10b858548861b494f57eae9d25cd411930ff4511 (
plain) (
tree)
|
|
#!/bin/sh
# PROVIDE: puma
# REQUIRE: LOGIN postgresql
# KEYWORD: shutdown
. /etc/rc.subr
name="puma"
rcvar="${name}_enable"
procname="ruby"
extra_commands="upgrade show reopenlogs"
start_cmd="puma_start_command"
upgrade_cmd="puma_upgrade_command"
show_cmd="puma_show_command"
reopenlogs_cmd="puma_reopenlogs_command"
load_rc_config "${name}"
: ${puma_enable:="NO"}
: ${puma_flags:="-d"}
: ${puma_env:="production"}
: ${puma_init_config:=""}
: ${puma_bundle_gemfile:=""}
: ${puma_profiles:=""}
: ${puma_upgrade_timeout:="60"}
: ${puma_rc_script:="/usr/local/etc/rc.d/puma"}
#
# Convenience function to read a profile's environment variable, or fall back to a default
#
# e.x. _read_profile_var my_app pidfile '/u/my_app/shard/pids/puma.pid'
#
_read_profile_var()
{
profile=$1
var=$2
default=$3
default2=$4
eval value="\${puma_${profile}_${var}:-${default}}"
eval value="\${value:-${default2}}"
echo "${value}"
}
#
# Takes a directory and sets up some default environement variables based on a capistrano layout
#
_setup_directory()
{
local directory
directory=$1
directory_command="${directory}/current/bin/puma"
directory_pidfile="${directory}/shared/tmp/pids/puma.pid"
directory_old_pidfile="${directory_pidfile}.oldbin"
directory_config="${directory}/current/config/puma.rb"
directory_rackup="${directory}/current/config.ru"
directory_init_config="${directory}/current/.env"
directory_bundle_gemfile="${directory}/current/Gemfile"
directory_chdir="${directory}/current"
# only use the directory_init_config if it exists
if [ ! -f "${directory_init_config}" ]; then
unset directory_init_config
fi
# only use the bundle_gemfile if it exists
if [ ! -f "${directory_bundle_gemfile}" ]; then
unset directory_bundle_gemfile
fi
if [ -f "${directory_config}" ]; then
directory_user=`stat -f "%Su" "${directory_config}"` # default to the owner of the config file
fi
}
#
# If we have a profile, set up the environment for that profile
#
if [ -n "$2" ]; then
profile="$2"
# set the rcvar for this specific profile
rcvar="${name}_${profile}_enable"
rcvar="${rcvar}"
# if the user provides a directory, we can infer some default configuration
directory=`_read_profile_var "${profile}" "directory"`
if [ -n "${directory}" ]; then
_setup_directory "${directory}"
fi
puma_rackup=` _read_profile_var "${profile}" "rackup" "${directory_rackup}"`
puma_old_pidfile=` _read_profile_var "${profile}" "old_pidfile" "${directory_old_pidfile}"`
puma_config=` _read_profile_var "${profile}" "config" "${directory_config}"`
puma_init_config=` _read_profile_var "${profile}" "init_config" "${directory_init_config}"`
puma_bundle_gemfile=`_read_profile_var "${profile}" "bundle_gemfile" "${directory_bundle_gemfile}"`
puma_chdir=` _read_profile_var "${profile}" "chdir" "${directory_chdir}"`
puma_listen=` _read_profile_var "${profile}" "listen" "${puma_listen}"`
puma_user=` _read_profile_var "${profile}" "user" "${puma_user}" "${directory_user}"`
puma_nice=` _read_profile_var "${profile}" "nice" "${puma_nice}"`
puma_env=` _read_profile_var "${profile}" "env" "${puma_env}"`
puma_flags=` _read_profile_var "${profile}" "flags" "${puma_flags}"`
command=`_read_profile_var "${profile}" "command" "${puma_command}" "${directory_command}"`
command_args=`_read_profile_var "${profile}" "command_args" "${puma_command_args}" "${directory_command_args}"`
pidfile=`_read_profile_var "${profile}" "pidfile" "${directory_pidfile}"`
else
if [ "x${puma_profiles}" != "x" -a "x$1" != "x" ]; then
# If we weren't started with a profile, run the command on all available profiles
for profile in ${puma_profiles}; do
# By default set the profile rcvar to no to suppress warnings by checkyesno
profile_rcvar="${name}_${profile}_enable"
eval "${profile_rcvar}=\${${profile_rcvar}:-'NO'}"
if checkyesno ${profile_rcvar}; then
echo "Running ${1} on ${profile}"
${puma_rc_script} $1 $profile
else
echo "Skipping ${profile}"
# Unset the variable and then checkyesno again to print the warning
eval "unset ${profile_rcvar}"
checkyesno ${profile_rcvar}
fi
echo
done
exit 0
else
# look for a profile-less configuration
# if the user provides a directory, we can infer some default configuration
directory=${puma_directory:-}
if [ -n "${directory}" ]; then
_setup_directory "${directory}"
fi
puma_rackup=${puma_rackup:-$directory_rackup}
puma_old_pidfile=${puma_old_pidfile:-$directory_old_pidfile}
puma_chdir=${puma_chdir:-$directory_chdir}
puma_rackup=${puma_rackup:-$directory_rackup}
puma_user=${puma_user:-$directory_user}
puma_config=${puma_config:-$directory_config}
puma_init_config=${puma_init_config:-$directory_init_config}
puma_bundle_gemfile=${puma_bundle_gemfile:-$directory_bundle_gemfile}
command=${puma_command:-$directory_command}
command_args=${puma_command_args:-$directory_command_args}
pidfile=${puma_pidfile:-$directory_pidfile}
fi
fi
# add the directory as a required directory, if it's specified
required_dirs="${directory:-}"
# if we have a config file or rackup file specified, make sure it exists
required_files="${puma_config:-} ${puma_rackup:-}"
#
# Build up the flags based on the environment variables
#
[ -n "${puma_listen}" ] && puma_flags="-b ${puma_listen} ${puma_flags}"
[ -n "${puma_config}" ] && puma_flags="-C ${puma_config} ${puma_flags}"
[ -n "${puma_env}" ] && puma_flags="-e ${puma_env} ${puma_flags}"
# Add our rackup file to the puma command_args
[ -n "${puma_rackup:-}" ] && command_args="${puma_rackup:-} ${command_args:-}"
# This function builds the command to start puma. This is split out so we can
# print it from the "show" command
_puma_start_command()
{
local shell_command
shell_command="${puma_bundle_gemfile:+export BUNDLE_GEMFILE=$puma_bundle_gemfile && }"\
"${puma_init_config:+. $puma_init_config && }"\
"${puma_chdir:+cd $puma_chdir && }"\
"${puma_nice:+nice -n $puma_nice }"\
"${command} ${rc_flags} ${command_args}"
if [ -n "${puma_user}" ]; then
echo "su -l ${puma_user} -c \"${shell_command}\""
else
echo "sh -c \"${shell_command}\""
fi
}
#
# The start command
#
puma_start_command()
{
# ensure puma isn't already running
if [ -z "$rc_fast" -a -n "$rc_pid" ]; then
echo 1>&2 "${name} already running? (pid=$rc_pid)."
return 1
fi
# ensure that the command exists and is executable
if [ ! -x "${_chroot}${_chroot:+/}${command}" ]; then
warn "run_rc_command: cannot run $command"
return 1
fi
check_startmsgs && echo "Starting ${name}: ${profile}."
eval "$(_puma_start_command)"
_return=$?
if [ $_return -ne 0 ] && [ -z "${rc_force}" ]; then
return 1
fi
return 0
}
puma_upgrade_command()
{
if [ -n "${rc_pid}" ]; then
# Tell the master to spawn a new version of itself
if kill -USR2 "${rc_pid}"; then
n=$puma_upgrade_timeout
# Wait until the puma_old_pidfile and pidfile both exist and are non-empty
echo -n >&2 "Waiting for the new master to spawn"
while [ \( ! -s "${puma_old_pidfile}" -o ! -s "${pidfile}" \) -a $n -ge 0 ]; do
printf >&2 '.' && sleep 1 && n=$(( $n-1 ))
done
echo
# if the pidfile or puma_old_pidfile still don't exist, quit
if [ ! -s "${pidfile}" -o ! -s "${puma_old_pidfile}" ]; then
[ ! -s "${pidfile}" ] && echo >&2 "${pidfile} doesn't exist after ${puma_upgrade_timeout} seconds"
[ ! -s "${ppuma_old_pidfile}" ] && echo >&2 "${puma_old_pidfile} doesn't exist after ${puma_upgrade_timeout} seconds"
return 1
fi
# make sure the new master can receive signals, and then QUIT the old one
echo >&2 "Killing the old master"
kill -0 `check_pidfile "${pidfile}" "${procname}"` && kill -QUIT `check_pidfile "${puma_old_pidfile}" "${procname}"`
# Wait for the old master to die
echo -n >&2 "Waiting for the old master to cleanup"
while [ -s "${puma_old_pidfile}" -a $n -ge 0 ]; do
printf >&2 '.' && sleep 1 && n=$(( $n-1 ))
done
echo
# If the old master is still around, print that fact and exit with an error
if [ -s "${puma_old_pidfile}" -a $n -lt 0 ]; then
echo >&2 "${puma_old_pidfile} still exists after ${puma_upgrade_timeout} seconds"
return 1
fi
# everything worked, return success
return 0
fi
# If there isn't a pid in rc_pid, just run the start command
echo >&2 "Couldn't upgrade, running `start` instead"
$0 start "${2}"
fi
}
#
# Prints the configuration for the given profile
#
puma_show_command()
{
if [ -n "${profile}" ]; then
banner="Unicorn Configuration for ${profile}"
else
banner="Unicorn Configuration"
fi
echo "
#
# ${banner}
#
command: ${command}
command_args: ${command_args}
rackup: ${puma_rackup}
pidfile: ${pidfile}
old_pidfile: ${puma_old_pidfile}
listen: ${puma_listen}
config: ${puma_config}
init_config: ${puma_init_config}
bundle_gemfile: ${puma_bundle_gemfile}
chdir: ${puma_chdir}
user: ${puma_user}
nice: ${puma_nice}
env: ${puma_env}
flags: ${puma_flags}
start_command:
$(_puma_start_command)
"
}
puma_reopenlogs_command()
{
[ -n "${rc_pid}" ] && kill -USR1 $rc_pid
}
run_rc_command "${1}"
|