passenger 5.0.0.beta3 → 5.0.0.rc1
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/.editorconfig +11 -5
- data/CHANGELOG +38 -0
- data/CONTRIBUTING.md +1 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/Rakefile +33 -33
- data/bin/passenger +1 -1
- data/bin/passenger-config +1 -1
- data/bin/passenger-install-apache2-module +800 -800
- data/bin/passenger-install-nginx-module +592 -592
- data/bin/passenger-memory-stats +127 -127
- data/bin/passenger-status +216 -216
- data/build/agents.rb +127 -127
- data/build/apache2.rb +87 -87
- data/build/basics.rb +60 -60
- data/build/common_library.rb +165 -165
- data/build/cplusplus_support.rb +51 -51
- data/build/cxx_tests.rb +268 -268
- data/build/debian.rb +143 -143
- data/build/documentation.rb +58 -58
- data/build/integration_tests.rb +81 -81
- data/build/misc.rb +132 -132
- data/build/nginx.rb +20 -20
- data/build/node_tests.rb +7 -7
- data/build/oxt_tests.rb +14 -14
- data/build/packaging.rb +570 -570
- data/build/preprocessor.rb +260 -260
- data/build/rake_extensions.rb +71 -71
- data/build/ruby_extension.rb +29 -29
- data/build/ruby_tests.rb +6 -6
- data/build/test_basics.rb +37 -37
- data/debian.template/control.template +3 -5
- data/dev/copy_boost_headers +134 -134
- data/dev/install_scripts_bootstrap_code.rb +25 -25
- data/dev/list_tests +20 -20
- data/dev/ruby_server.rb +223 -223
- data/dev/runner +18 -18
- data/doc/ServerOptimizationGuide.txt.md +55 -2
- data/doc/Users guide Nginx.txt +0 -26
- data/doc/Users guide Standalone.txt +5 -1
- data/doc/users_guide_snippets/tips.txt +9 -0
- data/ext/common/ApplicationPool2/Group.h +23 -11
- data/ext/common/ApplicationPool2/Implementation.cpp +32 -7
- data/ext/common/ApplicationPool2/Pool.h +22 -17
- data/ext/common/ApplicationPool2/SmartSpawner.h +4 -1
- data/ext/common/ApplicationPool2/Spawner.h +1 -1
- data/ext/common/Constants.h +1 -1
- data/ext/common/agents/Base.cpp +35 -20
- data/ext/common/agents/HelperAgent/Main.cpp +8 -1
- data/ext/common/agents/HelperAgent/OptionParser.h +18 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +2 -83
- data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +54 -1
- data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +7 -4
- data/ext/common/agents/Main.cpp +1 -1
- data/ext/common/agents/Watchdog/Main.cpp +54 -19
- data/ext/nginx/Configuration.c +7 -0
- data/ext/nginx/ContentHandler.c +9 -1
- data/helper-scripts/backtrace-sanitizer.rb +106 -87
- data/helper-scripts/crash-watch.rb +32 -0
- data/helper-scripts/download_binaries/extconf.rb +38 -38
- data/helper-scripts/meteor-loader.rb +107 -107
- data/helper-scripts/prespawn +101 -101
- data/helper-scripts/rack-loader.rb +96 -96
- data/helper-scripts/rack-preloader.rb +137 -137
- data/lib/phusion_passenger.rb +292 -292
- data/lib/phusion_passenger/abstract_installer.rb +438 -438
- data/lib/phusion_passenger/active_support3_extensions/init.rb +168 -170
- data/lib/phusion_passenger/admin_tools.rb +20 -20
- data/lib/phusion_passenger/admin_tools/instance.rb +178 -178
- data/lib/phusion_passenger/admin_tools/instance_registry.rb +61 -61
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +267 -267
- data/lib/phusion_passenger/apache2/config_options.rb +182 -182
- data/lib/phusion_passenger/common_library.rb +479 -485
- data/lib/phusion_passenger/config/about_command.rb +161 -161
- data/lib/phusion_passenger/config/admin_command_command.rb +129 -129
- data/lib/phusion_passenger/config/agent_compiler.rb +121 -121
- data/lib/phusion_passenger/config/build_native_support_command.rb +43 -43
- data/lib/phusion_passenger/config/command.rb +25 -25
- data/lib/phusion_passenger/config/compile_agent_command.rb +62 -62
- data/lib/phusion_passenger/config/compile_nginx_engine_command.rb +88 -73
- data/lib/phusion_passenger/config/detach_process_command.rb +72 -72
- data/lib/phusion_passenger/config/download_agent_command.rb +246 -227
- data/lib/phusion_passenger/config/download_nginx_engine_command.rb +245 -224
- data/lib/phusion_passenger/config/install_agent_command.rb +144 -132
- data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +205 -185
- data/lib/phusion_passenger/config/installation_utils.rb +204 -204
- data/lib/phusion_passenger/config/list_instances_command.rb +64 -64
- data/lib/phusion_passenger/config/main.rb +152 -152
- data/lib/phusion_passenger/config/nginx_engine_compiler.rb +319 -300
- data/lib/phusion_passenger/config/reopen_logs_command.rb +67 -67
- data/lib/phusion_passenger/config/restart_app_command.rb +155 -155
- data/lib/phusion_passenger/config/system_metrics_command.rb +13 -13
- data/lib/phusion_passenger/config/utils.rb +95 -95
- data/lib/phusion_passenger/config/validate_install_command.rb +198 -198
- data/lib/phusion_passenger/console_text_template.rb +25 -25
- data/lib/phusion_passenger/constants.rb +90 -90
- data/lib/phusion_passenger/debug_logging.rb +106 -106
- data/lib/phusion_passenger/loader_shared_helpers.rb +447 -432
- data/lib/phusion_passenger/message_channel.rb +312 -312
- data/lib/phusion_passenger/message_client.rb +176 -176
- data/lib/phusion_passenger/native_support.rb +369 -369
- data/lib/phusion_passenger/nginx/config_options.rb +297 -297
- data/lib/phusion_passenger/packaging.rb +131 -131
- data/lib/phusion_passenger/platform_info.rb +360 -360
- data/lib/phusion_passenger/platform_info/apache.rb +767 -767
- data/lib/phusion_passenger/platform_info/apache_detector.rb +199 -199
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +107 -107
- data/lib/phusion_passenger/platform_info/compiler.rb +570 -570
- data/lib/phusion_passenger/platform_info/curl.rb +32 -32
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +188 -188
- data/lib/phusion_passenger/platform_info/depcheck.rb +372 -372
- data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +109 -109
- data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
- data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +10 -34
- data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +101 -101
- data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -5
- data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +13 -13
- data/lib/phusion_passenger/platform_info/linux.rb +55 -55
- data/lib/phusion_passenger/platform_info/operating_system.rb +149 -149
- data/lib/phusion_passenger/platform_info/ruby.rb +468 -448
- data/lib/phusion_passenger/platform_info/zlib.rb +9 -9
- data/lib/phusion_passenger/plugin.rb +66 -66
- data/lib/phusion_passenger/preloader_shared_helpers.rb +126 -126
- data/lib/phusion_passenger/public_api.rb +191 -191
- data/lib/phusion_passenger/rack/out_of_band_gc.rb +93 -94
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +231 -227
- data/lib/phusion_passenger/request_handler.rb +567 -577
- data/lib/phusion_passenger/request_handler/thread_handler.rb +379 -381
- data/lib/phusion_passenger/ruby_core_enhancements.rb +86 -86
- data/lib/phusion_passenger/ruby_core_io_enhancements.rb +74 -74
- data/lib/phusion_passenger/simple_benchmarking.rb +25 -25
- data/lib/phusion_passenger/standalone/app_finder.rb +153 -150
- data/lib/phusion_passenger/standalone/command.rb +44 -40
- data/lib/phusion_passenger/standalone/config_utils.rb +53 -53
- data/lib/phusion_passenger/standalone/control_utils.rb +38 -59
- data/lib/phusion_passenger/standalone/main.rb +73 -73
- data/lib/phusion_passenger/standalone/start_command.rb +697 -685
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +193 -155
- data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +162 -133
- data/lib/phusion_passenger/standalone/status_command.rb +64 -64
- data/lib/phusion_passenger/standalone/stop_command.rb +72 -72
- data/lib/phusion_passenger/standalone/version_command.rb +9 -9
- data/lib/phusion_passenger/union_station/connection.rb +32 -32
- data/lib/phusion_passenger/union_station/core.rb +251 -251
- data/lib/phusion_passenger/union_station/transaction.rb +126 -126
- data/lib/phusion_passenger/utils.rb +199 -167
- data/lib/phusion_passenger/utils/ansi_colors.rb +128 -128
- data/lib/phusion_passenger/utils/download.rb +196 -196
- data/lib/phusion_passenger/utils/file_system_watcher.rb +158 -158
- data/lib/phusion_passenger/utils/hosts_file_parser.rb +101 -101
- data/lib/phusion_passenger/utils/lock.rb +31 -31
- data/lib/phusion_passenger/utils/native_support_utils.rb +31 -31
- data/lib/phusion_passenger/utils/progress_bar.rb +26 -26
- data/lib/phusion_passenger/utils/shellwords.rb +20 -20
- data/lib/phusion_passenger/utils/terminal_choice_menu.rb +206 -206
- data/lib/phusion_passenger/utils/unseekable_socket.rb +272 -272
- data/lib/phusion_passenger/vendor/crash_watch/app.rb +129 -0
- data/lib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +341 -0
- data/lib/phusion_passenger/vendor/crash_watch/version.rb +24 -0
- data/lib/phusion_passenger/vendor/daemon_controller.rb +877 -0
- data/lib/phusion_passenger/vendor/daemon_controller/lock_file.rb +127 -0
- data/lib/phusion_passenger/vendor/daemon_controller/spawn.rb +26 -0
- data/lib/phusion_passenger/vendor/daemon_controller/version.rb +29 -0
- data/packaging/rpm/passenger_spec/passenger.spec.template +0 -1
- data/passenger.gemspec +0 -1
- data/resources/templates/config/nginx_engine_compiler/possible_solutions_for_download_and_extraction_problems.txt.erb +27 -0
- data/resources/templates/standalone/config.erb +19 -15
- data/test/integration_tests/apache2_tests.rb +566 -566
- data/test/integration_tests/downloaded_binaries_tests.rb +126 -125
- data/test/integration_tests/native_packaging_spec.rb +296 -296
- data/test/integration_tests/nginx_tests.rb +393 -393
- data/test/integration_tests/shared/example_webapp_tests.rb +282 -280
- data/test/integration_tests/source_packaging_test.rb +138 -138
- data/test/integration_tests/spec_helper.rb +5 -5
- data/test/integration_tests/standalone_tests.rb +367 -367
- data/test/ruby/debug_logging_spec.rb +133 -133
- data/test/ruby/message_channel_spec.rb +186 -186
- data/test/ruby/rack/loader_spec.rb +28 -28
- data/test/ruby/rack/preloader_spec.rb +34 -34
- data/test/ruby/rails3.0/loader_spec.rb +12 -12
- data/test/ruby/rails3.0/preloader_spec.rb +18 -18
- data/test/ruby/rails3.1/loader_spec.rb +12 -12
- data/test/ruby/rails3.1/preloader_spec.rb +18 -18
- data/test/ruby/rails3.2/loader_spec.rb +12 -12
- data/test/ruby/rails3.2/preloader_spec.rb +18 -18
- data/test/ruby/rails4.0/loader_spec.rb +12 -12
- data/test/ruby/rails4.0/preloader_spec.rb +18 -18
- data/test/ruby/rails4.1/loader_spec.rb +12 -12
- data/test/ruby/rails4.1/preloader_spec.rb +18 -18
- data/test/ruby/request_handler_spec.rb +730 -730
- data/test/ruby/shared/loader_sharedspec.rb +224 -224
- data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +327 -327
- data/test/ruby/shared/ruby_loader_sharedspec.rb +47 -47
- data/test/ruby/spec_helper.rb +65 -65
- data/test/ruby/standalone/runtime_installer_spec.rb +384 -384
- data/test/ruby/union_station_spec.rb +276 -276
- data/test/ruby/utils/file_system_watcher_spec.rb +220 -220
- data/test/ruby/utils/hosts_file_parser.rb +248 -248
- data/test/ruby/utils/tee_input_spec.rb +215 -215
- data/test/ruby/utils/unseekable_socket_spec.rb +57 -57
- data/test/ruby/utils_spec.rb +21 -21
- data/test/stub/rack/config.ru +87 -87
- data/test/stub/rack/library.rb +8 -8
- data/test/stub/rack/start.rb +30 -30
- data/test/support/apache2_controller.rb +191 -191
- data/test/support/nginx_controller.rb +90 -99
- data/test/support/placebo-preloader.rb +57 -57
- data/test/support/test_helper.rb +435 -435
- metadata +11 -21
- metadata.gz.asc +7 -7
- data/lib/phusion_passenger/standalone/command2.rb +0 -292
- data/lib/phusion_passenger/standalone/start2_command.rb +0 -799
- data/resources/templates/standalone/download_tool_missing.txt.erb +0 -18
- data/resources/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -17
- data/resources/templates/standalone/run_installer_as_root.txt.erb +0 -8
data/bin/passenger-memory-stats
CHANGED
@@ -26,7 +26,7 @@
|
|
26
26
|
source_root = File.expand_path("..", File.dirname(__FILE__))
|
27
27
|
$LOAD_PATH.unshift("#{source_root}/lib")
|
28
28
|
begin
|
29
|
-
|
29
|
+
require 'rubygems'
|
30
30
|
rescue LoadError
|
31
31
|
end
|
32
32
|
require 'phusion_passenger'
|
@@ -42,136 +42,136 @@ include PhusionPassenger
|
|
42
42
|
|
43
43
|
# Container for tabular data.
|
44
44
|
class Table
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
45
|
+
def initialize(column_names, colors)
|
46
|
+
@column_names = column_names
|
47
|
+
@rows = []
|
48
|
+
@colors = colors
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_row(values)
|
52
|
+
@rows << values.to_a
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_rows(list_of_rows)
|
56
|
+
list_of_rows.each do |row|
|
57
|
+
add_row(row)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def remove_column(name)
|
62
|
+
i = @column_names.index(name)
|
63
|
+
@column_names.delete_at(i)
|
64
|
+
@rows.each do |row|
|
65
|
+
row.delete_at(i)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s(title = nil)
|
70
|
+
max_column_widths = [1] * @column_names.size
|
71
|
+
(@rows + [@column_names]).each do |row|
|
72
|
+
row.each_with_index do |value, i|
|
73
|
+
max_column_widths[i] = [value.to_s.size, max_column_widths[i]].max
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
format_string = max_column_widths.map{ |i| "%#{-i}s" }.join(" ")
|
78
|
+
header = sprintf(format_string, *@column_names).rstrip << "\n"
|
79
|
+
if title
|
80
|
+
free_space = header.size - title.size - 2
|
81
|
+
if free_space <= 0
|
82
|
+
left_bar_size = 3
|
83
|
+
right_bar_size = 3
|
84
|
+
else
|
85
|
+
left_bar_size = free_space / 2
|
86
|
+
right_bar_size = free_space - left_bar_size
|
87
|
+
end
|
88
|
+
result = "#{@colors.blue_bg}#{@colors.bold}#{@colors.yellow}\n"
|
89
|
+
result << "#{"-" * left_bar_size} #{title} #{"-" * right_bar_size}\n"
|
90
|
+
if !@rows.empty?
|
91
|
+
result << @colors.white
|
92
|
+
result << header
|
93
|
+
end
|
94
|
+
else
|
95
|
+
result = header.dup
|
96
|
+
end
|
97
|
+
if @rows.empty?
|
98
|
+
result << @colors.reset
|
99
|
+
else
|
100
|
+
result << ("-" * header.size) << "#{@colors.reset}\n"
|
101
|
+
@rows.each do |row|
|
102
|
+
result << sprintf(format_string, *row).rstrip << "\n"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
result
|
106
|
+
end
|
107
107
|
end
|
108
108
|
|
109
109
|
class App
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
110
|
+
def initialize
|
111
|
+
@stats = AdminTools::MemoryStats.new
|
112
|
+
@colors = Utils::AnsiColors.new
|
113
|
+
end
|
114
|
+
|
115
|
+
def start
|
116
|
+
puts "Version: #{PhusionPassenger::VERSION_STRING}"
|
117
|
+
puts "Date : #{Time.now}"
|
118
|
+
if @stats.apache_processes
|
119
|
+
print_process_list("Apache processes", @stats.apache_processes)
|
120
|
+
else
|
121
|
+
puts "#{@colors.blue_bg}#{@colors.bold}#{@colors.yellow}------------- Apache processes -------------#{@colors.reset}\n"
|
122
|
+
STDERR.puts "*** WARNING: The Apache executable cannot be found."
|
123
|
+
STDERR.puts "Please set the APXS2 environment variable to your 'apxs2' " <<
|
124
|
+
"executable's filename, or set the HTTPD environment variable " <<
|
125
|
+
"to your 'httpd' or 'apache2' executable's filename."
|
126
|
+
end
|
127
|
+
|
128
|
+
puts
|
129
|
+
print_process_list("Nginx processes", @stats.nginx_processes)
|
130
|
+
|
131
|
+
puts
|
132
|
+
print_process_list("Passenger processes", @stats.passenger_processes, :show_ppid => false)
|
133
|
+
|
134
|
+
if @stats.platform_provides_private_dirty_rss_information? &&
|
135
|
+
Process.euid != 0 &&
|
136
|
+
@stats.root_privileges_required_for_private_dirty_rss?
|
137
|
+
puts "*** WARNING: Please run this tool with #{@colors.bold}#{PlatformInfo.ruby_sudo_command}#{@colors.reset}. Otherwise the " <<
|
138
|
+
"private dirty RSS (a reliable metric for real memory usage) of processes cannot be determined."
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
142
|
private
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
143
|
+
def print_process_list(title, processes, options = {})
|
144
|
+
table = Table.new(%w{PID PPID VMSize Private Resident Name}, @colors)
|
145
|
+
table.add_rows(processes)
|
146
|
+
if options.has_key?(:show_ppid) && !options[:show_ppid]
|
147
|
+
table.remove_column('PPID')
|
148
|
+
end
|
149
|
+
if @stats.platform_provides_private_dirty_rss_information?
|
150
|
+
table.remove_column('Resident')
|
151
|
+
else
|
152
|
+
table.remove_column('Private')
|
153
|
+
end
|
154
|
+
puts table.to_s(title)
|
155
|
+
|
156
|
+
if @stats.platform_provides_private_dirty_rss_information?
|
157
|
+
total_private_dirty_rss = 0
|
158
|
+
some_private_dirty_rss_cannot_be_determined = false
|
159
|
+
processes.each do |p|
|
160
|
+
if p.private_dirty_rss.is_a?(Numeric)
|
161
|
+
total_private_dirty_rss += p.private_dirty_rss
|
162
|
+
else
|
163
|
+
some_private_dirty_rss_cannot_be_determined = true
|
164
|
+
end
|
165
|
+
end
|
166
|
+
puts "### Processes: #{processes.size}"
|
167
|
+
printf "### Total private dirty RSS: %.2f MB", total_private_dirty_rss / 1024.0
|
168
|
+
if some_private_dirty_rss_cannot_be_determined
|
169
|
+
puts " (?)"
|
170
|
+
else
|
171
|
+
puts
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
175
|
end
|
176
176
|
|
177
177
|
App.new.start
|
data/bin/passenger-status
CHANGED
@@ -26,7 +26,7 @@
|
|
26
26
|
source_root = File.expand_path("..", File.dirname(__FILE__))
|
27
27
|
$LOAD_PATH.unshift("#{source_root}/lib")
|
28
28
|
begin
|
29
|
-
|
29
|
+
require 'rubygems'
|
30
30
|
rescue LoadError
|
31
31
|
end
|
32
32
|
require 'phusion_passenger'
|
@@ -51,263 +51,263 @@ DEFAULT_OPTIONS = { :show => 'pool', :color => STDOUT.tty?, :header => true }.fr
|
|
51
51
|
##### Show status command #####
|
52
52
|
|
53
53
|
def command_show_status(argv, options)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
54
|
+
if argv.empty?
|
55
|
+
instance = find_sole_instance
|
56
|
+
else
|
57
|
+
instance = find_instance_by_name_prefix(argv[0])
|
58
|
+
end
|
59
|
+
show_status(instance, options)
|
60
60
|
end
|
61
61
|
|
62
62
|
def find_sole_instance
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
63
|
+
instances = InstanceRegistry.new.list
|
64
|
+
if instances.empty?
|
65
|
+
abort "ERROR: #{PROGRAM_NAME} doesn't seem to be running. If you " +
|
66
|
+
"are sure that it is running, then the causes of this problem could be:\n\n" +
|
67
|
+
"1. You customized the instance registry directory using Apache's " +
|
68
|
+
"PassengerInstanceRegistryDir option, Nginx's passenger_instance_registry_dir " +
|
69
|
+
"option, or #{PROGRAM_NAME} Standalone's --instance-registry-dir command line " +
|
70
|
+
"argument. If so, please set the environment variable PASSENGER_INSTANCE_REGISTRY_DIR " +
|
71
|
+
"to that directory and run passenger-status again.\n" +
|
72
|
+
"2. The instance directory has been removed by an operating system background service. " +
|
73
|
+
"Please set a different instance registry directory using Apache's " +
|
74
|
+
"PassengerInstanceRegistryDir option, Nginx's passenger_instance_registry_dir " +
|
75
|
+
"option, or #{PROGRAM_NAME} Standalone's --instance-registry-dir command line " +
|
76
|
+
"argument."
|
77
|
+
elsif instances.size == 1
|
78
|
+
return instances.first
|
79
|
+
else
|
80
|
+
puts "It appears that multiple #{PROGRAM_NAME} instances are running. Please"
|
81
|
+
puts "select a specific one by running:"
|
82
|
+
puts
|
83
|
+
puts " passenger-status <NAME>"
|
84
|
+
puts
|
85
|
+
puts "The following instances are running:"
|
86
|
+
puts
|
87
|
+
printf "%-25s %s\n", "Name", "Description"
|
88
|
+
puts "------------------------------------------------------------------"
|
89
|
+
instances.each do |instance|
|
90
|
+
printf "%-25s %s\n", instance.name, instance.server_software
|
91
|
+
end
|
92
|
+
exit 1
|
93
|
+
end
|
94
94
|
end
|
95
95
|
|
96
96
|
def find_instance_by_name_prefix(name)
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
97
|
+
instance = InstanceRegistry.new.find_by_name_prefix(name)
|
98
|
+
if instance == :ambigious
|
99
|
+
abort "ERROR: there are multiple instances whose name start with '#{name}'. Please specify the full name."
|
100
|
+
elsif instance
|
101
|
+
return instance
|
102
|
+
else
|
103
|
+
abort "ERROR: there doesn't seem to be a #{PROGRAM_NAME} instance running with the name '#{name}'."
|
104
|
+
end
|
105
105
|
end
|
106
106
|
|
107
107
|
def show_status(instance, options)
|
108
|
-
|
108
|
+
print_header(STDOUT, instance) if options[:header]
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
110
|
+
case options[:show]
|
111
|
+
when 'pool'
|
112
|
+
request = Net::HTTP::Get.new("/pool.txt?colorize=#{options[:color]}&verbose=#{options[:verbose]}")
|
113
|
+
request.basic_auth("ro_admin", obtain_read_only_admin_password(instance))
|
114
|
+
response = instance.http_request("agents.s/server_admin", request)
|
115
|
+
if response.code.to_i / 100 == 2
|
116
|
+
puts response.body
|
117
|
+
else
|
118
|
+
STDERR.puts "*** An error occured."
|
119
|
+
STDERR.puts "#{response.code}: #{response.body}"
|
120
|
+
exit 2
|
121
|
+
end
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
123
|
+
when 'requests', 'server'
|
124
|
+
request = Net::HTTP::Get.new("/server.json")
|
125
|
+
request.basic_auth("ro_admin", obtain_read_only_admin_password(instance))
|
126
|
+
response = instance.http_request("agents.s/server_admin", request)
|
127
|
+
if response.code.to_i / 100 == 2
|
128
|
+
puts response.body
|
129
|
+
else
|
130
|
+
STDERR.puts "*** An error occured."
|
131
|
+
STDERR.puts "#{response.code}: #{response.body}"
|
132
|
+
exit 2
|
133
|
+
end
|
134
134
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
when 'xml'
|
153
|
-
request = Net::HTTP::Get.new("/pool.xml")
|
154
|
-
request.basic_auth("ro_admin", obtain_read_only_admin_password(instance))
|
155
|
-
response = instance.http_request("agents.s/server_admin", request)
|
156
|
-
if response.code.to_i / 100 == 2
|
157
|
-
indented = format_with_xmllint(response.body)
|
158
|
-
if indented
|
159
|
-
puts indented
|
160
|
-
else
|
161
|
-
puts response.body
|
162
|
-
STDERR.puts "*** Tip: if you install the 'xmllint' command then the XML output will be indented."
|
163
|
-
end
|
164
|
-
else
|
165
|
-
STDERR.puts "*** An error occured."
|
166
|
-
STDERR.puts "#{response.code}: #{response.body}"
|
167
|
-
exit 2
|
168
|
-
end
|
135
|
+
when 'backtraces'
|
136
|
+
request = Net::HTTP::Get.new("/backtraces.txt")
|
137
|
+
request.basic_auth("ro_admin", obtain_read_only_admin_password(instance))
|
138
|
+
response = instance.http_request("agents.s/server_admin", request)
|
139
|
+
if response.code.to_i / 100 == 2
|
140
|
+
text = response.body
|
141
|
+
# Colorize output
|
142
|
+
color = PhusionPassenger::Utils::AnsiColors.new
|
143
|
+
text.gsub!(/^(Thread .*:)$/, color.black_bg + color.yellow + '\1' + color.reset)
|
144
|
+
text.gsub!(/^( +in '.*? )(.*?)\(/, '\1' + color.bold + '\2' + color.reset + '(')
|
145
|
+
puts text
|
146
|
+
else
|
147
|
+
STDERR.puts "*** An error occured."
|
148
|
+
STDERR.puts "#{response.code}: #{response.body}"
|
149
|
+
exit 2
|
150
|
+
end
|
169
151
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
152
|
+
when 'xml'
|
153
|
+
request = Net::HTTP::Get.new("/pool.xml?secrets=#{options[:verbose]}")
|
154
|
+
request.basic_auth("ro_admin", obtain_read_only_admin_password(instance))
|
155
|
+
response = instance.http_request("agents.s/server_admin", request)
|
156
|
+
if response.code.to_i / 100 == 2
|
157
|
+
indented = format_with_xmllint(response.body)
|
158
|
+
if indented
|
159
|
+
puts indented
|
160
|
+
else
|
161
|
+
puts response.body
|
162
|
+
STDERR.puts "*** Tip: if you install the 'xmllint' command then the XML output will be indented."
|
163
|
+
end
|
164
|
+
else
|
165
|
+
STDERR.puts "*** An error occured."
|
166
|
+
STDERR.puts "#{response.code}: #{response.body}"
|
167
|
+
exit 2
|
168
|
+
end
|
169
|
+
|
170
|
+
when 'union_station'
|
171
|
+
request = Net::HTTP::Get.new("/status.txt")
|
172
|
+
request.basic_auth("ro_admin", obtain_read_only_admin_password(instance))
|
173
|
+
response = instance.http_request("agents.s/logging_admin", request)
|
174
|
+
if response.code.to_i / 100 == 2
|
175
|
+
puts response.body
|
176
|
+
else
|
177
|
+
STDERR.puts "*** An error occured."
|
178
|
+
STDERR.puts "#{response.code}: #{response.body}"
|
179
|
+
exit 2
|
180
|
+
end
|
181
|
+
end
|
182
182
|
end
|
183
183
|
|
184
184
|
def print_header(io, instance)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
185
|
+
io.puts "Version : #{PhusionPassenger::VERSION_STRING}"
|
186
|
+
io.puts "Date : #{Time.now}"
|
187
|
+
io.puts "Instance: #{instance.name} (#{instance.server_software})"
|
188
|
+
io.puts
|
189
189
|
end
|
190
190
|
|
191
191
|
def obtain_read_only_admin_password(instance)
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
192
|
+
begin
|
193
|
+
password = instance.read_only_admin_password
|
194
|
+
rescue Errno::EACCES
|
195
|
+
print_permission_error_message
|
196
|
+
exit 2
|
197
|
+
end
|
198
198
|
end
|
199
199
|
|
200
200
|
def print_permission_error_message
|
201
|
-
|
202
|
-
|
203
|
-
|
201
|
+
PhusionPassenger.require_passenger_lib 'platform_info/ruby'
|
202
|
+
STDERR.puts "*** ERROR: You are not authorized to query the status for this " <<
|
203
|
+
"#{PROGRAM_NAME} instance. Please try again with '#{PhusionPassenger::PlatformInfo.ruby_sudo_command}'."
|
204
204
|
end
|
205
205
|
|
206
206
|
def format_with_xmllint(xml)
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
207
|
+
return nil if !PhusionPassenger::PlatformInfo.find_command('xmllint')
|
208
|
+
require 'open3'
|
209
|
+
require 'thread'
|
210
|
+
ENV['XMLLINT_INDENT'] = ' '
|
211
|
+
Open3.popen3("xmllint", "--format", "-") do |stdin, stdout, stderr|
|
212
|
+
stdout_text = nil
|
213
|
+
stderr_text = nil
|
214
|
+
thread1 = Thread.new do
|
215
|
+
stdin.write(xml)
|
216
|
+
stdin.close
|
217
|
+
end
|
218
|
+
thread2 = Thread.new do
|
219
|
+
stdout_text = stdout.read
|
220
|
+
stdout.close
|
221
|
+
end
|
222
|
+
thread3 = Thread.new do
|
223
|
+
stderr_text = stderr.read
|
224
|
+
stderr.close
|
225
|
+
end
|
226
|
+
thread1.join
|
227
|
+
thread2.join
|
228
|
+
thread3.join
|
229
|
+
|
230
|
+
if stdout_text.nil? || stdout_text.empty?
|
231
|
+
if stderr_text !~ /No such file or directory/ && stderr_text !~ /command not found/
|
232
|
+
STDERR.puts stderr_text
|
233
|
+
end
|
234
|
+
return nil
|
235
|
+
else
|
236
|
+
return stdout_text
|
237
|
+
end
|
238
|
+
end
|
239
239
|
end
|
240
240
|
|
241
241
|
|
242
242
|
##### Main command dispatcher #####
|
243
243
|
|
244
244
|
def create_option_parser(options)
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
245
|
+
return OptionParser.new do |opts|
|
246
|
+
nl = "\n" << " " * 37
|
247
|
+
opts.banner = "Usage: passenger-status [options] [instance name]"
|
248
|
+
opts.separator ""
|
249
|
+
opts.separator "Tool for inspecting Phusion Passenger's internal status."
|
250
|
+
opts.separator ""
|
251
251
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
252
|
+
opts.separator "Options:"
|
253
|
+
opts.on("--show=pool|server|backtraces|xml|union_station", String,
|
254
|
+
"Whether to show the pool's contents,#{nl}" <<
|
255
|
+
"the currently running requests,#{nl}" <<
|
256
|
+
"the backtraces of all threads or an XML#{nl}" <<
|
257
|
+
"description of the pool.") do |what|
|
258
|
+
if what !~ /\A(pool|server|requests|backtraces|xml|union_station)\Z/
|
259
|
+
STDERR.puts "Invalid argument for --show."
|
260
|
+
exit 1
|
261
|
+
else
|
262
|
+
options[:show] = what
|
263
|
+
end
|
264
|
+
end
|
265
|
+
opts.on("--no-header", "Do not display an informative header#{nl}" <<
|
266
|
+
"containing the timestamp, version number,#{nl}" <<
|
267
|
+
"etc.") do
|
268
|
+
options[:header] = false
|
269
|
+
end
|
270
|
+
opts.on("--force-colors", "Display colors even if stdout is not a TTY") do
|
271
|
+
options[:color] = true
|
272
|
+
end
|
273
|
+
opts.on("--verbose", "-v", "Show verbose information.") do
|
274
|
+
options[:verbose] = true
|
275
|
+
end
|
276
|
+
end
|
277
277
|
end
|
278
278
|
|
279
279
|
def parse_argv
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
280
|
+
options = DEFAULT_OPTIONS.dup
|
281
|
+
parser = create_option_parser(options)
|
282
|
+
begin
|
283
|
+
parser.parse!
|
284
|
+
rescue OptionParser::ParseError => e
|
285
|
+
puts e
|
286
|
+
puts
|
287
|
+
puts "Please see '--help' for valid options."
|
288
|
+
exit 1
|
289
|
+
end
|
290
290
|
|
291
|
-
|
291
|
+
return options
|
292
292
|
end
|
293
293
|
|
294
294
|
def infer_command
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
295
|
+
if !ARGV[0] || ARGV[0] !~ /^-/
|
296
|
+
return [:show_status, ARGV.dup]
|
297
|
+
else
|
298
|
+
command_name, *argv = ARGV
|
299
|
+
if respond_to?("command_#{command_name}")
|
300
|
+
return [command_name, argv]
|
301
|
+
else
|
302
|
+
abort "ERROR: unrecognized command '#{command_name}'"
|
303
|
+
end
|
304
|
+
end
|
305
305
|
end
|
306
306
|
|
307
307
|
def start
|
308
|
-
|
309
|
-
|
310
|
-
|
308
|
+
options = parse_argv
|
309
|
+
command, argv = infer_command
|
310
|
+
send("command_#{command}", argv, options)
|
311
311
|
end
|
312
312
|
|
313
313
|
start
|