commit 64234edfbb40bd779b71e8799532ae0440291865
Author: Lukas Zapletal <lzap+git@redhat.com>
Date:   Wed May 28 10:51:46 2014 +0200

    fixes #6036 - Timeout for passenger needs to be raised to avoid timeouts
    
    and also made sure Passenger won't kill all worker instances.

diff --git a/manifests/config/passenger.pp b/manifests/config/passenger.pp
index 027c46c..a2a68f3 100644
--- a/manifests/config/passenger.pp
+++ b/manifests/config/passenger.pp
@@ -24,6 +24,13 @@
 #
 # $user::                   The user under which the application runs.
 #
+# $prestart::               Pre-start the first passenger worker instance process during httpd start.
+#                           type:boolean
+#
+# $min_instances::          Minimum passenger worker instances to keep when application is idle.
+#
+# $start_timeout::          Amount of seconds to wait for Ruby application boot.
+#
 class foreman::config::passenger(
   $app_root            = $foreman::app_root,
   $listen_on_interface = $foreman::passenger_interface,
@@ -35,11 +42,15 @@ class foreman::config::passenger(
   $ssl_cert            = $foreman::server_ssl_cert,
   $ssl_key             = $foreman::server_ssl_key,
   $use_vhost           = $foreman::use_vhost,
-  $user                = $foreman::user
+  $user                = $foreman::user,
+  $prestart            = $foreman::passenger_prestart,
+  $min_instances       = $foreman::passenger_min_instances,
+  $start_timeout       = $foreman::passenger_start_timeout,
 ) {
   # validate parameter values
   validate_string($listen_on_interface)
   validate_bool($ssl)
+  validate_bool($prestart)
 
   $docroot = "${app_root}/public"
 
diff --git a/manifests/init.pp b/manifests/init.pp
index a70c89a..6703262 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -86,6 +86,13 @@
 #
 # $passenger_interface::    Defines which network interface passenger should listen on, undef means all interfaces
 #
+# $passenger_prestart::     Pre-start the first passenger worker instance process during httpd start.
+#                           type:boolean
+#
+# $passenger_min_instances:: Minimum passenger worker instances to keep when application is idle.
+#
+# $passenger_start_timeout:: Amount of seconds to wait for Ruby application boot.
+#
 # $server_ssl_ca::          Defines Apache mod_ssl SSLCACertificateFile setting in Foreman vhost conf file.
 #
 # $server_ssl_chain::       Defines Apache mod_ssl SSLCertificateChainFile setting in Foreman vhost conf file.
@@ -144,7 +151,10 @@ class foreman (
   $oauth_active           = $foreman::params::oauth_active,
   $oauth_map_users        = $foreman::params::oauth_map_users,
   $oauth_consumer_key     = $foreman::params::oauth_consumer_key,
-  $oauth_consumer_secret  = $foreman::params::oauth_consumer_secret
+  $oauth_consumer_secret  = $foreman::params::oauth_consumer_secret,
+  $passenger_prestart     = $foreman::params::passenger_prestart,
+  $passenger_min_instances = $foreman::params::passenger_min_instances,
+  $passenger_start_timeout = $foreman::params::passenger_start_timeout,
 ) inherits foreman::params {
   if $db_adapter == 'UNSET' {
     $db_adapter_real = $foreman::db_type ? {
diff --git a/manifests/params.pp b/manifests/params.pp
index 4991fa1..3ea27c5 100644
--- a/manifests/params.pp
+++ b/manifests/params.pp
@@ -68,6 +68,18 @@ class foreman::params {
           $yumcode = "f${::operatingsystemrelease}"
           $passenger_scl = undef
           $plugin_prefix = 'rubygem-foreman_'
+          case $::operatingsystemrelease {
+            '19': {
+              $passenger_prestart = false
+              $passenger_min_instances = 1
+              $passenger_start_timeout = 0
+            }
+            default: {
+              $passenger_prestart = true
+              $passenger_min_instances = 1
+              $passenger_start_timeout = 600
+            }
+          }
         }
         default: {
           $puppet_basedir = regsubst($::rubyversion, '^(\d+\.\d+).*$', '/usr/lib/ruby/site_ruby/\1/puppet')
@@ -75,6 +87,9 @@ class foreman::params {
           # add passenger::install::scl as EL uses SCL on Foreman 1.2+
           $passenger_scl = 'ruby193'
           $plugin_prefix = 'ruby193-rubygem-foreman_'
+          $passenger_prestart = true
+          $passenger_min_instances = 1
+          $passenger_start_timeout = 600
         }
       }
     }
@@ -84,6 +99,24 @@ class foreman::params {
       $plugin_prefix = 'ruby-foreman-'
       $init_config = '/etc/default/foreman'
       $init_config_tmpl = 'foreman.default'
+
+      case $::lsbdistcodename {
+        /^(squeeze|precise)$/: {
+          $passenger_prestart = false
+          $passenger_min_instances = 0
+          $passenger_start_timeout = 0
+        }
+        /^wheezy$/: {
+          $passenger_prestart = false
+          $passenger_min_instances = 1
+          $passenger_start_timeout = 0
+        }
+        default: {
+          $passenger_prestart = true
+          $passenger_min_instances = 1
+          $passenger_start_timeout = 600
+        }
+      }
     }
     'Linux': {
       case $::operatingsystem {
@@ -95,6 +128,9 @@ class foreman::params {
           $plugin_prefix = 'ruby193-rubygem-foreman_'
           $init_config = '/etc/sysconfig/foreman'
           $init_config_tmpl = 'foreman.sysconfig'
+          $passenger_prestart = true
+          $passenger_min_instances = 1
+          $passenger_start_timeout = 600
         }
         default: {
           fail("${::hostname}: This module does not support operatingsystem ${::operatingsystem}")
diff --git a/spec/classes/foreman_config_passenger_spec.rb b/spec/classes/foreman_config_passenger_spec.rb
index 9cf3e38..fb318f8 100644
--- a/spec/classes/foreman_config_passenger_spec.rb
+++ b/spec/classes/foreman_config_passenger_spec.rb
@@ -2,91 +2,154 @@ require 'spec_helper'
 
 
 describe 'foreman::config::passenger' do
-  let :facts do {
-    :concat_basedir         => '/nonexistant',
-    :fqdn                   => 'foreman.example.org',
-    :operatingsystem        => 'RedHat',
-    :operatingsystemrelease => '6.4',
-    :osfamily               => 'RedHat',
-  } end
-
-  describe 'with minimal parameters' do
-    let :params do {
-      :app_root => '/usr/share/foreman',
-      :ssl      => false,
-      :user     => 'foreman',
+  context 'on redhat' do
+    let :facts do {
+      :concat_basedir          => '/nonexistant',
+      :fqdn                    => 'foreman.example.org',
+      :operatingsystem         => 'RedHat',
+      :operatingsystemrelease  => '6.4',
+      :osfamily                => 'RedHat',
     } end
 
-    it 'should include apache with modules' do
-      should contain_class('apache').that_comes_before('Anchor[foreman::config::passenger_end]')
-      should contain_class('apache::mod::headers')
-      should contain_class('apache::mod::passenger')
+    describe 'with minimal parameters' do
+      let :params do {
+        :app_root => '/usr/share/foreman',
+        :ssl      => false,
+        :user     => 'foreman',
+        :prestart      => true,
+        :min_instances => '1',
+        :start_timeout => '600',
+      } end
+
+      it 'should include apache with modules' do
+        should contain_class('apache').that_comes_before('Anchor[foreman::config::passenger_end]')
+        should contain_class('apache::mod::headers')
+        should contain_class('apache::mod::passenger')
+      end
+
+      it 'should ensure ownership' do
+        should contain_file("#{params[:app_root]}/config.ru").with_owner(params[:user])
+        should contain_file("#{params[:app_root]}/config/environment.rb").with_owner(params[:user])
+      end
     end
 
-    it 'should ensure ownership' do
-      should contain_file("#{params[:app_root]}/config.ru").with_owner(params[:user])
-      should contain_file("#{params[:app_root]}/config/environment.rb").with_owner(params[:user])
+    describe 'with vhost and ssl' do
+      let :params do {
+        :app_root  => '/usr/share/foreman',
+        :use_vhost => true,
+        :ssl       => true,
+        :ssl_cert  => 'cert.pem',
+        :ssl_key   => 'key.pem',
+        :ssl_ca    => 'ca.pem',
+        :prestart      => true,
+        :min_instances => '1',
+        :start_timeout => '600',
+      } end
+
+      it 'should contain the docroot' do
+        should contain_file("#{params[:app_root]}/public")
+      end
+
+      it 'should contain virt host plugin dir' do
+         should contain_file('/etc/httpd/conf.d/05-foreman.d').with({
+           'ensure'  => 'directory',
+         })
+      end
+
+      it 'should contain ssl virt host plugin dir' do
+         should contain_file('/etc/httpd/conf.d/05-foreman-ssl.d').with({
+           'ensure'  => 'directory',
+         })
+      end
+
+      it 'should include a http vhost' do
+        should contain_apache__vhost('foreman').with({
+          :ip              => nil,
+          :servername      => facts[:fqdn],
+          :serveraliases   => ['foreman'],
+          :docroot         => "#{params[:app_root]}/public",
+          :priority        => '05',
+          :options         => ['SymLinksIfOwnerMatch'],
+          :port            => 80,
+          :custom_fragment => %r{^<Directory #{params[:app_root]}/public>$},
+        })
+      end
+
+      it 'should include a pre-start http fragment' do
+        should contain_apache__vhost('foreman').with({
+          :custom_fragment => %r{^PassengerPreStart http://#{facts[:fqdn]}$},
+        })
+      end
+
+      it 'should include a https vhost' do
+        should contain_apache__vhost('foreman-ssl').with({
+          :ip                => nil,
+          :servername        => facts[:fqdn],
+          :serveraliases     => ['foreman'],
+          :docroot           => "#{params[:app_root]}/public",
+          :priority          => '05',
+          :options           => ['SymLinksIfOwnerMatch'],
+          :port              => 443,
+          :ssl               => true,
+          :ssl_cert          => params[:ssl_cert],
+          :ssl_key           => params[:ssl_key],
+          :ssl_chain         => params[:ssl_chain],
+          :ssl_ca            => params[:ssl_ca],
+          :ssl_verify_client => 'optional',
+          :ssl_options       => '+StdEnvVars',
+          :ssl_verify_depth  => '3',
+          :custom_fragment   => %r{^<Directory #{params[:app_root]}/public>$},
+        })
+      end
+
+      it 'should include a pre-start https fragment' do
+        should contain_apache__vhost('foreman-ssl').with({
+          :custom_fragment => %r{^PassengerPreStart https://#{facts[:fqdn]}$},
+        })
+      end
     end
   end
 
-  describe 'with vhost and ssl' do
-    let :params do {
-      :app_root  => '/usr/share/foreman',
-      :use_vhost => true,
-      :ssl       => true,
-      :ssl_cert  => 'cert.pem',
-      :ssl_key   => 'key.pem',
-      :ssl_ca    => 'ca.pem',
+  context 'on debian' do
+    let :facts do {
+      :concat_basedir         => '/nonexistant',
+      :fqdn                   => 'foreman.example.org',
+      :osfamily               => 'Debian',
+      :operatingsystem        => 'Debian',
+      :operatingsystemrelease => 'squeeze',
+      :lsbdistcodename        => 'squeeze',
     } end
 
-    it 'should contain the docroot' do
-      should contain_file("#{params[:app_root]}/public")
-    end
+    describe 'with vhost and ssl' do
+      let :params do {
+        :app_root  => '/usr/share/foreman',
+        :use_vhost => true,
+        :ssl       => true,
+        :ssl_cert  => 'cert.pem',
+        :ssl_key   => 'key.pem',
+        :ssl_ca    => 'ca.pem',
+        :prestart      => false,
+        :min_instances => '0',
+        :start_timeout => '0',
+      } end
 
-    it 'should contain virt host plugin dir' do
-       should contain_file('/etc/httpd/conf.d/05-foreman.d').with({
-         'ensure'  => 'directory',
-       })
-    end
+      it 'should not include a pre-start https fragment on Squeeze' do
+        should contain_apache__vhost('foreman-ssl').without({
+          :custom_fragment => %r{^PassengerPreStart},
+        })
+      end
 
-    it 'should contain ssl virt host plugin dir' do
-       should contain_file('/etc/httpd/conf.d/05-foreman-ssl.d').with({
-         'ensure'  => 'directory',
-       })
-    end
-
-    it 'should include a http vhost' do
-      should contain_apache__vhost('foreman').with({
-        :ip              => nil,
-        :servername      => facts[:fqdn],
-        :serveraliases   => ['foreman'],
-        :docroot         => "#{params[:app_root]}/public",
-        :priority        => '05',
-        :options         => ['SymLinksIfOwnerMatch'],
-        :port            => 80,
-        :custom_fragment => %r{^<Directory #{params[:app_root]}/public>$},
-      })
-    end
+      it 'should not include min instances fragment on Squeeze' do
+        should contain_apache__vhost('foreman-ssl').without({
+          :custom_fragment => %r{^PassengerMinInstances},
+        })
+      end
 
-    it 'should include a https vhost' do
-      should contain_apache__vhost('foreman-ssl').with({
-        :ip                => nil,
-        :servername        => facts[:fqdn],
-        :serveraliases     => ['foreman'],
-        :docroot           => "#{params[:app_root]}/public",
-        :priority          => '05',
-        :options           => ['SymLinksIfOwnerMatch'],
-        :port              => 443,
-        :ssl               => true,
-        :ssl_cert          => params[:ssl_cert],
-        :ssl_key           => params[:ssl_key],
-        :ssl_chain         => params[:ssl_chain],
-        :ssl_ca            => params[:ssl_ca],
-        :ssl_verify_client => 'optional',
-        :ssl_options       => '+StdEnvVars',
-        :ssl_verify_depth  => '3',
-        :custom_fragment   => %r{^<Directory #{params[:app_root]}/public>$},
-      })
+      it 'should not include start timeout fragment on Squeeze' do
+        should contain_apache__vhost('foreman-ssl').without({
+          :custom_fragment => %r{^PassengerStartTimeout},
+        })
+      end
     end
   end
 end
diff --git a/templates/_ssl_virt_host_include.erb b/templates/_ssl_virt_host_include.erb
index 77210d4..c025068 100644
--- a/templates/_ssl_virt_host_include.erb
+++ b/templates/_ssl_virt_host_include.erb
@@ -4,3 +4,4 @@
 <IfVersion >= 2.4>
   IncludeOptional <%= File.join(scope.lookupvar('apache::confd_dir'), '/05-foreman-ssl.d/*.conf') %>
 </IfVersion>
+<%= "PassengerPreStart https://#{@servername}\n" if @prestart -%>
diff --git a/templates/_virt_host_include.erb b/templates/_virt_host_include.erb
index aba5ea6..1045149 100644
--- a/templates/_virt_host_include.erb
+++ b/templates/_virt_host_include.erb
@@ -4,3 +4,4 @@
 <IfVersion >= 2.4>
   IncludeOptional <%= File.join(scope.lookupvar('apache::confd_dir'), '/05-foreman.d/*.conf') %>
 </IfVersion>
+<%= "PassengerPreStart http://#{@servername}\n" if @prestart -%>
diff --git a/templates/apache-fragment.conf.erb b/templates/apache-fragment.conf.erb
index ed12270..0c26783 100644
--- a/templates/apache-fragment.conf.erb
+++ b/templates/apache-fragment.conf.erb
@@ -2,5 +2,7 @@ PassengerAppRoot <%= @app_root %>
 <% if @scl_prefix and !@scl_prefix.empty? -%>
   PassengerRuby /usr/bin/<%= @scl_prefix -%>-ruby
 <% end -%>
+<%= "PassengerMinInstances #{@min_instances}\n" unless @min_instances == '0' -%>
+<%= "PassengerStartTimeout #{@start_timeout}\n" unless @start_timeout == '0' -%>
 
 AddDefaultCharset UTF-8
