passenger 5.0.6 → 5.0.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/CHANGELOG +26 -0
- data/Rakefile +0 -1
- data/bin/passenger-install-apache2-module +46 -12
- data/bin/passenger-status +6 -3
- data/build/packaging.rb +9 -1
- data/dev/ci/run_travis.sh +0 -36
- data/doc/ServerOptimizationGuide.html +12 -11
- data/doc/ServerOptimizationGuide.txt.md +12 -11
- data/doc/Users guide Apache.html +81 -75
- data/doc/Users guide Apache.idmap.txt +15 -13
- data/doc/Users guide Apache.txt +9 -1
- data/doc/Users guide Nginx.html +81 -76
- data/doc/Users guide Nginx.idmap.txt +15 -13
- data/doc/Users guide Nginx.txt +8 -0
- data/doc/Users guide Standalone.html +183 -24
- data/doc/Users guide Standalone.idmap.txt +19 -11
- data/doc/Users guide Standalone.txt +4 -0
- data/doc/users_guide_snippets/environment_variables.txt +2 -1
- data/doc/users_guide_snippets/installation.txt +15 -2
- data/doc/users_guide_snippets/tips.txt +19 -31
- data/doc/users_guide_snippets/under_the_hood/relationship_with_ruby.txt +7 -0
- data/ext/apache2/ConfigurationCommands.cpp +7 -0
- data/ext/apache2/ConfigurationFields.hpp +2 -0
- data/ext/apache2/ConfigurationSetters.cpp +8 -0
- data/ext/apache2/CreateDirConfig.cpp +1 -0
- data/ext/apache2/MergeDirConfig.cpp +7 -0
- data/ext/apache2/SetHeaders.cpp +5 -0
- data/ext/common/ApplicationPool2/Options.h +9 -0
- data/ext/common/Constants.h +3 -1
- data/ext/common/Logging.cpp +2 -2
- data/ext/common/ServerKit/HttpHeaderParser.h +13 -1
- data/ext/common/ServerKit/Implementation.cpp +7 -1
- data/ext/common/agents/Base.cpp +1 -1
- data/ext/common/agents/HelperAgent/OptionParser.h +15 -0
- data/ext/common/agents/HelperAgent/RequestHandler.h +3 -1
- data/ext/common/agents/HelperAgent/RequestHandler/BufferBody.cpp +3 -3
- data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +12 -1
- data/ext/common/agents/HelperAgent/RequestHandler/Utils.cpp +7 -3
- data/ext/common/agents/HelperAgent/ResponseCache.h +7 -1
- data/ext/common/agents/LoggingAgent/Main.cpp +4 -1
- data/ext/nginx/CacheLocationConfig.c +20 -0
- data/ext/nginx/Configuration.c +7 -0
- data/ext/nginx/ConfigurationCommands.c +10 -0
- data/ext/nginx/ConfigurationFields.h +2 -0
- data/ext/nginx/ContentHandler.c +10 -0
- data/ext/nginx/CreateLocationConfig.c +5 -0
- data/ext/nginx/MergeLocationConfig.c +6 -0
- data/helper-scripts/meteor-loader.rb +15 -2
- data/helper-scripts/rack-loader.rb +2 -6
- data/helper-scripts/rack-preloader.rb +1 -5
- data/lib/phusion_passenger.rb +3 -3
- data/lib/phusion_passenger/apache2/config_options.rb +5 -0
- data/lib/phusion_passenger/config/command.rb +9 -0
- data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +4 -0
- data/lib/phusion_passenger/config/validate_install_command.rb +478 -46
- data/lib/phusion_passenger/constants.rb +1 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +26 -3
- data/lib/phusion_passenger/nginx/config_options.rb +4 -0
- data/lib/phusion_passenger/packaging.rb +0 -8
- data/lib/phusion_passenger/platform_info/apache.rb +40 -28
- data/lib/phusion_passenger/platform_info/apache_detector.rb +29 -3
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +12 -7
- data/lib/phusion_passenger/request_handler/thread_handler.rb +5 -0
- data/lib/phusion_passenger/standalone/start_command.rb +46 -5
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +5 -3
- data/resources/templates/apache2/config_snippets.txt.erb +1 -1
- data/resources/templates/apache2/run_installer_as_root_for_apache_analysis.txt.erb +9 -0
- data/resources/templates/standalone/config.erb +16 -1
- metadata +3 -3
- metadata.gz.asc +7 -7
- data/build/debian.rb +0 -213
@@ -87,6 +87,7 @@ module PhusionPassenger
|
|
87
87
|
# Misc
|
88
88
|
FEEDBACK_FD = 3
|
89
89
|
PROGRAM_NAME = "Phusion Passenger"
|
90
|
+
SHORT_PROGRAM_NAME = "Passenger"
|
90
91
|
SERVER_TOKEN_NAME = "Phusion_Passenger"
|
91
92
|
FLYING_PASSENGER_NAME = "Flying Passenger"
|
92
93
|
INDEX_DOC_URL = "https://www.phusionpassenger.com/documentation/Users%20guide.html"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: binary
|
2
2
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
# Copyright (c) 2011-
|
3
|
+
# Copyright (c) 2011-2015 Phusion
|
4
4
|
#
|
5
5
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
#
|
@@ -274,8 +274,7 @@ module PhusionPassenger
|
|
274
274
|
# there's always the load_path_setup_file option and
|
275
275
|
# setup_load_paths.rb.
|
276
276
|
running_bundler(options) do
|
277
|
-
|
278
|
-
require 'bundler/setup'
|
277
|
+
activate_gem 'bundler', 'bundler/setup'
|
279
278
|
end
|
280
279
|
end
|
281
280
|
|
@@ -376,6 +375,30 @@ module PhusionPassenger
|
|
376
375
|
PhusionPassenger.call_event(:stopping_worker_process)
|
377
376
|
end
|
378
377
|
|
378
|
+
# Activate a gem and require it. This method exists in order to load
|
379
|
+
# a library from RubyGems instead of from vendor_ruby. For example,
|
380
|
+
# on Debian systems, Rack may be installed from APT, but that is usually
|
381
|
+
# a very old version which we don't want. This method ensures that the
|
382
|
+
# RubyGems-installed version is loaded, not the the version in vendor_ruby.
|
383
|
+
# See the following threads for discussion:
|
384
|
+
# https://github.com/phusion/passenger/issues/1478
|
385
|
+
# https://github.com/phusion/passenger/issues/1480
|
386
|
+
def activate_gem(gem_name, library_name = nil)
|
387
|
+
if !defined?(::Gem)
|
388
|
+
begin
|
389
|
+
require 'rubygems'
|
390
|
+
rescue LoadError
|
391
|
+
end
|
392
|
+
end
|
393
|
+
if Kernel.respond_to?(:gem, true)
|
394
|
+
begin
|
395
|
+
gem(gem_name)
|
396
|
+
rescue Gem::LoadError
|
397
|
+
end
|
398
|
+
end
|
399
|
+
require(library_name || gem_name)
|
400
|
+
end
|
401
|
+
|
379
402
|
private
|
380
403
|
def running_bundler(options)
|
381
404
|
yield
|
@@ -127,14 +127,10 @@ module PhusionPassenger
|
|
127
127
|
'Vagrantfile',
|
128
128
|
'Passenger.sublime-project',
|
129
129
|
'Passenger.xcodeproj/**/*',
|
130
|
-
'debian.template/**/*',
|
131
130
|
'packaging/**/*',
|
132
131
|
'test/**/*'
|
133
132
|
]
|
134
133
|
|
135
|
-
# Files that should be excluded from the Debian tarball.
|
136
|
-
DEBIAN_EXCLUDE_GLOB = []
|
137
|
-
|
138
134
|
# Files and directories that should be excluded from the Homebrew installation.
|
139
135
|
HOMEBREW_EXCLUDE = [
|
140
136
|
"package.json", "npm-shrinkwrap.json"
|
@@ -145,10 +141,6 @@ module PhusionPassenger
|
|
145
141
|
result.reject! { |path| path =~ %r{/\.\.?$} }
|
146
142
|
result
|
147
143
|
end
|
148
|
-
|
149
|
-
def self.debian_orig_tarball_files
|
150
|
-
files - Dir[*DEBIAN_EXCLUDE_GLOB]
|
151
|
-
end
|
152
144
|
end
|
153
145
|
|
154
146
|
end # module PhusionPassenger
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: binary
|
2
2
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
# Copyright (c) 2010-
|
3
|
+
# Copyright (c) 2010-2015 Phusion
|
4
4
|
#
|
5
5
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
#
|
@@ -26,6 +26,7 @@ PhusionPassenger.require_passenger_lib 'platform_info'
|
|
26
26
|
PhusionPassenger.require_passenger_lib 'platform_info/compiler'
|
27
27
|
PhusionPassenger.require_passenger_lib 'platform_info/operating_system'
|
28
28
|
PhusionPassenger.require_passenger_lib 'platform_info/linux'
|
29
|
+
PhusionPassenger.require_passenger_lib 'utils/shellwords'
|
29
30
|
|
30
31
|
module PhusionPassenger
|
31
32
|
|
@@ -101,47 +102,58 @@ module PhusionPassenger
|
|
101
102
|
end
|
102
103
|
memoize :httpd_version
|
103
104
|
|
104
|
-
# Run `
|
105
|
-
#
|
106
|
-
#
|
107
|
-
|
105
|
+
# Run `apache2ctl -V` and return its output.
|
106
|
+
#
|
107
|
+
# We used to run `httpd -V`, but on systems like Ubuntu it depends on various
|
108
|
+
# environment variables or directories, wich apache2ctl loads or initializes.
|
109
|
+
def self.apache2ctl_V(options = nil)
|
108
110
|
if options
|
109
|
-
|
111
|
+
apache2ctl = options[:apache2ctl] || self.apache2ctl(options)
|
110
112
|
else
|
111
|
-
|
113
|
+
apache2ctl = self.apache2ctl
|
112
114
|
end
|
113
|
-
if
|
114
|
-
|
115
|
-
|
116
|
-
|
115
|
+
if apache2ctl
|
116
|
+
create_temp_file("apache2ctl_V") do |filename, f|
|
117
|
+
e_filename = Shellwords.escape(filename)
|
118
|
+
output = `#{apache2ctl} -V 2>#{e_filename}`
|
119
|
+
|
120
|
+
stderr_text = File.open(filename, "rb") do |f2|
|
121
|
+
f2.read
|
122
|
+
end
|
123
|
+
# This stderr message shows up on Ubuntu. We ignore it.
|
124
|
+
stderr_text.sub!(/.*Could not reliably determine the server's fully qualified domain name.*\r?\n?/, "")
|
125
|
+
# But we print the rest of stderr.
|
126
|
+
STDERR.write(stderr_text)
|
127
|
+
STDERR.flush
|
128
|
+
|
129
|
+
output
|
117
130
|
end
|
118
|
-
return `#{command}`
|
119
131
|
else
|
120
|
-
|
132
|
+
nil
|
121
133
|
end
|
122
134
|
end
|
123
|
-
memoize :
|
135
|
+
memoize :apache2ctl_V
|
124
136
|
|
125
137
|
# The Apache executable's architectural bits. Returns 32 or 64,
|
126
138
|
# or nil if unable to detect.
|
127
139
|
def self.httpd_architecture_bits(options = nil)
|
128
140
|
if options
|
129
|
-
|
141
|
+
info = apache2ctl_V(options)
|
130
142
|
else
|
131
|
-
|
143
|
+
info = apache2ctl_V
|
132
144
|
end
|
133
|
-
if
|
134
|
-
|
145
|
+
if info
|
146
|
+
info =~ %r{Architecture:(.*)}
|
135
147
|
text = $1
|
136
148
|
if text =~ /32/
|
137
|
-
|
149
|
+
32
|
138
150
|
elsif text =~ /64/
|
139
|
-
|
151
|
+
64
|
140
152
|
else
|
141
|
-
|
153
|
+
nil
|
142
154
|
end
|
143
155
|
else
|
144
|
-
|
156
|
+
nil
|
145
157
|
end
|
146
158
|
end
|
147
159
|
memoize :httpd_architecture_bits
|
@@ -150,9 +162,9 @@ module PhusionPassenger
|
|
150
162
|
# This may be different from the value of the ServerRoot directive.
|
151
163
|
def self.httpd_default_root(options = nil)
|
152
164
|
if options
|
153
|
-
info =
|
165
|
+
info = apache2ctl_V(options)
|
154
166
|
else
|
155
|
-
info =
|
167
|
+
info = apache2ctl_V
|
156
168
|
end
|
157
169
|
if info
|
158
170
|
info =~ / -D HTTPD_ROOT="(.+)"$/
|
@@ -166,9 +178,9 @@ module PhusionPassenger
|
|
166
178
|
# The default Apache configuration file, or nil if Apache is not found.
|
167
179
|
def self.httpd_default_config_file(options = nil)
|
168
180
|
if options
|
169
|
-
info =
|
181
|
+
info = apache2ctl_V(options)
|
170
182
|
else
|
171
|
-
info =
|
183
|
+
info = apache2ctl_V
|
172
184
|
end
|
173
185
|
if info
|
174
186
|
info =~ /-D SERVER_CONFIG_FILE="(.+)"$/
|
@@ -216,7 +228,7 @@ module PhusionPassenger
|
|
216
228
|
# Returns nil if Apache is not detected, or if the default error log filename
|
217
229
|
# cannot be detected.
|
218
230
|
def self.httpd_default_error_log(options = nil)
|
219
|
-
if info =
|
231
|
+
if info = apache2ctl_V(options)
|
220
232
|
info =~ /-D DEFAULT_ERRORLOG="(.+)"$/
|
221
233
|
filename = $1
|
222
234
|
if filename =~ /\A\//
|
@@ -263,7 +275,7 @@ module PhusionPassenger
|
|
263
275
|
elsif contents =~ /ErrorLog/i
|
264
276
|
# The user apparently has ErrorLog set somewhere but
|
265
277
|
# we can't parse it. The default error log location,
|
266
|
-
# as reported by `
|
278
|
+
# as reported by `apache2ctl -V`, may be wrong (it is on OS X).
|
267
279
|
# So to be safe, let's assume that we don't know.
|
268
280
|
log "Unable to parse ErrorLog directive in Apache configuration file"
|
269
281
|
return nil
|
@@ -85,8 +85,9 @@ module PhusionPassenger
|
|
85
85
|
attr_reader :results
|
86
86
|
|
87
87
|
def initialize(output)
|
88
|
-
@output
|
89
|
-
@results
|
88
|
+
@output = output
|
89
|
+
@results = []
|
90
|
+
@failures = 0
|
90
91
|
PlatformInfo.verbose = true
|
91
92
|
PlatformInfo.log_implementation = lambda do |message|
|
92
93
|
if message =~ /: found$/
|
@@ -169,10 +170,31 @@ module PhusionPassenger
|
|
169
170
|
end
|
170
171
|
|
171
172
|
def report
|
173
|
+
if @failures > 0 && Process.uid != 0
|
174
|
+
user = `whoami`.strip
|
175
|
+
sudo_s_e = PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E")
|
176
|
+
ruby = PhusionPassenger::PlatformInfo.ruby_command
|
177
|
+
log ""
|
178
|
+
log "----------------------------"
|
179
|
+
log ""
|
180
|
+
log "<red>Permission problems</red>"
|
181
|
+
log ""
|
182
|
+
log "Sorry, this program doesn't have enough permissions to autodetect all your"
|
183
|
+
log "Apache installations, because it's running as the <b>#{`whoami`.strip}</b> user."
|
184
|
+
log "Please re-run this program with root privileges:"
|
185
|
+
log ""
|
186
|
+
log " <b>export ORIG_PATH=\"$PATH\"</b>"
|
187
|
+
log " <b>#{sudo_s_e}</b>"
|
188
|
+
log " <b>export PATH=\"$ORIG_PATH\"</b>"
|
189
|
+
log " <b>#{ruby} #{PhusionPassenger.bin_dir}/passenger-config --detect-apache2</b>"
|
190
|
+
return
|
191
|
+
end
|
192
|
+
|
172
193
|
log "<banner>Final autodetection results</banner>"
|
173
194
|
@results.each do |result|
|
174
195
|
result.report
|
175
196
|
end
|
197
|
+
|
176
198
|
if @results.empty?
|
177
199
|
log "<red>Sorry, this program cannot find an Apache installation.</red>"
|
178
200
|
log ""
|
@@ -223,7 +245,11 @@ module PhusionPassenger
|
|
223
245
|
|
224
246
|
def add_result
|
225
247
|
result = Result.new(self)
|
226
|
-
|
248
|
+
if yield(result)
|
249
|
+
@results << result
|
250
|
+
else
|
251
|
+
@failures += 1
|
252
|
+
end
|
227
253
|
end
|
228
254
|
end
|
229
255
|
|
@@ -81,6 +81,10 @@ module PhusionPassenger
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
# Rails somehow modifies env['REQUEST_METHOD'], so we perform the comparison
|
85
|
+
# before the Rack application object is called.
|
86
|
+
is_head_request = env[REQUEST_METHOD] == HEAD
|
87
|
+
|
84
88
|
begin
|
85
89
|
status, headers, body = @app.call(env)
|
86
90
|
rescue => e
|
@@ -101,7 +105,8 @@ module PhusionPassenger
|
|
101
105
|
return true if env[RACK_HIJACK_IO]
|
102
106
|
|
103
107
|
begin
|
104
|
-
process_body(env, connection, socket_wrapper, status.to_i,
|
108
|
+
process_body(env, connection, socket_wrapper, status.to_i, is_head_request,
|
109
|
+
headers, body)
|
105
110
|
rescue Exception => e
|
106
111
|
disable_keep_alive
|
107
112
|
raise
|
@@ -115,7 +120,7 @@ module PhusionPassenger
|
|
115
120
|
|
116
121
|
private
|
117
122
|
# The code here is ugly, but it's necessary for performance.
|
118
|
-
def process_body(env, connection, socket_wrapper, status, headers, body)
|
123
|
+
def process_body(env, connection, socket_wrapper, status, is_head_request, headers, body)
|
119
124
|
if hijack_callback = headers[RACK_HIJACK]
|
120
125
|
# Application requested a partial socket hijack.
|
121
126
|
body = nil
|
@@ -132,7 +137,7 @@ module PhusionPassenger
|
|
132
137
|
# object instead of a real Array, even when #is_a? claims so.
|
133
138
|
# Call #to_a just to be sure.
|
134
139
|
body = body.to_a
|
135
|
-
output_body = should_output_body?(status,
|
140
|
+
output_body = should_output_body?(status, is_head_request)
|
136
141
|
headers_output = generate_headers_array(status, headers)
|
137
142
|
perform_keep_alive(env, headers_output)
|
138
143
|
if output_body && should_add_message_length_header?(status, headers)
|
@@ -150,7 +155,7 @@ module PhusionPassenger
|
|
150
155
|
end
|
151
156
|
false
|
152
157
|
elsif body.is_a?(String)
|
153
|
-
output_body = should_output_body?(status,
|
158
|
+
output_body = should_output_body?(status, is_head_request)
|
154
159
|
headers_output = generate_headers_array(status, headers)
|
155
160
|
perform_keep_alive(env, headers_output)
|
156
161
|
if output_body && should_add_message_length_header?(status, headers)
|
@@ -165,7 +170,7 @@ module PhusionPassenger
|
|
165
170
|
connection.writev(headers_output)
|
166
171
|
false
|
167
172
|
else
|
168
|
-
output_body = should_output_body?(status,
|
173
|
+
output_body = should_output_body?(status, is_head_request)
|
169
174
|
headers_output = generate_headers_array(status, headers)
|
170
175
|
perform_keep_alive(env, headers_output)
|
171
176
|
chunk = output_body && should_add_message_length_header?(status, headers)
|
@@ -240,10 +245,10 @@ module PhusionPassenger
|
|
240
245
|
@keepalive_performed = false
|
241
246
|
end
|
242
247
|
|
243
|
-
def should_output_body?(status,
|
248
|
+
def should_output_body?(status, is_head_request)
|
244
249
|
return (status < 100 ||
|
245
250
|
(status >= 200 && status != 204 && status != 205 && status != 304)) &&
|
246
|
-
|
251
|
+
!is_head_request
|
247
252
|
end
|
248
253
|
|
249
254
|
def should_add_message_length_header?(status, headers)
|
@@ -245,6 +245,11 @@ module PhusionPassenger
|
|
245
245
|
request_method = $1
|
246
246
|
request_uri = $2
|
247
247
|
protocol = $3
|
248
|
+
if request_method.nil?
|
249
|
+
warn("*** Passenger RequestHandler warning: " <<
|
250
|
+
"Invalid HTTP request.")
|
251
|
+
return
|
252
|
+
end
|
248
253
|
path_info, query_string = request_uri.split("?", 2)
|
249
254
|
headers[REQUEST_METHOD] = request_method
|
250
255
|
headers["REQUEST_URI"] = request_uri
|
@@ -29,6 +29,7 @@ PhusionPassenger.require_passenger_lib 'standalone/command'
|
|
29
29
|
PhusionPassenger.require_passenger_lib 'standalone/config_utils'
|
30
30
|
PhusionPassenger.require_passenger_lib 'utils'
|
31
31
|
PhusionPassenger.require_passenger_lib 'utils/tmpio'
|
32
|
+
PhusionPassenger.require_passenger_lib 'platform_info/ruby'
|
32
33
|
|
33
34
|
# We lazy load as many libraries as possible not only to improve startup performance,
|
34
35
|
# but also to ensure that we don't require libraries before we've passed the dependency
|
@@ -73,20 +74,22 @@ module PhusionPassenger
|
|
73
74
|
watch_log_files_in_background if should_watch_logs?
|
74
75
|
wait_until_engine_has_exited if should_wait_until_engine_has_exited?
|
75
76
|
rescue Interrupt
|
76
|
-
|
77
|
+
trapsafe_shutdown_and_cleanup(true)
|
77
78
|
exit 2
|
78
79
|
rescue SignalException => signal
|
79
|
-
|
80
|
+
trapsafe_shutdown_and_cleanup(true)
|
80
81
|
if signal.message == 'SIGINT' || signal.message == 'SIGTERM'
|
81
82
|
exit 2
|
82
83
|
else
|
83
84
|
raise
|
84
85
|
end
|
85
86
|
rescue Exception
|
86
|
-
|
87
|
+
trapsafe_shutdown_and_cleanup(true)
|
87
88
|
raise
|
88
89
|
else
|
89
|
-
|
90
|
+
trapsafe_shutdown_and_cleanup(false)
|
91
|
+
ensure
|
92
|
+
reset_traps_intterm
|
90
93
|
end
|
91
94
|
end
|
92
95
|
|
@@ -172,6 +175,19 @@ module PhusionPassenger
|
|
172
175
|
"Default: #{DEFAULT_OPTIONS[:environment]}") do |value|
|
173
176
|
options[:environment] = value
|
174
177
|
end
|
178
|
+
opts.on("--ruby FILENAME", String, "Executable to use for Ruby apps#{nl}" +
|
179
|
+
"Default: " + PlatformInfo.ruby_command + " (current context)") do |value|
|
180
|
+
options[:ruby] = value
|
181
|
+
end
|
182
|
+
opts.on("--nodejs FILENAME", String, "Executable to use for NodeJs apps") do |value|
|
183
|
+
options[:nodejs] = value
|
184
|
+
end
|
185
|
+
opts.on("--python FILENAME", String, "Executable to use for Python apps") do |value|
|
186
|
+
options[:python] = value
|
187
|
+
end
|
188
|
+
opts.on("--meteor-app-settings FILENAME", String, "Settings file to use for (development mode) Meteor apps") do |value|
|
189
|
+
options[:meteor_app_settings] = value
|
190
|
+
end
|
175
191
|
opts.on("-R", "--rackup FILE", String,
|
176
192
|
"Consider application a Ruby app, and use#{nl}" +
|
177
193
|
"the given rackup file") do |value|
|
@@ -704,7 +720,32 @@ module PhusionPassenger
|
|
704
720
|
|
705
721
|
################## Shut down and cleanup ##################
|
706
722
|
|
707
|
-
def
|
723
|
+
def capture_traps_intterm
|
724
|
+
return if @traps_captured
|
725
|
+
@traps_captured = 1
|
726
|
+
trap("INT", &method(:trapped_intterm))
|
727
|
+
trap("TERM", &method(:trapped_intterm))
|
728
|
+
end
|
729
|
+
|
730
|
+
def reset_traps_intterm
|
731
|
+
@traps_captured = nil
|
732
|
+
trap("INT", "DEFAULT")
|
733
|
+
trap("TERM", "DEFAULT")
|
734
|
+
end
|
735
|
+
|
736
|
+
def trapped_intterm(signal)
|
737
|
+
if @traps_captured == 1
|
738
|
+
@traps_captured += 1
|
739
|
+
puts "Ignoring signal #{signal} during shutdown. Send it again to force exit."
|
740
|
+
else
|
741
|
+
exit!(1)
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
def trapsafe_shutdown_and_cleanup(error_occurred)
|
746
|
+
# Ignore INT and TERM once, to allow clean shutdown in e.g. Foreman
|
747
|
+
capture_traps_intterm
|
748
|
+
|
708
749
|
# Stop engine
|
709
750
|
if @engine && (error_occurred || should_wait_until_engine_has_exited?)
|
710
751
|
@console_mutex.synchronize do
|