Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Oct 2014 23:30:36 +0200 (CEST)
From:      Geoffroy Desvernay <dgeo@centrale-marseille.fr>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        ruby@FreeBSD.org, caleb@land.fm
Subject:   [PATCH] www/rubygem-unicorn: add rc script
Message-ID:  <201410152130.s9FLUaOu010414@dgeo.sysadm.ec-m.fr>

next in thread | raw e-mail | index | archive | help

>Submitter-Id:	current-users
>Originator:	Geoffroy Desvernay
>Organization:	Ecole Centrale de Marseille
>Confidential:	no
>Synopsis:	[PATCH] www/rubygem-unicorn: add rc script
>Severity:	non-critical
>Priority:	low
>Category:	ports
>Class:		change-request
>Release:	FreeBSD 10.0-RELEASE-p9 amd64
>Environment:
System: FreeBSD dgeo.sysadm.ec-m.fr 10.0-RELEASE-p9 FreeBSD 10.0-RELEASE-p9 #0: Mon Sep 15 14:35:52 UTC 2014
>Description:
add rc script from https://github.com/caleb/freebsd-unicorn

It can handle one/many capistrano/rack/rails apps nicely

2nd try:
It was already submitted in (now closed) #184592 but with errors I didn't managed to catch (uuencoded patch, multiple set_rcvar, …). 
All of these should be corrected now (upstream too).

Port maintainer (ruby@FreeBSD.org) is cc'd, as well as original author (thanks to him !).

Generated with FreeBSD Port Tools 1.02 (mode: change, diff: SVN)
>How-To-Repeat:
>Fix:

--- rubygem-unicorn-4.6.3.patch begins here ---
Index: Makefile
===================================================================
--- Makefile	(revision 370949)
+++ Makefile	(working copy)
@@ -20,6 +20,9 @@
 USE_RUBYGEMS=	yes
 RUBYGEM_AUTOPLIST=	yes
 
+SUB_LIST=	RUBY_NAME=${RUBY_NAME}
+USE_RC_SUBR=	unicorn
+
 PLIST_FILES=	bin/unicorn bin/unicorn_rails
 
 .include <bsd.port.mk>
Index: files/unicorn.in
===================================================================
--- files/unicorn.in	(revision 0)
+++ files/unicorn.in	(working copy)
@@ -0,0 +1,309 @@
+#!/bin/sh
+
+# PROVIDE: unicorn
+# REQUIRE: LOGIN mysql postgresql
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="unicorn"
+rcvar="${name}_enable"
+procname="%%RUBY_NAME%%"
+
+extra_commands="upgrade show reopenlogs"
+start_cmd="unicorn_start_command"
+upgrade_cmd="unicorn_upgrade_command"
+show_cmd="unicorn_show_command"
+reopenlogs_cmd="unicorn_reopenlogs_command"
+
+load_rc_config "${name}"
+
+: ${unicorn_enable:="NO"}
+: ${unicorn_flags:="-D"}
+: ${unicorn_env:="production"}
+: ${unicorn_init_config:=""}
+: ${unicorn_bundle_gemfile:=""}
+: ${unicorn_profiles:=""}
+: ${unicorn_upgrade_timeout:="60"}
+: ${unicorn_rc_script:="%%PREFIX%%/etc/rc.d/unicorn"}
+
+#
+# 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/unicorn.pid'
+#
+_read_profile_var()
+{
+  profile=$1
+  var=$2
+  default=$3
+  default2=$4
+  eval value="\${unicorn_${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/unicorn"
+  directory_pidfile="${directory}/shared/tmp/pids/unicorn.pid"
+  directory_old_pidfile="${directory_pidfile}.oldbin"
+  directory_config="${directory}/current/config/unicorn.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"
+
+  # 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
+
+  unicorn_rackup=`        _read_profile_var "${profile}" "rackup"         "${directory_rackup}"`
+  unicorn_old_pidfile=`   _read_profile_var "${profile}" "old_pidfile"    "${directory_old_pidfile}"`
+  unicorn_config=`        _read_profile_var "${profile}" "config"         "${directory_config}"`
+  unicorn_init_config=`   _read_profile_var "${profile}" "init_config"    "${directory_init_config}"`
+  unicorn_bundle_gemfile=`_read_profile_var "${profile}" "bundle_gemfile" "${directory_bundle_gemfile}"`
+  unicorn_chdir=`         _read_profile_var "${profile}" "chdir"          "${directory_chdir}"`
+  unicorn_listen=`        _read_profile_var "${profile}" "listen"         "${unicorn_listen}"`
+  unicorn_user=`          _read_profile_var "${profile}" "user"           "${unicorn_user}"           "${directory_user}"`
+  unicorn_nice=`          _read_profile_var "${profile}" "nice"           "${unicorn_nice}"`
+  unicorn_env=`           _read_profile_var "${profile}" "env"            "${unicorn_env}"`
+  unicorn_flags=`         _read_profile_var "${profile}" "flags"          "${unicorn_flags}"`
+
+  command=`_read_profile_var "${profile}"      "command"      "${unicorn_command}"      "${directory_command}"`
+  command_args=`_read_profile_var "${profile}" "command_args" "${unicorn_command_args}" "${directory_command_args}"`
+  pidfile=`_read_profile_var "${profile}"      "pidfile"      "${directory_pidfile}"`
+else
+  if [ "x${unicorn_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 ${unicorn_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}"
+        ${unicorn_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=${unicorn_directory:-}
+
+    if [ -n "${directory}" ]; then
+      _setup_directory "${directory}"
+    fi
+
+    unicorn_rackup=${unicorn_rackup:-$directory_rackup}
+    unicorn_old_pidfile=${unicorn_old_pidfile:-$directory_old_pidfile}
+    unicorn_chdir=${unicorn_chdir:-$directory_chdir}
+    unicorn_rackup=${unicorn_rackup:-$directory_rackup}
+    unicorn_user=${unicorn_user:-$directory_user}
+    unicorn_config=${unicorn_config:-$directory_config}
+    unicorn_init_config=${unicorn_init_config:-$directory_init_config}
+    unicorn_bundle_gemfile=${unicorn_bundle_gemfile:-$directory_bundle_gemfile}
+
+    command=${unicorn_command:-$directory_command}
+    command_args=${unicorn_command_args:-$directory_command_args}
+    pidfile=${unicorn_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="${unicorn_config:-} ${unicorn_rackup:-}"
+
+#
+# Build up the flags based on the environment variables
+#
+[ -n "${unicorn_listen}" ] && unicorn_flags="-l ${unicorn_listen} ${unicorn_flags}"
+[ -n "${unicorn_config}" ] && unicorn_flags="-c ${unicorn_config} ${unicorn_flags}"
+[ -n "${unicorn_env}" ] && unicorn_flags="-E ${unicorn_env} ${unicorn_flags}"
+
+# Add our rackup file to the unicorn command_args
+[ -n "${unicorn_rackup:-}" ] && command_args="${unicorn_rackup:-} ${command_args:-}"
+
+# This function builds the command to start unicorn. This is split out so we can
+# print it from the "show" command
+_unicorn_start_command()
+{
+  local shell_command
+  shell_command="${unicorn_bundle_gemfile:+export BUNDLE_GEMFILE=$unicorn_bundle_gemfile && }"\
+"${unicorn_init_config:+. $unicorn_init_config && }"\
+"${unicorn_chdir:+cd $unicorn_chdir && }"\
+"${unicorn_nice:+nice -n $unicorn_nice }"\
+"${command} ${rc_flags} ${command_args}"
+
+  if [ -n "${unicorn_user}" ]; then
+    echo "su -l ${unicorn_user} -c \"${shell_command}\""
+  else
+    echo "sh -c \"${shell_command}\""
+  fi
+}
+
+#
+# The start command
+#
+unicorn_start_command()
+{
+  # ensure unicorn 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 ${name}_command \"$command\""
+    return 1
+  fi
+
+  check_startmsgs && echo "Starting ${name}: ${profile}."
+
+  eval "$(_unicorn_start_command)"
+  _return=$?
+
+  if [ $_return -ne 0 ] && [ -z "${rc_force}" ]; then
+    return 1
+  fi
+
+  return 0
+}
+
+unicorn_upgrade_command()
+{
+  if [ -n "${rc_pid}" ]; then
+    # Tell the master to spawn a new version of itself
+    if kill -USR2 "${rc_pid}"; then
+      n=$unicorn_upgrade_timeout
+
+      # Wait until the unicorn_old_pidfile and pidfile both exist and are non-empty
+      echo -n >&2 "Waiting for the new master to spawn"
+      while [ \( ! -s "${unicorn_old_pidfile}" -o ! -s "${pidfile}" \) -a $n -ge 0 ]; do
+        printf >&2 '.' && sleep 1 && n=$(( $n-1 ))
+      done
+      echo
+
+      # if the pidfile or unicorn_old_pidfile still don't exist, quit
+      if [ ! -s "${pidfile}" -o ! -s "${unicorn_old_pidfile}" ]; then
+        [ ! -s "${pidfile}" ]              && echo >&2 "${pidfile} doesn't exist after ${unicorn_upgrade_timeout} seconds"
+        [ ! -s "${punicorn_old_pidfile}" ] && echo >&2 "${unicorn_old_pidfile} doesn't exist after ${unicorn_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 "${unicorn_old_pidfile}" "${procname}"`
+
+      # Wait for the old master to die
+      echo -n >&2 "Waiting for the old master to cleanup"
+      while [ -s "${unicorn_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 "${unicorn_old_pidfile}" -a $n -lt 0 ]; then
+        echo >&2 "${unicorn_old_pidfile} still exists after ${unicorn_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
+#
+unicorn_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:         ${unicorn_rackup}
+pidfile:        ${pidfile}
+old_pidfile:    ${unicorn_old_pidfile}
+listen:         ${unicorn_listen}
+config:         ${unicorn_config}
+init_config:    ${unicorn_init_config}
+bundle_gemfile: ${unicorn_bundle_gemfile}
+chdir:          ${unicorn_chdir}
+user:           ${unicorn_user}
+nice:           ${unicorn_nice}
+env:            ${unicorn_env}
+flags:          ${unicorn_flags}
+
+start_command:
+
+$(_unicorn_start_command)
+"
+}
+
+unicorn_reopenlogs_command()
+{
+  [ -n "${rc_pid}" ] && kill -USR1 $rc_pid
+}
+
+run_rc_command "${1}"
+

Property changes on: files/unicorn.in
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
--- rubygem-unicorn-4.6.3.patch ends here ---




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410152130.s9FLUaOu010414>