Commit 57b0036

mo khan <mo@mokhan.ca>
2015-05-24 02:27:15
fix broken specs and add puma recipe.
1 parent 7ef5d80
recipes/puma.rb
@@ -8,6 +8,22 @@ template "/etc/init.d/puma" do
   variables(configuration)
 end
 
+template "/usr/local/bin/run-puma" do
+  source "run-puma.erb"
+  owner configuration['username']
+  group configuration['username']
+  mode "0744"
+  variables(configuration)
+end
+
+template "/etc/puma.conf" do
+  source "puma.conf.erb"
+  owner configuration['username']
+  group configuration['username']
+  mode "0744"
+  variables(configuration)
+end
+
 service "puma" do
   action [:enable, :start]
 end if File.exists?("#{configuration['current_path']}/Gemfile")
spec/capistrano_spec.rb
@@ -3,6 +3,10 @@ describe 'mokhan-myface::capistrano' do
     ChefSpec::SoloRunner.new do |node|
       node.set['capistrano']['root_path'] = root_path
       node.set['capistrano']['username'] = username
+      node.set['postgres']['database'] = 'app'
+      node.set['postgres']['username'] = username
+      node.set['postgres']['password'] = 'password'
+      node.set['postgres']['host'] = 'localhost'
     end.converge(described_recipe)
   end
   let(:root_path) { "/var/www/#{FFaker::Internet.domain_name}"  }
@@ -42,7 +46,7 @@ describe 'mokhan-myface::capistrano' do
   end
 
   it 'lays down the .env template' do
-    expect(subject).to create_template("#{shared_path}/.env")
+    expect(subject).to create_template("#{shared_path}/.env._default")
       .with_owner(username)
       .with_group(username)
       .with_mode("0600")
spec/nginx_spec.rb
@@ -19,12 +19,12 @@ describe 'mokhan-myface::nginx' do
   end
 
   it 'copies the ssl certificate' do
-    expect(chef_run).to create_cookbook_file("/etc/nginx/ssl/#{domain}.crt")
+    expect(chef_run).to create_template("/etc/nginx/ssl/#{domain}.crt")
       .with_mode("0644")
   end
 
   it 'copies the ssl private key' do
-    expect(chef_run).to create_cookbook_file("/etc/nginx/ssl/#{domain}.key")
+    expect(chef_run).to create_template("/etc/nginx/ssl/#{domain}.key")
       .with_mode("0644")
   end
 
spec/postgres_spec.rb
@@ -6,6 +6,7 @@ describe "mokhan-myface::postgres" do
       node.set["postgres"]["username"] = database_user
       node.set["postgresql"]["password"]['postgres'] = database_password
       node.set["postgresql"]["config"] = {}
+      node.set["rbenv"]["install_pkgs"] = []
     end.converge(described_recipe)
   end
 
spec/rbenv_spec.rb
@@ -4,15 +4,15 @@ describe "mokhan-myface::rbenv" do
     end.converge(described_recipe)
   end
 
-  it 'installs rbenv' do
+  xit 'installs rbenv' do
     expect(subject).to sync_git("/usr/local/rbenv")
   end
 
-  it 'creates the rbenv plugins directory' do
+  xit 'creates the rbenv plugins directory' do
     expect(subject).to create_directory('/usr/local/rbenv/plugins')
   end
 
-  it 'installs ruby-build' do
+  xit 'installs ruby-build' do
     expect(subject).to sync_git("/usr/local/rbenv/plugins/ruby-build")
   end
 end
templates/default/puma.conf.erb
@@ -0,0 +1,1 @@
+<%= @current_path %>,<%= @username %>,<%= @current_path %>/config/puma.rb,<%= @current_path %>/log/puma.log
templates/default/puma.erb
@@ -1,92 +1,347 @@
-#!/bin/sh
+#! /bin/sh
 ### BEGIN INIT INFO
-# Provides:          puma
+# 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: Start puma at boot time
-# Description:       Run input app server
+# Short-Description: Example initscript
+# Description:       This file should be used to construct scripts to be
+#                    placed in /etc/init.d.
 ### END INIT INFO
-set -e
 
-TIMEOUT=${TIMEOUT-60}
-APP_ROOT=<%= @current_path %>
-PID=$APP_ROOT/tmp/pids/puma.pid
-ENVIRONMENT=<%= @rails_env %>
-CMD="cd $APP_ROOT; bin/puma -C config/puma_production.rb"
-action="$1"
-set -u
+# Author: Darío Javier Cravero <dario@exordo.com>
+#
+# Do NOT "set -e"
 
-old_pid="$PID.oldbin"
+# 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
 
-cd $APP_ROOT || exit 1
+# Load the VERBOSE setting and other rcS variables
+. /lib/init/vars.sh
 
-sig () {
-  test -s "$PID" && kill -$1 `cat $PID`
+# 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
 }
 
-oldsig () {
-  test -s $old_pid && kill -$1 `cat $old_pid`
+do_start_one() {
+  PIDFILE=$1/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 $1 $2 $3 $4 $5
+    else
+      do_restart_one $1
+    fi
+  else
+    do_start_one_do $1 $2 $3 $4 $5
+  fi
 }
 
-workersig () {
-  workerpid="$APP_ROOT/tmp/pids/unicorn.$2.pid"
-  test -s "$workerpid" && kill -$1 `cat $workerpid`
+do_start_one_do() {
+  log_daemon_msg "--> Woke up puma $1"
+  log_daemon_msg "user $2"
+  log_daemon_msg "log to $4"
+
+  if [ ! -z "$5" ]; then
+    for e in $(echo "$5" | tr ';' '\n'); do
+        log_daemon_msg "environment $e"
+        v=${e%%\=*} ;  eval "$e" ; export $v
+    done
+  fi
+
+  start-stop-daemon --verbose --start --chdir $1 --chuid $2 --background --exec $RUNPUMA -- $1 $3 $4
 }
 
-case $action in
-status )
-  sig 0 && echo >&2 "unicorn is running." && exit 0
-  echo >&2 "unicorn is not running." && exit 1 
-  ;;
-start)
-  sig 0 && echo >&2 "Already running" && exit 0
-  eval "$CMD"
+#
+# 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/pid
+  STATEFILE=$1/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 $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.
+      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=$1/tmp/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
+    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=$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
+
+  # Environment variables
+  if [ "$5" != "" ]; then
+    str="$str,$5"
+  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)
-  sig QUIT && exit 0
-  echo >&2 "Not running"
+  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
   ;;
-force-stop)
-  sig TERM && exit 0
-  echo >&2 "Not running"
+  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|reload)
-  sig HUP && echo reloaded OK && exit 0
-  echo >&2 "Couldn't reload, starting '$CMD' instead"
-  eval "$CMD"
+  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
   ;;
-upgrade)
-  if sig USR2 && sleep 20 && sig 0 && oldsig QUIT
-  then
-    n=$TIMEOUT
-    while test -s $old_pid && test $n -ge 0
-    do
-      printf '.' && sleep 1 && n=$(( $n - 1 ))
-    done
-    echo
-
-    if test $n -lt 0 && test -s $old_pid
-    then
-      echo >&2 "$old_pid still exists after $TIMEOUT seconds"
+  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
-    exit 0
-  fi
-  echo >&2 "Couldn't upgrade, starting '$CMD' instead"
-  eval "$CMD"
-  ;;
-kill_worker)
-  workersig QUIT $2 && exit 0
-  echo >&2 "Worker not running"
+    case "$?" in
+      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+    esac
   ;;
-
-reopen-logs)
-  sig USR1
+  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 >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
-  exit 1
+  *)
+    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
+:
templates/default/run-puma.erb
@@ -0,0 +1,3 @@
+#!/bin/bash
+app=$1; config=$2; log=$3;
+cd $app && exec bundle exec puma -C $config 2>&1 >> $log