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.

Files changed (218) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.editorconfig +11 -5
  5. data/CHANGELOG +38 -0
  6. data/CONTRIBUTING.md +1 -4
  7. data/Gemfile +0 -1
  8. data/Gemfile.lock +0 -2
  9. data/Rakefile +33 -33
  10. data/bin/passenger +1 -1
  11. data/bin/passenger-config +1 -1
  12. data/bin/passenger-install-apache2-module +800 -800
  13. data/bin/passenger-install-nginx-module +592 -592
  14. data/bin/passenger-memory-stats +127 -127
  15. data/bin/passenger-status +216 -216
  16. data/build/agents.rb +127 -127
  17. data/build/apache2.rb +87 -87
  18. data/build/basics.rb +60 -60
  19. data/build/common_library.rb +165 -165
  20. data/build/cplusplus_support.rb +51 -51
  21. data/build/cxx_tests.rb +268 -268
  22. data/build/debian.rb +143 -143
  23. data/build/documentation.rb +58 -58
  24. data/build/integration_tests.rb +81 -81
  25. data/build/misc.rb +132 -132
  26. data/build/nginx.rb +20 -20
  27. data/build/node_tests.rb +7 -7
  28. data/build/oxt_tests.rb +14 -14
  29. data/build/packaging.rb +570 -570
  30. data/build/preprocessor.rb +260 -260
  31. data/build/rake_extensions.rb +71 -71
  32. data/build/ruby_extension.rb +29 -29
  33. data/build/ruby_tests.rb +6 -6
  34. data/build/test_basics.rb +37 -37
  35. data/debian.template/control.template +3 -5
  36. data/dev/copy_boost_headers +134 -134
  37. data/dev/install_scripts_bootstrap_code.rb +25 -25
  38. data/dev/list_tests +20 -20
  39. data/dev/ruby_server.rb +223 -223
  40. data/dev/runner +18 -18
  41. data/doc/ServerOptimizationGuide.txt.md +55 -2
  42. data/doc/Users guide Nginx.txt +0 -26
  43. data/doc/Users guide Standalone.txt +5 -1
  44. data/doc/users_guide_snippets/tips.txt +9 -0
  45. data/ext/common/ApplicationPool2/Group.h +23 -11
  46. data/ext/common/ApplicationPool2/Implementation.cpp +32 -7
  47. data/ext/common/ApplicationPool2/Pool.h +22 -17
  48. data/ext/common/ApplicationPool2/SmartSpawner.h +4 -1
  49. data/ext/common/ApplicationPool2/Spawner.h +1 -1
  50. data/ext/common/Constants.h +1 -1
  51. data/ext/common/agents/Base.cpp +35 -20
  52. data/ext/common/agents/HelperAgent/Main.cpp +8 -1
  53. data/ext/common/agents/HelperAgent/OptionParser.h +18 -4
  54. data/ext/common/agents/HelperAgent/RequestHandler.h +2 -83
  55. data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +54 -1
  56. data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +7 -4
  57. data/ext/common/agents/Main.cpp +1 -1
  58. data/ext/common/agents/Watchdog/Main.cpp +54 -19
  59. data/ext/nginx/Configuration.c +7 -0
  60. data/ext/nginx/ContentHandler.c +9 -1
  61. data/helper-scripts/backtrace-sanitizer.rb +106 -87
  62. data/helper-scripts/crash-watch.rb +32 -0
  63. data/helper-scripts/download_binaries/extconf.rb +38 -38
  64. data/helper-scripts/meteor-loader.rb +107 -107
  65. data/helper-scripts/prespawn +101 -101
  66. data/helper-scripts/rack-loader.rb +96 -96
  67. data/helper-scripts/rack-preloader.rb +137 -137
  68. data/lib/phusion_passenger.rb +292 -292
  69. data/lib/phusion_passenger/abstract_installer.rb +438 -438
  70. data/lib/phusion_passenger/active_support3_extensions/init.rb +168 -170
  71. data/lib/phusion_passenger/admin_tools.rb +20 -20
  72. data/lib/phusion_passenger/admin_tools/instance.rb +178 -178
  73. data/lib/phusion_passenger/admin_tools/instance_registry.rb +61 -61
  74. data/lib/phusion_passenger/admin_tools/memory_stats.rb +267 -267
  75. data/lib/phusion_passenger/apache2/config_options.rb +182 -182
  76. data/lib/phusion_passenger/common_library.rb +479 -485
  77. data/lib/phusion_passenger/config/about_command.rb +161 -161
  78. data/lib/phusion_passenger/config/admin_command_command.rb +129 -129
  79. data/lib/phusion_passenger/config/agent_compiler.rb +121 -121
  80. data/lib/phusion_passenger/config/build_native_support_command.rb +43 -43
  81. data/lib/phusion_passenger/config/command.rb +25 -25
  82. data/lib/phusion_passenger/config/compile_agent_command.rb +62 -62
  83. data/lib/phusion_passenger/config/compile_nginx_engine_command.rb +88 -73
  84. data/lib/phusion_passenger/config/detach_process_command.rb +72 -72
  85. data/lib/phusion_passenger/config/download_agent_command.rb +246 -227
  86. data/lib/phusion_passenger/config/download_nginx_engine_command.rb +245 -224
  87. data/lib/phusion_passenger/config/install_agent_command.rb +144 -132
  88. data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +205 -185
  89. data/lib/phusion_passenger/config/installation_utils.rb +204 -204
  90. data/lib/phusion_passenger/config/list_instances_command.rb +64 -64
  91. data/lib/phusion_passenger/config/main.rb +152 -152
  92. data/lib/phusion_passenger/config/nginx_engine_compiler.rb +319 -300
  93. data/lib/phusion_passenger/config/reopen_logs_command.rb +67 -67
  94. data/lib/phusion_passenger/config/restart_app_command.rb +155 -155
  95. data/lib/phusion_passenger/config/system_metrics_command.rb +13 -13
  96. data/lib/phusion_passenger/config/utils.rb +95 -95
  97. data/lib/phusion_passenger/config/validate_install_command.rb +198 -198
  98. data/lib/phusion_passenger/console_text_template.rb +25 -25
  99. data/lib/phusion_passenger/constants.rb +90 -90
  100. data/lib/phusion_passenger/debug_logging.rb +106 -106
  101. data/lib/phusion_passenger/loader_shared_helpers.rb +447 -432
  102. data/lib/phusion_passenger/message_channel.rb +312 -312
  103. data/lib/phusion_passenger/message_client.rb +176 -176
  104. data/lib/phusion_passenger/native_support.rb +369 -369
  105. data/lib/phusion_passenger/nginx/config_options.rb +297 -297
  106. data/lib/phusion_passenger/packaging.rb +131 -131
  107. data/lib/phusion_passenger/platform_info.rb +360 -360
  108. data/lib/phusion_passenger/platform_info/apache.rb +767 -767
  109. data/lib/phusion_passenger/platform_info/apache_detector.rb +199 -199
  110. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +107 -107
  111. data/lib/phusion_passenger/platform_info/compiler.rb +570 -570
  112. data/lib/phusion_passenger/platform_info/curl.rb +32 -32
  113. data/lib/phusion_passenger/platform_info/cxx_portability.rb +188 -188
  114. data/lib/phusion_passenger/platform_info/depcheck.rb +372 -372
  115. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +109 -109
  116. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  117. data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +10 -34
  118. data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +101 -101
  119. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -5
  120. data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +13 -13
  121. data/lib/phusion_passenger/platform_info/linux.rb +55 -55
  122. data/lib/phusion_passenger/platform_info/operating_system.rb +149 -149
  123. data/lib/phusion_passenger/platform_info/ruby.rb +468 -448
  124. data/lib/phusion_passenger/platform_info/zlib.rb +9 -9
  125. data/lib/phusion_passenger/plugin.rb +66 -66
  126. data/lib/phusion_passenger/preloader_shared_helpers.rb +126 -126
  127. data/lib/phusion_passenger/public_api.rb +191 -191
  128. data/lib/phusion_passenger/rack/out_of_band_gc.rb +93 -94
  129. data/lib/phusion_passenger/rack/thread_handler_extension.rb +231 -227
  130. data/lib/phusion_passenger/request_handler.rb +567 -577
  131. data/lib/phusion_passenger/request_handler/thread_handler.rb +379 -381
  132. data/lib/phusion_passenger/ruby_core_enhancements.rb +86 -86
  133. data/lib/phusion_passenger/ruby_core_io_enhancements.rb +74 -74
  134. data/lib/phusion_passenger/simple_benchmarking.rb +25 -25
  135. data/lib/phusion_passenger/standalone/app_finder.rb +153 -150
  136. data/lib/phusion_passenger/standalone/command.rb +44 -40
  137. data/lib/phusion_passenger/standalone/config_utils.rb +53 -53
  138. data/lib/phusion_passenger/standalone/control_utils.rb +38 -59
  139. data/lib/phusion_passenger/standalone/main.rb +73 -73
  140. data/lib/phusion_passenger/standalone/start_command.rb +697 -685
  141. data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +193 -155
  142. data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +162 -133
  143. data/lib/phusion_passenger/standalone/status_command.rb +64 -64
  144. data/lib/phusion_passenger/standalone/stop_command.rb +72 -72
  145. data/lib/phusion_passenger/standalone/version_command.rb +9 -9
  146. data/lib/phusion_passenger/union_station/connection.rb +32 -32
  147. data/lib/phusion_passenger/union_station/core.rb +251 -251
  148. data/lib/phusion_passenger/union_station/transaction.rb +126 -126
  149. data/lib/phusion_passenger/utils.rb +199 -167
  150. data/lib/phusion_passenger/utils/ansi_colors.rb +128 -128
  151. data/lib/phusion_passenger/utils/download.rb +196 -196
  152. data/lib/phusion_passenger/utils/file_system_watcher.rb +158 -158
  153. data/lib/phusion_passenger/utils/hosts_file_parser.rb +101 -101
  154. data/lib/phusion_passenger/utils/lock.rb +31 -31
  155. data/lib/phusion_passenger/utils/native_support_utils.rb +31 -31
  156. data/lib/phusion_passenger/utils/progress_bar.rb +26 -26
  157. data/lib/phusion_passenger/utils/shellwords.rb +20 -20
  158. data/lib/phusion_passenger/utils/terminal_choice_menu.rb +206 -206
  159. data/lib/phusion_passenger/utils/unseekable_socket.rb +272 -272
  160. data/lib/phusion_passenger/vendor/crash_watch/app.rb +129 -0
  161. data/lib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +341 -0
  162. data/lib/phusion_passenger/vendor/crash_watch/version.rb +24 -0
  163. data/lib/phusion_passenger/vendor/daemon_controller.rb +877 -0
  164. data/lib/phusion_passenger/vendor/daemon_controller/lock_file.rb +127 -0
  165. data/lib/phusion_passenger/vendor/daemon_controller/spawn.rb +26 -0
  166. data/lib/phusion_passenger/vendor/daemon_controller/version.rb +29 -0
  167. data/packaging/rpm/passenger_spec/passenger.spec.template +0 -1
  168. data/passenger.gemspec +0 -1
  169. data/resources/templates/config/nginx_engine_compiler/possible_solutions_for_download_and_extraction_problems.txt.erb +27 -0
  170. data/resources/templates/standalone/config.erb +19 -15
  171. data/test/integration_tests/apache2_tests.rb +566 -566
  172. data/test/integration_tests/downloaded_binaries_tests.rb +126 -125
  173. data/test/integration_tests/native_packaging_spec.rb +296 -296
  174. data/test/integration_tests/nginx_tests.rb +393 -393
  175. data/test/integration_tests/shared/example_webapp_tests.rb +282 -280
  176. data/test/integration_tests/source_packaging_test.rb +138 -138
  177. data/test/integration_tests/spec_helper.rb +5 -5
  178. data/test/integration_tests/standalone_tests.rb +367 -367
  179. data/test/ruby/debug_logging_spec.rb +133 -133
  180. data/test/ruby/message_channel_spec.rb +186 -186
  181. data/test/ruby/rack/loader_spec.rb +28 -28
  182. data/test/ruby/rack/preloader_spec.rb +34 -34
  183. data/test/ruby/rails3.0/loader_spec.rb +12 -12
  184. data/test/ruby/rails3.0/preloader_spec.rb +18 -18
  185. data/test/ruby/rails3.1/loader_spec.rb +12 -12
  186. data/test/ruby/rails3.1/preloader_spec.rb +18 -18
  187. data/test/ruby/rails3.2/loader_spec.rb +12 -12
  188. data/test/ruby/rails3.2/preloader_spec.rb +18 -18
  189. data/test/ruby/rails4.0/loader_spec.rb +12 -12
  190. data/test/ruby/rails4.0/preloader_spec.rb +18 -18
  191. data/test/ruby/rails4.1/loader_spec.rb +12 -12
  192. data/test/ruby/rails4.1/preloader_spec.rb +18 -18
  193. data/test/ruby/request_handler_spec.rb +730 -730
  194. data/test/ruby/shared/loader_sharedspec.rb +224 -224
  195. data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +327 -327
  196. data/test/ruby/shared/ruby_loader_sharedspec.rb +47 -47
  197. data/test/ruby/spec_helper.rb +65 -65
  198. data/test/ruby/standalone/runtime_installer_spec.rb +384 -384
  199. data/test/ruby/union_station_spec.rb +276 -276
  200. data/test/ruby/utils/file_system_watcher_spec.rb +220 -220
  201. data/test/ruby/utils/hosts_file_parser.rb +248 -248
  202. data/test/ruby/utils/tee_input_spec.rb +215 -215
  203. data/test/ruby/utils/unseekable_socket_spec.rb +57 -57
  204. data/test/ruby/utils_spec.rb +21 -21
  205. data/test/stub/rack/config.ru +87 -87
  206. data/test/stub/rack/library.rb +8 -8
  207. data/test/stub/rack/start.rb +30 -30
  208. data/test/support/apache2_controller.rb +191 -191
  209. data/test/support/nginx_controller.rb +90 -99
  210. data/test/support/placebo-preloader.rb +57 -57
  211. data/test/support/test_helper.rb +435 -435
  212. metadata +11 -21
  213. metadata.gz.asc +7 -7
  214. data/lib/phusion_passenger/standalone/command2.rb +0 -292
  215. data/lib/phusion_passenger/standalone/start2_command.rb +0 -799
  216. data/resources/templates/standalone/download_tool_missing.txt.erb +0 -18
  217. data/resources/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -17
  218. data/resources/templates/standalone/run_installer_as_root.txt.erb +0 -8
@@ -1,5 +1,6 @@
1
+ # encoding: utf-8
1
2
  # Phusion Passenger - https://www.phusionpassenger.com/
2
- # Copyright (c) 2014 Phusion
3
+ # Copyright (c) 2014-2015 Phusion
3
4
  #
4
5
  # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
5
6
  #
@@ -25,160 +26,197 @@ require 'etc'
25
26
  PhusionPassenger.require_passenger_lib 'constants'
26
27
  PhusionPassenger.require_passenger_lib 'standalone/control_utils'
27
28
  PhusionPassenger.require_passenger_lib 'utils/shellwords'
29
+ PhusionPassenger.require_passenger_lib 'utils/json'
28
30
 
29
31
  module PhusionPassenger
30
- module Standalone
31
- class StartCommand
32
-
33
- module BuiltinEngine
34
- private
35
- def start_engine_real
36
- Standalone::ControlUtils.require_daemon_controller
37
- @engine = DaemonController.new(build_daemon_controller_options)
38
- start_engine_no_create
39
- end
40
-
41
- def start_engine_no_create
42
- begin
43
- @engine.start
44
- rescue DaemonController::AlreadyStarted
45
- begin
46
- pid = @engine.pid
47
- rescue SystemCallError, IOError
48
- pid = nil
49
- end
50
- if pid
51
- abort "#{PROGRAM_NAME} Standalone is already running on PID #{pid}."
52
- else
53
- abort "#{PROGRAM_NAME} Standalone is already running."
54
- end
55
- rescue DaemonController::StartError => e
56
- abort "Could not start the server engine:\n#{e}"
57
- end
58
- end
59
-
60
- def build_daemon_controller_options
61
- if @options[:socket_file]
62
- ping_spec = [:unix, @options[:socket_file]]
63
- else
64
- ping_spec = [:tcp, @options[:address], @options[:port]]
65
- end
66
-
67
- command = "#{@agent_exe} watchdog";
68
- command << " --passenger-root #{Shellwords.escape PhusionPassenger.install_spec}"
69
- command << " --daemonize"
70
- command << " --no-user-switching"
71
- command << " --no-delete-pid-file"
72
- command << " --cleanup-pidfile #{Shellwords.escape @working_dir}/temp_dir_toucher.pid"
73
- add_param(command, :user, "--user")
74
- add_param(command, :log_file, "--log-file")
75
- add_param(command, :pid_file, "--pid-file")
76
- add_param(command, :instance_registry_dir, "--instance-registry-dir")
77
- add_param(command, :data_buffer_dir, "--data-buffer-dir")
78
- add_param(command, :log_level, "--log-level")
79
- @options[:ctls].each do |ctl|
80
- command << " --ctl #{Shellwords.escape ctl}"
81
- end
82
- if @options[:user]
83
- command << " --default-user #{Shellwords.escape @options[:user]}"
84
- else
85
- user = Etc.getpwuid(Process.uid).name
86
- begin
87
- group = Etc.getgrgid(Process.gid)
88
- rescue ArgumentError
89
- # Do nothing. On Heroku, it's normal that the group
90
- # database is broken.
91
- else
92
- command << " --default-group #{Shellwords.escape group.name}"
93
- end
94
- command << " --default-user #{Shellwords.escape user}"
95
- end
96
-
97
- command << " --BS"
98
- command << " --listen #{listen_address}"
99
- command << " --no-graceful-exit"
100
- add_param(command, :environment, "--environment")
101
- add_param(command, :app_type, "--app-type")
102
- add_param(command, :startup_file, "--startup-file")
103
- add_param(command, :spawn_method, "--spawn-method")
104
- add_param(command, :restart_dir, "--restart-dir")
105
- if @options.has_key?(:friendly_error_pages)
106
- if @options[:friendly_error_pages]
107
- command << " --force-friendly-error-pages"
108
- else
109
- command << " --disable-friendly-error-pages"
110
- end
111
- end
112
- if @options[:turbocaching] == false
113
- command << " --disable-turbocaching"
114
- end
115
- add_flag_param(command, :load_shell_envvars, "--load-shell-envvars")
116
- add_param(command, :max_pool_size, "--max-pool-size")
117
- add_param(command, :min_instances, "--min-instances")
118
- add_enterprise_param(command, :concurrency_model, "--concurrency-model")
119
- add_enterprise_param(command, :thread_count, "--app-thread-count")
120
- add_enterprise_flag_param(command, :rolling_restarts, "--rolling-restarts")
121
- add_enterprise_flag_param(command, :resist_deployment_errors, "--resist-deployment-errors")
122
- add_flag_param(command, :sticky_sessions, "--sticky-sessions")
123
- add_param(command, :vary_turbocache_by_cookie, "--vary-turbocache-by-cookie")
124
- add_param(command, :sticky_sessions_cookie_name, "--sticky-sessions-cookie-name")
125
- add_param(command, :union_station_gateway_address, "--union-station-gateway-address")
126
- add_param(command, :union_station_gateway_port, "--union-station-gateway-port")
127
- add_param(command, :union_station_key, "--union-station-key")
128
-
129
- command << " #{Shellwords.escape(@apps[0][:root])}"
130
-
131
- return {
132
- :identifier => "#{AGENT_EXE} watchdog",
133
- :start_command => command,
134
- :ping_command => ping_spec,
135
- :pid_file => @options[:pid_file],
136
- :log_file => @options[:log_file],
137
- :timeout => 25
138
- }
139
- end
140
-
141
- def listen_address(options = @options, for_ping_port = false)
142
- if options[:socket_file]
143
- return "unix:" + File.absolute_path_no_resolve(options[:socket_file])
144
- else
145
- return "tcp://" + compose_ip_and_port(options[:address], options[:port])
146
- end
147
- end
148
-
149
- def add_param(command, option_name, param_name)
150
- if value = @options[option_name]
151
- command << " #{param_name} #{Shellwords.escape value.to_s}"
152
- end
153
- end
154
-
155
- def add_flag_param(command, option_name, param_name)
156
- if value = @options[option_name]
157
- command << " #{param_name}"
158
- end
159
- end
160
-
161
- def add_enterprise_param(command, option_name, param_name)
162
- if value = @options[option_name]
163
- abort "The '#{option_name}' feature is only available in #{PROGRAM_NAME} " +
164
- "Enterprise. You are currently running the open source #{PROGRAM_NAME}. " +
165
- "Please learn more about and/or buy #{PROGRAM_NAME} Enterprise at " +
166
- "https://www.phusionpassenger.com/enterprise"
167
- end
168
- end
169
-
170
- def add_enterprise_flag_param(command, option_name, param_name)
171
- if value = @options[option_name]
172
- abort "The '#{option_name}' feature is only available in #{PROGRAM_NAME} " +
173
- "Enterprise. You are currently running the open source #{PROGRAM_NAME}. " +
174
- "Please learn more about and/or buy #{PROGRAM_NAME} Enterprise at " +
175
- "https://www.phusionpassenger.com/enterprise"
176
- end
177
- end
178
-
179
- #####################
180
- end
181
-
182
- end # module StartCommand
183
- end # module Standalone
32
+ module Standalone
33
+ class StartCommand
34
+
35
+ module BuiltinEngine
36
+ private
37
+ def start_engine_real
38
+ Standalone::ControlUtils.require_daemon_controller
39
+ @engine = DaemonController.new(build_daemon_controller_options)
40
+ start_engine_no_create
41
+ end
42
+
43
+ def wait_until_engine_has_exited
44
+ lock = DaemonController::LockFile.new(read_watchdog_lock_file_path!)
45
+ lock.shared_lock do
46
+ # Do nothing
47
+ end
48
+ end
49
+
50
+
51
+ def start_engine_no_create
52
+ begin
53
+ @engine.start
54
+ rescue DaemonController::AlreadyStarted
55
+ begin
56
+ pid = @engine.pid
57
+ rescue SystemCallError, IOError
58
+ pid = nil
59
+ end
60
+ if pid
61
+ abort "#{PROGRAM_NAME} Standalone is already running on PID #{pid}."
62
+ else
63
+ abort "#{PROGRAM_NAME} Standalone is already running."
64
+ end
65
+ rescue DaemonController::StartError => e
66
+ abort "Could not start the server engine:\n#{e}"
67
+ end
68
+ end
69
+
70
+ def build_daemon_controller_options
71
+ if @options[:socket_file]
72
+ ping_spec = [:unix, @options[:socket_file]]
73
+ else
74
+ ping_spec = [:tcp, @options[:address], @options[:port]]
75
+ end
76
+
77
+ command = ""
78
+
79
+ if !@options[:envvars].empty?
80
+ command = "env "
81
+ @options[:envvars].each_pair do |name, value|
82
+ command << "#{Shellwords.escape name}=#{Shellwords.escape value} "
83
+ end
84
+ end
85
+
86
+ command << "#{@agent_exe} watchdog";
87
+ command << " --passenger-root #{Shellwords.escape PhusionPassenger.install_spec}"
88
+ command << " --daemonize"
89
+ command << " --no-user-switching"
90
+ command << " --no-delete-pid-file"
91
+ command << " --cleanup-pidfile #{Shellwords.escape @working_dir}/temp_dir_toucher.pid"
92
+ if should_wait_until_engine_has_exited?
93
+ command << " --report-file #{Shellwords.escape @working_dir}/report.json"
94
+ end
95
+ add_param(command, :user, "--user")
96
+ add_param(command, :log_file, "--log-file")
97
+ add_param(command, :pid_file, "--pid-file")
98
+ add_param(command, :instance_registry_dir, "--instance-registry-dir")
99
+ add_param(command, :data_buffer_dir, "--data-buffer-dir")
100
+ add_param(command, :log_level, "--log-level")
101
+ @options[:ctls].each do |ctl|
102
+ command << " --ctl #{Shellwords.escape ctl}"
103
+ end
104
+ if @options[:user]
105
+ command << " --default-user #{Shellwords.escape @options[:user]}"
106
+ else
107
+ user = Etc.getpwuid(Process.uid).name
108
+ begin
109
+ group = Etc.getgrgid(Process.gid)
110
+ rescue ArgumentError
111
+ # Do nothing. On Heroku, it's normal that the group
112
+ # database is broken.
113
+ else
114
+ command << " --default-group #{Shellwords.escape group.name}"
115
+ end
116
+ command << " --default-user #{Shellwords.escape user}"
117
+ end
118
+
119
+ command << " --BS"
120
+ command << " --listen #{listen_address}"
121
+ command << " --no-graceful-exit"
122
+ add_param(command, :environment, "--environment")
123
+ add_param(command, :app_type, "--app-type")
124
+ add_param(command, :startup_file, "--startup-file")
125
+ add_param(command, :spawn_method, "--spawn-method")
126
+ add_param(command, :restart_dir, "--restart-dir")
127
+ if @options.has_key?(:friendly_error_pages)
128
+ if @options[:friendly_error_pages]
129
+ command << " --force-friendly-error-pages"
130
+ else
131
+ command << " --disable-friendly-error-pages"
132
+ end
133
+ end
134
+ if @options[:turbocaching] == false
135
+ command << " --disable-turbocaching"
136
+ end
137
+ add_flag_param(command, :load_shell_envvars, "--load-shell-envvars")
138
+ add_param(command, :max_pool_size, "--max-pool-size")
139
+ add_param(command, :min_instances, "--min-instances")
140
+ add_enterprise_param(command, :concurrency_model, "--concurrency-model")
141
+ add_enterprise_param(command, :thread_count, "--app-thread-count")
142
+ add_enterprise_flag_param(command, :rolling_restarts, "--rolling-restarts")
143
+ add_enterprise_flag_param(command, :resist_deployment_errors, "--resist-deployment-errors")
144
+ add_enterprise_flag_param(command, :debugger, "--debugger")
145
+ add_flag_param(command, :sticky_sessions, "--sticky-sessions")
146
+ add_param(command, :vary_turbocache_by_cookie, "--vary-turbocache-by-cookie")
147
+ add_param(command, :sticky_sessions_cookie_name, "--sticky-sessions-cookie-name")
148
+ add_param(command, :union_station_gateway_address, "--union-station-gateway-address")
149
+ add_param(command, :union_station_gateway_port, "--union-station-gateway-port")
150
+ add_param(command, :union_station_key, "--union-station-key")
151
+
152
+ command << " #{Shellwords.escape(@apps[0][:root])}"
153
+
154
+ return {
155
+ :identifier => "#{AGENT_EXE} watchdog",
156
+ :start_command => command,
157
+ :ping_command => ping_spec,
158
+ :pid_file => @options[:pid_file],
159
+ :log_file => @options[:log_file],
160
+ :timeout => 25
161
+ }
162
+ end
163
+
164
+ def listen_address(options = @options, for_ping_port = false)
165
+ if options[:socket_file]
166
+ return "unix:" + File.absolute_path_no_resolve(options[:socket_file])
167
+ else
168
+ return "tcp://" + compose_ip_and_port(options[:address], options[:port])
169
+ end
170
+ end
171
+
172
+ def add_param(command, option_name, param_name)
173
+ if value = @options[option_name]
174
+ command << " #{param_name} #{Shellwords.escape value.to_s}"
175
+ end
176
+ end
177
+
178
+ def add_flag_param(command, option_name, param_name)
179
+ if value = @options[option_name]
180
+ command << " #{param_name}"
181
+ end
182
+ end
183
+
184
+ def add_enterprise_param(command, option_name, param_name)
185
+ if value = @options[option_name]
186
+ abort "The '#{option_name}' feature is only available in #{PROGRAM_NAME} " +
187
+ "Enterprise. You are currently running the open source #{PROGRAM_NAME}. " +
188
+ "Please learn more about and/or buy #{PROGRAM_NAME} Enterprise at " +
189
+ "https://www.phusionpassenger.com/enterprise"
190
+ end
191
+ end
192
+
193
+ def add_enterprise_flag_param(command, option_name, param_name)
194
+ if value = @options[option_name]
195
+ abort "The '#{option_name}' feature is only available in #{PROGRAM_NAME} " +
196
+ "Enterprise. You are currently running the open source #{PROGRAM_NAME}. " +
197
+ "Please learn more about and/or buy #{PROGRAM_NAME} Enterprise at " +
198
+ "https://www.phusionpassenger.com/enterprise"
199
+ end
200
+ end
201
+
202
+ def report_file_path
203
+ @report_file_path ||= "#{@working_dir}/report.json"
204
+ end
205
+
206
+ def read_watchdog_lock_file_path!
207
+ @watchdog_lock_file_path ||= begin
208
+ report = File.open(report_file_path, "r:utf-8") do |f|
209
+ Utils::JSON.parse(f.read)
210
+ end
211
+ # The report file may contain sensitive information, so delete it.
212
+ File.unlink(report_file_path)
213
+ report["instance_dir"] + "/lock"
214
+ end
215
+ end
216
+
217
+ #####################
218
+ end # module BuiltinEngine
219
+
220
+ end # module StartCommand
221
+ end # module Standalone
184
222
  end # module PhusionPassenger
@@ -1,5 +1,5 @@
1
1
  # Phusion Passenger - https://www.phusionpassenger.com/
2
- # Copyright (c) 2010-2014 Phusion
2
+ # Copyright (c) 2010-2015 Phusion
3
3
  #
4
4
  # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
5
5
  #
@@ -30,136 +30,165 @@ PhusionPassenger.require_passenger_lib 'utils/tmpio'
30
30
  PhusionPassenger.require_passenger_lib 'utils/shellwords'
31
31
 
32
32
  module PhusionPassenger
33
- module Standalone
34
- class StartCommand
35
-
36
- module NginxEngine
37
- private
38
- def start_engine_real
39
- Standalone::ControlUtils.require_daemon_controller
40
- @engine = DaemonController.new(build_daemon_controller_options)
41
- write_nginx_config_file(nginx_config_path)
42
-
43
- begin
44
- @engine.start
45
- rescue DaemonController::AlreadyStarted
46
- begin
47
- pid = @engine.pid
48
- rescue SystemCallError, IOError
49
- pid = nil
50
- end
51
- if pid
52
- abort "#{PROGRAM_NAME} Standalone is already running on PID #{pid}."
53
- else
54
- abort "#{PROGRAM_NAME} Standalone is already running."
55
- end
56
- rescue DaemonController::StartError => e
57
- abort "Could not start the Nginx engine:\n#{e}"
58
- end
59
- end
60
-
61
- def build_daemon_controller_options
62
- if @options[:socket_file]
63
- ping_spec = [:unix, @options[:socket_file]]
64
- else
65
- ping_spec = [:tcp, @options[:address], @options[:port]]
66
- end
67
- return {
68
- :identifier => 'Nginx',
69
- :start_command => "#{@nginx_binary} " +
70
- "-c #{Shellwords.escape nginx_config_path} " +
71
- "-p #{Shellwords.escape @working_dir}",
72
- :ping_command => ping_spec,
73
- :pid_file => @options[:pid_file],
74
- :log_file => @options[:log_file],
75
- :timeout => 25
76
- }
77
- end
78
-
79
- def nginx_config_path
80
- return "#{@working_dir}/nginx.conf"
81
- end
82
-
83
- def write_nginx_config_file(path)
84
- File.open(path, 'w') do |f|
85
- f.chmod(0644)
86
- erb = ERB.new(File.read(nginx_config_template_filename), nil, "-")
87
- erb.filename = nginx_config_template_filename
88
- current_user = Etc.getpwuid(Process.uid).name
89
-
90
- # The template requires some helper methods which are defined in start_command.rb.
91
- output = erb.result(binding)
92
- f.write(output)
93
- puts output if debugging?
94
- end
95
- end
96
-
97
- def nginx_config_template_filename
98
- if @options[:nginx_config_template]
99
- return @options[:nginx_config_template]
100
- else
101
- return File.join(PhusionPassenger.resources_dir,
102
- "templates", "standalone", "config.erb")
103
- end
104
- end
105
-
106
- def debugging?
107
- return ENV['PASSENGER_DEBUG'] && !ENV['PASSENGER_DEBUG'].empty?
108
- end
109
-
110
- #### Config file template helpers ####
111
-
112
- def nginx_listen_address(options = @options)
113
- if options[:socket_file]
114
- return "unix:" + File.absolute_path_no_resolve(options[:socket_file])
115
- else
116
- return compose_ip_and_port(options[:address], options[:port])
117
- end
118
- end
119
-
120
- def nginx_listen_address_with_ssl_port(options = @options)
121
- if options[:socket_file]
122
- return "unix:" + File.absolute_path_no_resolve(options[:socket_file])
123
- else
124
- return compose_ip_and_port(options[:address], options[:ssl_port])
125
- end
126
- end
127
-
128
- def default_group_for(username)
129
- user = Etc.getpwnam(username)
130
- group = Etc.getgrgid(user.gid)
131
- return group.name
132
- end
133
-
134
- def nginx_option(nginx_config_name, option_name)
135
- if @options[option_name]
136
- return "#{nginx_config_name} #{@options[option_name]};"
137
- end
138
- end
139
-
140
- def default_group_for(username)
141
- user = Etc.getpwnam(username)
142
- group = Etc.getgrgid(user.gid)
143
- return group.name
144
- end
145
-
146
- def boolean_config_value(val)
147
- return val ? "on" : "off"
148
- end
149
-
150
- def serialize_strset(*items)
151
- if "".respond_to?(:force_encoding)
152
- items = items.map { |x| x.force_encoding('binary') }
153
- null = "\0".force_encoding('binary')
154
- else
155
- null = "\0"
156
- end
157
- return [items.join(null)].pack('m*').gsub("\n", "").strip
158
- end
159
-
160
- #####################
161
- end
162
-
163
- end # module StartCommand
164
- end # module Standalone
33
+ module Standalone
34
+ class StartCommand
35
+
36
+ module NginxEngine
37
+ private
38
+ def start_engine_real
39
+ Standalone::ControlUtils.require_daemon_controller
40
+ @engine = DaemonController.new(build_daemon_controller_options)
41
+ write_nginx_config_file(nginx_config_path)
42
+
43
+ begin
44
+ @engine.start
45
+ rescue DaemonController::AlreadyStarted
46
+ begin
47
+ pid = @engine.pid
48
+ rescue SystemCallError, IOError
49
+ pid = nil
50
+ end
51
+ if pid
52
+ abort "#{PROGRAM_NAME} Standalone is already running on PID #{pid}."
53
+ else
54
+ abort "#{PROGRAM_NAME} Standalone is already running."
55
+ end
56
+ rescue DaemonController::StartError => e
57
+ abort "Could not start the Nginx engine:\n#{e}"
58
+ end
59
+ end
60
+
61
+ def wait_until_engine_has_exited
62
+ # Since the engine is not our child process (it daemonizes)
63
+ # we cannot use Process.waitpid to wait for it. A busy-sleep-loop with
64
+ # Process.kill(0, pid) isn't very efficient. Instead we do this:
65
+ #
66
+ # Connect to the engine's server and wait until it disconnects the socket
67
+ # because of timeout. Keep doing this until we can no longer connect.
68
+ while true
69
+ if @options[:socket_file]
70
+ socket = UNIXSocket.new(@options[:socket_file])
71
+ else
72
+ socket = TCPSocket.new(@options[:address], @options[:port])
73
+ end
74
+ begin
75
+ begin
76
+ socket.read
77
+ rescue SystemCallError, IOError, SocketError
78
+ end
79
+ ensure
80
+ begin
81
+ socket.close
82
+ rescue SystemCallError, IOError, SocketError
83
+ end
84
+ end
85
+ end
86
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET
87
+ end
88
+
89
+
90
+ def build_daemon_controller_options
91
+ if @options[:socket_file]
92
+ ping_spec = [:unix, @options[:socket_file]]
93
+ else
94
+ ping_spec = [:tcp, @options[:address], @options[:port]]
95
+ end
96
+ return {
97
+ :identifier => 'Nginx',
98
+ :start_command => "#{@nginx_binary} " +
99
+ "-c #{Shellwords.escape nginx_config_path} " +
100
+ "-p #{Shellwords.escape @working_dir}",
101
+ :ping_command => ping_spec,
102
+ :pid_file => @options[:pid_file],
103
+ :log_file => @options[:log_file],
104
+ :timeout => 25
105
+ }
106
+ end
107
+
108
+ def nginx_config_path
109
+ return "#{@working_dir}/nginx.conf"
110
+ end
111
+
112
+ def write_nginx_config_file(path)
113
+ File.open(path, 'w') do |f|
114
+ f.chmod(0644)
115
+ erb = ERB.new(File.read(nginx_config_template_filename), nil, "-")
116
+ erb.filename = nginx_config_template_filename
117
+ current_user = Etc.getpwuid(Process.uid).name
118
+
119
+ # The template requires some helper methods which are defined in start_command.rb.
120
+ output = erb.result(binding)
121
+ f.write(output)
122
+ puts output if debugging?
123
+ end
124
+ end
125
+
126
+ def nginx_config_template_filename
127
+ if @options[:nginx_config_template]
128
+ return @options[:nginx_config_template]
129
+ else
130
+ return File.join(PhusionPassenger.resources_dir,
131
+ "templates", "standalone", "config.erb")
132
+ end
133
+ end
134
+
135
+ def debugging?
136
+ return ENV['PASSENGER_DEBUG'] && !ENV['PASSENGER_DEBUG'].empty?
137
+ end
138
+
139
+ #### Config file template helpers ####
140
+
141
+ def nginx_listen_address(options = @options)
142
+ if options[:socket_file]
143
+ return "unix:" + File.absolute_path_no_resolve(options[:socket_file])
144
+ else
145
+ return compose_ip_and_port(options[:address], options[:port])
146
+ end
147
+ end
148
+
149
+ def nginx_listen_address_with_ssl_port(options = @options)
150
+ if options[:socket_file]
151
+ return "unix:" + File.absolute_path_no_resolve(options[:socket_file])
152
+ else
153
+ return compose_ip_and_port(options[:address], options[:ssl_port])
154
+ end
155
+ end
156
+
157
+ def default_group_for(username)
158
+ user = Etc.getpwnam(username)
159
+ group = Etc.getgrgid(user.gid)
160
+ return group.name
161
+ end
162
+
163
+ def nginx_option(nginx_config_name, option_name)
164
+ if @options[option_name]
165
+ return "#{nginx_config_name} #{@options[option_name]};"
166
+ end
167
+ end
168
+
169
+ def default_group_for(username)
170
+ user = Etc.getpwnam(username)
171
+ group = Etc.getgrgid(user.gid)
172
+ return group.name
173
+ end
174
+
175
+ def boolean_config_value(val)
176
+ return val ? "on" : "off"
177
+ end
178
+
179
+ def serialize_strset(*items)
180
+ if "".respond_to?(:force_encoding)
181
+ items = items.map { |x| x.force_encoding('binary') }
182
+ null = "\0".force_encoding('binary')
183
+ else
184
+ null = "\0"
185
+ end
186
+ return [items.join(null)].pack('m*').gsub("\n", "").strip
187
+ end
188
+
189
+ #####################
190
+ end # module NginxEngine
191
+
192
+ end # module StartCommand
193
+ end # module Standalone
165
194
  end # module PhusionPassenger