passenger 5.2.3 → 5.3.0

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 (241) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +13 -0
  3. data/CONTRIBUTORS +5 -1
  4. data/build/agent.rb +22 -2
  5. data/build/cxx_tests.rb +41 -5
  6. data/build/misc.rb +4 -1
  7. data/build/support/cxx_dependency_map.rb +1746 -908
  8. data/build/support/vendor/cxx_hinted_parser/CxxHintedParser.sublime-project +8 -0
  9. data/build/support/vendor/cxx_hinted_parser/Gemfile +5 -0
  10. data/build/support/vendor/cxx_hinted_parser/Gemfile.lock +30 -0
  11. data/{src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core → build/support/vendor/cxx_hinted_parser}/LICENSE.md +1 -1
  12. data/build/support/vendor/cxx_hinted_parser/README.md +95 -0
  13. data/build/support/vendor/cxx_hinted_parser/Rakefile +4 -0
  14. data/{src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/initialize.rb → build/support/vendor/cxx_hinted_parser/lib/cxx_hinted_parser.rb} +2 -9
  15. data/build/support/vendor/cxx_hinted_parser/lib/cxx_hinted_parser/parser.rb +239 -0
  16. data/dev/ci/README.md +15 -2
  17. data/dev/ci/lib/set-container-envvars.sh +6 -0
  18. data/dev/ci/lib/setup-container.sh +4 -1
  19. data/dev/ci/scripts/debug-console-wrapper.sh +3 -1
  20. data/dev/ci/setup-host +5 -0
  21. data/dev/ci/tests/binaries/Jenkinsfile +105 -0
  22. data/dev/ci/tests/binaries/build-linux +38 -0
  23. data/dev/ci/tests/binaries/build-macos +40 -0
  24. data/dev/ci/tests/binaries/prepare-macos +38 -0
  25. data/dev/ci/tests/binaries/test-linux +45 -0
  26. data/dev/ci/tests/binaries/test-macos +38 -0
  27. data/dev/ci/tests/debian/Jenkinsfile +2 -2
  28. data/dev/ci/tests/rpm/Jenkinsfile +1 -1
  29. data/dev/configkit-schemas/index.json +3 -24
  30. data/dev/vagrant/nginx_rakefile +0 -1
  31. data/package.json +15 -5
  32. data/resources/templates/error_renderer/.editorconfig +19 -0
  33. data/resources/templates/error_renderer/with_details/README.md +9 -0
  34. data/resources/templates/error_renderer/with_details/dist/bundle.js +33 -0
  35. data/resources/templates/error_renderer/with_details/dist/styles.css +17 -0
  36. data/resources/templates/error_renderer/with_details/src/DetailsView.jsx +52 -0
  37. data/resources/templates/error_renderer/with_details/src/GetHelpView.jsx +61 -0
  38. data/resources/templates/error_renderer/with_details/src/JourneyView.css +50 -0
  39. data/resources/templates/error_renderer/with_details/src/JourneyView.jsx +621 -0
  40. data/resources/templates/error_renderer/with_details/src/PageMain.css +114 -0
  41. data/resources/templates/error_renderer/with_details/src/PageMain.jsx +136 -0
  42. data/resources/templates/error_renderer/with_details/src/ProblemDescriptionView.jsx +14 -0
  43. data/resources/templates/error_renderer/with_details/src/ProcessDetailsView.jsx +56 -0
  44. data/resources/templates/error_renderer/with_details/src/SolutionDescriptionView.css +5 -0
  45. data/resources/templates/error_renderer/with_details/src/SolutionDescriptionView.jsx +15 -0
  46. data/resources/templates/error_renderer/with_details/src/SummaryView.jsx +35 -0
  47. data/resources/templates/error_renderer/with_details/src/SystemComponentView.css +34 -0
  48. data/resources/templates/error_renderer/with_details/src/SystemComponentView.jsx +168 -0
  49. data/resources/templates/error_renderer/with_details/src/SystemComponentsView.css +13 -0
  50. data/resources/templates/error_renderer/with_details/src/SystemComponentsView.jsx +116 -0
  51. data/resources/templates/error_renderer/with_details/src/Tab.jsx +12 -0
  52. data/resources/templates/error_renderer/with_details/src/Tabs.jsx +104 -0
  53. data/resources/templates/error_renderer/with_details/src/bootstrap/bootstrap.css +3446 -0
  54. data/resources/templates/error_renderer/with_details/src/bootstrap/bootstrap.js +293 -0
  55. data/resources/templates/error_renderer/with_details/src/bootstrap/config.json +401 -0
  56. data/resources/templates/error_renderer/with_details/src/index.html.template +22 -0
  57. data/resources/templates/error_renderer/with_details/src/index.jsx +23 -0
  58. data/resources/templates/error_renderer/with_details/webpack.config.js +47 -0
  59. data/resources/templates/error_renderer/without_details/dist/bundle.js +1 -0
  60. data/resources/templates/error_renderer/without_details/dist/styles.css +1 -0
  61. data/resources/templates/{undisclosed_error.html.template → error_renderer/without_details/src/index.html.template} +7 -11
  62. data/resources/templates/error_renderer/without_details/src/index.js +1 -0
  63. data/resources/templates/{error_layout.css → error_renderer/without_details/src/main.css} +5 -2
  64. data/resources/templates/error_renderer/without_details/webpack.config.js +42 -0
  65. data/src/agent/AgentMain.cpp +3 -3
  66. data/src/agent/Core/ApplicationPool/BasicProcessInfo.h +13 -0
  67. data/src/agent/Core/ApplicationPool/Common.h +3 -4
  68. data/src/agent/Core/ApplicationPool/Context.h +27 -17
  69. data/src/agent/Core/ApplicationPool/Group.h +3 -1
  70. data/src/agent/Core/ApplicationPool/Group/InitializationAndShutdown.cpp +2 -12
  71. data/src/agent/Core/ApplicationPool/Group/InternalUtils.cpp +55 -10
  72. data/src/agent/Core/ApplicationPool/Group/LifetimeAndBasics.cpp +1 -1
  73. data/src/agent/Core/ApplicationPool/Group/OutOfBandWork.cpp +1 -1
  74. data/src/agent/Core/ApplicationPool/Group/SpawningAndRestarting.cpp +13 -6
  75. data/src/agent/Core/ApplicationPool/Implementation.cpp +16 -100
  76. data/src/agent/Core/ApplicationPool/Options.h +8 -65
  77. data/src/agent/Core/ApplicationPool/Pool.h +4 -21
  78. data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +1 -60
  79. data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +10 -13
  80. data/src/agent/Core/ApplicationPool/Pool/InitializationAndShutdown.cpp +3 -8
  81. data/src/agent/Core/ApplicationPool/Pool/Miscellaneous.cpp +2 -34
  82. data/src/agent/Core/ApplicationPool/Pool/StateInspection.cpp +1 -1
  83. data/src/agent/Core/ApplicationPool/Process.cpp +17 -12
  84. data/src/agent/Core/ApplicationPool/Process.h +146 -93
  85. data/src/agent/Core/ApplicationPool/Session.h +2 -2
  86. data/src/agent/Core/ApplicationPool/Socket.h +28 -27
  87. data/src/agent/Core/Config.h +1 -3
  88. data/src/agent/Core/ConfigChange.cpp +2 -4
  89. data/src/agent/Core/Controller.h +2 -8
  90. data/src/agent/Core/Controller/BufferBody.cpp +0 -2
  91. data/src/agent/Core/Controller/CheckoutSession.cpp +12 -24
  92. data/src/agent/Core/Controller/Config.h +1 -9
  93. data/src/agent/Core/Controller/ForwardResponse.cpp +0 -34
  94. data/src/agent/Core/Controller/Hooks.cpp +0 -7
  95. data/src/agent/Core/Controller/InitRequest.cpp +0 -43
  96. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +0 -4
  97. data/src/agent/Core/Controller/Request.h +1 -35
  98. data/src/agent/Core/Controller/SendRequest.cpp +0 -32
  99. data/src/agent/Core/CoreMain.cpp +19 -32
  100. data/src/agent/Core/SpawningKit/Config.h +329 -55
  101. data/src/agent/Core/SpawningKit/Config/AutoGeneratedCode.h +369 -0
  102. data/src/agent/Core/SpawningKit/Config/AutoGeneratedCode.h.cxxcodebuilder +307 -0
  103. data/src/agent/Core/SpawningKit/Context.h +211 -0
  104. data/src/agent/Core/SpawningKit/DirectSpawner.h +112 -122
  105. data/src/agent/Core/SpawningKit/DummySpawner.h +59 -20
  106. data/src/agent/Core/SpawningKit/ErrorRenderer.h +117 -0
  107. data/src/agent/Core/SpawningKit/Exceptions.h +1157 -0
  108. data/src/agent/Core/SpawningKit/Factory.h +24 -17
  109. data/src/agent/Core/SpawningKit/{BackgroundIOCapturer.h → Handshake/BackgroundIOCapturer.h} +48 -18
  110. data/src/agent/Core/SpawningKit/Handshake/Perform.h +1650 -0
  111. data/src/agent/Core/SpawningKit/Handshake/Prepare.h +582 -0
  112. data/src/agent/Core/SpawningKit/Handshake/Session.h +91 -0
  113. data/src/agent/Core/SpawningKit/Handshake/WorkDir.h +100 -0
  114. data/src/agent/Core/SpawningKit/Journey.h +561 -0
  115. data/src/agent/Core/SpawningKit/PipeWatcher.h +41 -18
  116. data/src/agent/Core/SpawningKit/README.md +534 -0
  117. data/src/agent/Core/SpawningKit/Result.h +182 -7
  118. data/src/agent/Core/SpawningKit/Result/AutoGeneratedCode.h +69 -0
  119. data/src/agent/Core/SpawningKit/Result/AutoGeneratedCode.h.cxxcodebuilder +110 -0
  120. data/src/agent/Core/SpawningKit/SmartSpawner.h +1027 -562
  121. data/src/agent/Core/SpawningKit/Spawner.h +70 -1134
  122. data/src/agent/Core/SpawningKit/UserSwitchingRules.h +3 -33
  123. data/src/agent/README.md +2 -3
  124. data/src/agent/Shared/ApiServerUtils.h +2 -3
  125. data/src/agent/SpawnEnvSetupper/SpawnEnvSetupperMain.cpp +932 -0
  126. data/src/agent/Watchdog/Config.h +1 -3
  127. data/src/agent/Watchdog/WatchdogMain.cpp +2 -1
  128. data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp +5 -0
  129. data/src/apache2_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.cpp +5 -0
  130. data/src/apache2_module/ConfigGeneral/ManifestGeneration.h +22 -13
  131. data/src/apache2_module/DirConfig/AutoGeneratedCreateFunction.cpp +5 -0
  132. data/src/apache2_module/DirConfig/AutoGeneratedHeaderSerialization.cpp +3 -0
  133. data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp +13 -0
  134. data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp +7 -0
  135. data/src/apache2_module/DirConfig/AutoGeneratedStruct.h +13 -0
  136. data/src/cxx_supportlib/Constants.h +3 -1
  137. data/src/cxx_supportlib/Exceptions.h +0 -121
  138. data/src/cxx_supportlib/LoggingKit/Implementation.cpp +7 -6
  139. data/src/cxx_supportlib/LoggingKit/Logging.h +3 -1
  140. data/src/cxx_supportlib/Utils.cpp +42 -0
  141. data/src/cxx_supportlib/Utils.h +7 -0
  142. data/src/cxx_supportlib/Utils/IOUtils.cpp +58 -0
  143. data/src/cxx_supportlib/Utils/IOUtils.h +13 -0
  144. data/src/cxx_supportlib/Utils/JsonUtils.h +130 -23
  145. data/src/cxx_supportlib/Utils/ScopeGuard.h +9 -4
  146. data/src/cxx_supportlib/Utils/StrIntUtils.cpp +7 -0
  147. data/src/cxx_supportlib/Utils/StrIntUtils.h +1 -0
  148. data/src/cxx_supportlib/Utils/SystemTime.h +1 -1
  149. data/src/cxx_supportlib/Utils/Timer.h +1 -1
  150. data/src/cxx_supportlib/WebSocketCommandReverseServer.h +6 -4
  151. data/src/cxx_supportlib/vendor-copy/adhoc_lve.h +1 -0
  152. data/src/helper-scripts/node-loader.js +54 -59
  153. data/src/helper-scripts/rack-loader.rb +63 -60
  154. data/src/helper-scripts/rack-preloader.rb +125 -72
  155. data/src/helper-scripts/wsgi-loader.py +100 -43
  156. data/src/nginx_module/ConfigGeneral/AutoGeneratedDefinitions.c +120 -112
  157. data/src/nginx_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.c +15 -8
  158. data/src/nginx_module/ConfigGeneral/AutoGeneratedSetterFuncs.c +142 -142
  159. data/src/nginx_module/ConfigGeneral/ManifestGeneration.c +26 -15
  160. data/src/nginx_module/ConfigGeneral/ManifestGeneration.h +3 -0
  161. data/src/nginx_module/LocationConfig/AutoGeneratedCreateFunction.c +76 -70
  162. data/src/nginx_module/LocationConfig/AutoGeneratedHeaderSerialization.c +114 -99
  163. data/src/nginx_module/LocationConfig/AutoGeneratedManifestGeneration.c +170 -156
  164. data/src/nginx_module/LocationConfig/AutoGeneratedMergeFunction.c +38 -35
  165. data/src/nginx_module/LocationConfig/AutoGeneratedStruct.h +5 -1
  166. data/src/ruby_supportlib/phusion_passenger.rb +5 -5
  167. data/src/ruby_supportlib/phusion_passenger/admin_tools/instance.rb +14 -1
  168. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +8 -0
  169. data/src/ruby_supportlib/phusion_passenger/common_library.rb +0 -3
  170. data/src/ruby_supportlib/phusion_passenger/config/nginx_engine_compiler.rb +0 -1
  171. data/src/ruby_supportlib/phusion_passenger/constants.rb +2 -0
  172. data/src/ruby_supportlib/phusion_passenger/loader_shared_helpers.rb +646 -238
  173. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +117 -95
  174. data/src/ruby_supportlib/phusion_passenger/packaging.rb +0 -1
  175. data/src/ruby_supportlib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +5 -1
  176. data/src/ruby_supportlib/phusion_passenger/preloader_shared_helpers.rb +92 -69
  177. data/src/ruby_supportlib/phusion_passenger/public_api.rb +0 -17
  178. data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +0 -3
  179. data/src/ruby_supportlib/phusion_passenger/request_handler.rb +4 -5
  180. data/src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb +0 -22
  181. metadata +64 -67
  182. data/resources/templates/error_layout.html.template +0 -86
  183. data/resources/templates/general_error.html.template +0 -1
  184. data/resources/templates/general_error_with_html.html.template +0 -1
  185. data/src/agent/Core/ApplicationPool/ErrorRenderer.h +0 -131
  186. data/src/agent/Core/SpawningKit/Options.h +0 -41
  187. data/src/agent/Core/UnionStation/Connection.h +0 -173
  188. data/src/agent/Core/UnionStation/Context.h +0 -536
  189. data/src/agent/Core/UnionStation/StopwatchLog.h +0 -147
  190. data/src/agent/Core/UnionStation/Transaction.h +0 -249
  191. data/src/agent/SpawnPreparer/SpawnPreparerMain.cpp +0 -208
  192. data/src/cxx_supportlib/UnionStationFilterSupport.cpp +0 -67
  193. data/src/cxx_supportlib/UnionStationFilterSupport.h +0 -1622
  194. data/src/nodejs_supportlib/phusion_passenger/log_express.js +0 -106
  195. data/src/nodejs_supportlib/phusion_passenger/log_mongodb.js +0 -202
  196. data/src/nodejs_supportlib/phusion_passenger/ustreporter.js +0 -227
  197. data/src/nodejs_supportlib/phusion_passenger/ustrouter_connector.js +0 -448
  198. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/CONFIG.md +0 -37
  199. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Gemfile +0 -17
  200. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Gemfile.lock +0 -59
  201. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README-API.md +0 -5
  202. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README.md +0 -117
  203. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Rakefile +0 -115
  204. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +0 -423
  205. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +0 -238
  206. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/connection.rb +0 -67
  207. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +0 -281
  208. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/lock.rb +0 -62
  209. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/log.rb +0 -66
  210. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/message_channel.rb +0 -157
  211. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +0 -150
  212. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/basics.rb +0 -199
  213. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/controllers.rb +0 -187
  214. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/misc.rb +0 -303
  215. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/view_rendering.rb +0 -91
  216. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +0 -396
  217. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/spec_helper.rb +0 -279
  218. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/time_point.rb +0 -39
  219. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +0 -173
  220. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +0 -177
  221. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version.rb +0 -32
  222. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version_data.rb +0 -44
  223. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.example +0 -16
  224. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis +0 -20
  225. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis-with-sudo +0 -18
  226. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/union_station_hooks_core.gemspec +0 -23
  227. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile +0 -14
  228. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile.lock +0 -45
  229. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/LICENSE.md +0 -19
  230. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/README.md +0 -104
  231. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Rakefile +0 -160
  232. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails.rb +0 -200
  233. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/action_controller_extension.rb +0 -45
  234. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/action_view_subscriber.rb +0 -55
  235. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_record_subscriber.rb +0 -41
  236. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_support_benchmarkable_extension.rb +0 -47
  237. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_support_cache_subscriber.rb +0 -79
  238. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/exception_logger.rb +0 -57
  239. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/version.rb +0 -32
  240. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/version_data.rb +0 -44
  241. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/union_station_hooks_rails.gemspec +0 -34
@@ -58,9 +58,10 @@ typedef struct {
58
58
  ngx_uint_t min_instances;
59
59
  ngx_array_t *monitor_log_file;
60
60
  ngx_int_t request_queue_overflow_status_code;
61
- ngx_int_t start_timeout;
61
+ ngx_uint_t start_timeout;
62
62
  ngx_flag_t sticky_sessions;
63
63
  ngx_str_t app_group_name;
64
+ ngx_str_t app_log_file;
64
65
  ngx_str_t app_rights;
65
66
  ngx_str_t app_root;
66
67
  ngx_str_t app_type;
@@ -81,6 +82,7 @@ typedef struct {
81
82
  ngx_str_t abort_websockets_on_process_shutdown_source_file;
82
83
  ngx_str_t app_file_descriptor_ulimit_source_file;
83
84
  ngx_str_t app_group_name_source_file;
85
+ ngx_str_t app_log_file_source_file;
84
86
  ngx_str_t app_rights_source_file;
85
87
  ngx_str_t app_root_source_file;
86
88
  ngx_str_t app_type_source_file;
@@ -129,6 +131,7 @@ typedef struct {
129
131
  ngx_uint_t abort_websockets_on_process_shutdown_source_line;
130
132
  ngx_uint_t app_file_descriptor_ulimit_source_line;
131
133
  ngx_uint_t app_group_name_source_line;
134
+ ngx_uint_t app_log_file_source_line;
132
135
  ngx_uint_t app_rights_source_line;
133
136
  ngx_uint_t app_root_source_line;
134
137
  ngx_uint_t app_type_source_line;
@@ -177,6 +180,7 @@ typedef struct {
177
180
  ngx_int_t abort_websockets_on_process_shutdown_explicitly_set;
178
181
  ngx_int_t app_file_descriptor_ulimit_explicitly_set;
179
182
  ngx_int_t app_group_name_explicitly_set;
183
+ ngx_int_t app_log_file_explicitly_set;
180
184
  ngx_int_t app_rights_explicitly_set;
181
185
  ngx_int_t app_root_explicitly_set;
182
186
  ngx_int_t app_type_explicitly_set;
@@ -31,15 +31,15 @@ module PhusionPassenger
31
31
 
32
32
  PACKAGE_NAME = 'passenger'
33
33
  # Run 'rake src/cxx_supportlib/Constants.h configkit_schemas_inline_comments' after changing this number.
34
- VERSION_STRING = '5.2.3'
34
+ VERSION_STRING = '5.3.0'
35
35
 
36
- PREFERRED_NGINX_VERSION = '1.12.2'
37
- NGINX_SHA256_CHECKSUM = '305f379da1d5fb5aefa79e45c829852ca6983c7cd2a79328f8e084a324cf0416'
36
+ PREFERRED_NGINX_VERSION = '1.14.0'
37
+ NGINX_SHA256_CHECKSUM = '5d15becbf69aba1fe33f8d416d97edd95ea8919ea9ac519eff9bafebb6022cb5'
38
38
 
39
39
  # Packaging may be locked to an older version due to the specific module configuration being
40
40
  # incompatible with the version we prefer (latest stable).
41
- PACKAGING_PREFERRED_NGINX_VERSION = '1.12.2'
42
- PACKAGING_NGINX_SHA256_CHECKSUM = '305f379da1d5fb5aefa79e45c829852ca6983c7cd2a79328f8e084a324cf0416'
41
+ PACKAGING_PREFERRED_NGINX_VERSION = '1.14.0'
42
+ PACKAGING_NGINX_SHA256_CHECKSUM = '5d15becbf69aba1fe33f8d416d97edd95ea8919ea9ac519eff9bafebb6022cb5'
43
43
 
44
44
  # sha256sum of the .tar.gz
45
45
  PREFERRED_PCRE_VERSION = '8.42'
@@ -115,8 +115,21 @@ module PhusionPassenger
115
115
  properties["watchdog_pid"]
116
116
  end
117
117
 
118
+ # Returns the Core's PID, or nil if it is not running
119
+ # or isn't finished initializing.
118
120
  def core_pid
119
- @core_pid ||= File.read("#{@path}/core.pid").to_i
121
+ @core_pid ||= begin
122
+ begin
123
+ data = File.read("#{@path}/core.pid")
124
+ if data.empty?
125
+ nil
126
+ else
127
+ data.to_i
128
+ end
129
+ rescue Errno::ENOENT
130
+ nil
131
+ end
132
+ end
120
133
  end
121
134
 
122
135
  def web_server_control_process_pid
@@ -291,6 +291,7 @@ APACHE2_CONFIGURATION_OPTIONS = [
291
291
  :desc => 'The password to use when connecting to the admin panel using basic authentication'
292
292
  },
293
293
 
294
+
294
295
  ###### Per-application configuration ######
295
296
 
296
297
  {
@@ -619,6 +620,13 @@ APACHE2_CONFIGURATION_OPTIONS = [
619
620
  :field => nil,
620
621
  :desc => 'The maximum number of seconds that a request may remain in the queue before it is dropped.'
621
622
  },
623
+ {
624
+ :name => 'PassengerAppLogFile',
625
+ :type => :string,
626
+ :dynamic_default => 'PassengerLogFile',
627
+ :function => 'cmd_passenger_enterprise_only',
628
+ :desc => 'Application log file path.'
629
+ },
622
630
 
623
631
 
624
632
  ##### Aliases and backwards compatibility options #####
@@ -357,9 +357,6 @@ COMMON_LIBRARY = CommonLibraryBuilder.new do
357
357
  :source => 'vendor-modified/modp_b64_strict_aliasing.cpp',
358
358
  :category => :base64,
359
359
  :optimize => true
360
- define_component 'UnionStationFilterSupport.o',
361
- :source => 'UnionStationFilterSupport.cpp',
362
- :category => :union_station_filter
363
360
 
364
361
  define_component 'JsonTools/CBindings.o',
365
362
  :source => 'JsonTools/CBindings.cpp',
@@ -55,7 +55,6 @@ module PhusionPassenger
55
55
  result << "--without-http_fastcgi_module " \
56
56
  "--without-http_scgi_module " \
57
57
  "--without-http_uwsgi_module " \
58
- "--with-ipv6 " \
59
58
  "--with-http_ssl_module " \
60
59
  "--with-http_v2_module " \
61
60
  "--with-http_realip_module " \
@@ -107,6 +107,8 @@ module PhusionPassenger
107
107
  SHORT_PROGRAM_NAME = "Passenger"
108
108
  SERVER_TOKEN_NAME = "Phusion_Passenger"
109
109
  FLYING_PASSENGER_NAME = "Flying Passenger"
110
+ PROGRAM_WEBSITE = "https://www.phusionpassenger.com"
111
+ PROGRAM_AUTHOR = "Phusion"
110
112
  SUPPORT_URL = "https://www.phusionpassenger.com/support"
111
113
  ENTERPRISE_URL = "https://www.phusionpassenger.com/enterprise"
112
114
  GLOBAL_NAMESPACE_DIRNAME = PhusionPassenger::GLOBAL_NAMESPACE_DIRNAME_
@@ -23,14 +23,6 @@
23
23
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
24
  # THE SOFTWARE.
25
25
 
26
- PhusionPassenger.require_passenger_lib 'constants'
27
- PhusionPassenger.require_passenger_lib 'public_api'
28
- PhusionPassenger.require_passenger_lib 'ruby_core_enhancements'
29
- PhusionPassenger.require_passenger_lib 'debug_logging'
30
- PhusionPassenger.require_passenger_lib 'platform_info/ruby'
31
- PhusionPassenger.require_passenger_lib 'platform_info/operating_system'
32
- PhusionPassenger.require_passenger_lib 'utils/shellwords'
33
-
34
26
  module PhusionPassenger
35
27
 
36
28
  # Provides shared functions for loader and preloader apps.
@@ -38,14 +30,49 @@ module PhusionPassenger
38
30
  extend self
39
31
 
40
32
  # To be called by the (pre)loader as soon as possible.
41
- def init(options)
42
- Thread.main[:name] = "Main thread"
33
+ def init(main_app)
34
+ @main_app = main_app
35
+ options = read_startup_arguments
36
+
43
37
  # We don't dump PATH info because at this point it's
44
38
  # unlikely to be changed.
45
39
  dump_ruby_environment
46
40
  check_rvm_using_wrapper_script(options)
41
+
42
+ PhusionPassenger.require_passenger_lib 'native_support'
43
+ if defined?(NativeSupport)
44
+ NativeSupport.disable_stdio_buffering
45
+ end
46
+
47
+ PhusionPassenger.require_passenger_lib 'constants'
48
+ PhusionPassenger.require_passenger_lib 'public_api'
49
+ PhusionPassenger.require_passenger_lib 'debug_logging'
50
+ PhusionPassenger.require_passenger_lib 'platform_info/ruby'
51
+ PhusionPassenger.require_passenger_lib 'platform_info/operating_system'
52
+ PhusionPassenger.require_passenger_lib 'utils/shellwords'
53
+ PhusionPassenger.require_passenger_lib 'ruby_core_enhancements'
54
+ PhusionPassenger.require_passenger_lib 'ruby_core_io_enhancements'
55
+ PhusionPassenger.require_passenger_lib 'request_handler'
56
+
57
+ PhusionPassenger.require_passenger_lib 'rack/thread_handler_extension'
58
+ RequestHandler::ThreadHandler.send(:include, Rack::ThreadHandlerExtension)
59
+ Thread.main[:name] = "Main thread"
60
+
47
61
  load_macos_foundation
48
- sanitize_spawn_options(options)
62
+
63
+ options
64
+ rescue Exception => e
65
+ record_journey_step_end('SUBPROCESS_WRAPPER_PREPARATION', 'STEP_ERRORED')
66
+ record_and_print_exception(e)
67
+ exit exit_code_for_exception(e)
68
+ end
69
+
70
+ def read_startup_arguments
71
+ work_dir = ENV['PASSENGER_SPAWN_WORK_DIR']
72
+ PhusionPassenger.require_passenger_lib 'utils/json'
73
+ @@options = File.open("#{work_dir}/args.json", 'rb') do |f|
74
+ PhusionPassenger::Utils::JSON.parse(f.read)
75
+ end
49
76
  end
50
77
 
51
78
  def check_rvm_using_wrapper_script(options)
@@ -63,22 +90,37 @@ module PhusionPassenger
63
90
  passenger_ruby_doc = "https://www.phusionpassenger.com/library/config/standalone/reference/#setting_correct_passenger_ruby_value"
64
91
  end
65
92
 
66
- raise "You've set the `#{passenger_ruby}` option to '#{ruby}'. " +
67
- "However, because you are using RVM, this is not allowed: the option must point to " +
68
- "an RVM wrapper script, not a raw Ruby binary. This is because RVM is implemented " +
69
- "through various environment variables, which are set through the wrapper script.\n" +
70
- "\n" +
71
- "To find out the correct value for `#{passenger_ruby}`, please read:\n\n" +
72
- " #{passenger_ruby_doc}\n" +
73
- "\n-------------------------\n"
93
+ log_error_to_response_dir(
94
+ :summary => "#{passenger_ruby} must be set to an RVM wrapper script instead of a raw Ruby binary",
95
+
96
+ :problem_description_html =>
97
+ "You've set the <code>#{h passenger_ruby}</code> option to <code>#{h ruby}</code>. " \
98
+ 'However, because you are using RVM, this is not allowed: the option must point to ' \
99
+ 'an RVM wrapper script, not a raw Ruby binary. This is because RVM is implemented ' \
100
+ "through various environment variables, which are set through the wrapper script.\n",
101
+
102
+ :solution_description_html =>
103
+ "To find out the correct value for <code>#{h passenger_ruby}</code>, please read " \
104
+ "<a href=\"#{h passenger_ruby_doc}\">its documentation entry</a>."
105
+ )
106
+ abort
74
107
  end
75
108
  end
76
109
 
77
- # To be called whenever the (pre)loader is about to abort with an error.
78
- def about_to_abort(options, exception = nil)
79
- dump_all_information(options)
80
- # https://code.google.com/p/phusion-passenger/issues/detail?id=1039
81
- puts
110
+ def is_ruby_program?(path)
111
+ File.open(path, "rb") do |f|
112
+ f.readline =~ /ruby/
113
+ end
114
+ rescue EOFError
115
+ false
116
+ end
117
+
118
+ def exit_code_for_exception(e)
119
+ if e.is_a?(SystemExit)
120
+ e.status
121
+ else
122
+ 1
123
+ end
82
124
  end
83
125
 
84
126
  def load_macos_foundation
@@ -104,138 +146,6 @@ module PhusionPassenger
104
146
  end
105
147
  end
106
148
 
107
- def to_boolean(value)
108
- return !(value.nil? || value == false || value == "false")
109
- end
110
-
111
- def sanitize_spawn_options(options)
112
- defaults = {
113
- "app_type" => "rack",
114
- "environment" => "production",
115
- "print_exceptions" => true
116
- }
117
- options = defaults.merge(options)
118
- options["app_group_name"] = options["app_root"] if !options["app_group_name"]
119
- options["print_exceptions"] = to_boolean(options["print_exceptions"])
120
- options["analytics"] = to_boolean(options["analytics"])
121
- options["show_version_in_header"] = to_boolean(options["show_version_in_header"])
122
- options["log_level"] = options["log_level"].to_i if options["log_level"]
123
- # TODO: smart spawning is not supported when using ruby-debug. We should raise an error
124
- # in this case.
125
- options["debugger"] = to_boolean(options["debugger"])
126
- options["spawn_method"] = "direct" if options["debugger"]
127
-
128
- return options
129
- end
130
-
131
- def dump_all_information(options)
132
- dump_ruby_environment
133
- dump_envvars
134
- dump_system_metrics(options)
135
- end
136
-
137
- def dump_ruby_environment
138
- if dir = ENV['PASSENGER_DEBUG_DIR']
139
- File.open("#{dir}/ruby_info", "w") do |f|
140
- f.puts "RUBY_VERSION = #{RUBY_VERSION}"
141
- f.puts "RUBY_PLATFORM = #{RUBY_PLATFORM}"
142
- f.puts "RUBY_ENGINE = #{defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'nil'}"
143
- end
144
- File.open("#{dir}/load_path", "wb") do |f|
145
- $LOAD_PATH.each do |path|
146
- f.puts path
147
- end
148
- end
149
- File.open("#{dir}/loaded_libs", "wb") do |f|
150
- $LOADED_FEATURES.each do |filename|
151
- f.puts filename
152
- end
153
- end
154
-
155
- # We write to these files last because the 'require' calls can fail.
156
- require 'rbconfig' if !defined?(RbConfig::CONFIG)
157
- File.open("#{dir}/rbconfig", "wb") do |f|
158
- RbConfig::CONFIG.each_pair do |key, value|
159
- f.puts "#{key} = #{value}"
160
- end
161
- end
162
- begin
163
- require 'rubygems' if !defined?(Gem)
164
- rescue LoadError
165
- end
166
- if defined?(Gem)
167
- File.open("#{dir}/ruby_info", "a") do |f|
168
- f.puts "RubyGems version = #{Gem::VERSION}"
169
- if Gem.respond_to?(:path)
170
- f.puts "RubyGems paths = #{Gem.path.inspect}"
171
- else
172
- f.puts "RubyGems paths = unknown; incompatible RubyGems API"
173
- end
174
- end
175
- File.open("#{dir}/activated_gems", "wb") do |f|
176
- if Gem.respond_to?(:loaded_specs)
177
- Gem.loaded_specs.each_pair do |name, spec|
178
- f.puts "#{name} => #{spec.version}"
179
- end
180
- else
181
- f.puts "Unable to query this information; incompatible RubyGems API."
182
- end
183
- end
184
- end
185
- end
186
- rescue SystemCallError
187
- # Don't care.
188
- end
189
-
190
- def dump_envvars
191
- if dir = ENV['PASSENGER_DEBUG_DIR']
192
- File.open("#{dir}/envvars", "wb") do |f|
193
- ENV.each_pair do |key, value|
194
- f.puts "#{key} = #{value}"
195
- end
196
- end
197
- end
198
- rescue SystemCallError
199
- # Don't care.
200
- end
201
-
202
- def dump_system_metrics(options)
203
- if dir = ENV['PASSENGER_DEBUG_DIR']
204
- # When invoked through Passenger Standalone, we want passenger-config
205
- # to use the PassengerAgent in the Passsenger Standalone buildout directory,
206
- # because the one in the source root may not exist.
207
- passenger_config = "#{PhusionPassenger.bin_dir}/passenger-config"
208
- if is_ruby_program?(passenger_config)
209
- ruby = options["ruby"]
210
- else
211
- ruby = nil
212
- end
213
- command = [
214
- "env",
215
- "PASSENGER_LOCATION_CONFIGURATION_FILE=#{PhusionPassenger.install_spec}",
216
- ruby,
217
- passenger_config,
218
- "system-metrics"
219
- ].compact
220
- contents = `#{Shellwords.join(command)}`
221
- if $? && $?.exitstatus == 0
222
- File.open("#{dir}/system_metrics", "wb") do |f|
223
- f.write(contents)
224
- end
225
- end
226
- end
227
- rescue SystemCallError
228
- # Don't care.
229
- end
230
-
231
- def is_ruby_program?(path)
232
- File.open(path, "rb") do |f|
233
- f.readline =~ /ruby/
234
- end
235
- rescue EOFError
236
- false
237
- end
238
-
239
149
  # Prepare an application process using rules for the given spawn options.
240
150
  # This method is to be called before loading the application code.
241
151
  #
@@ -247,18 +157,6 @@ module PhusionPassenger
247
157
  # passed to the request handler.
248
158
  def before_loading_app_code_step1(startup_file, options)
249
159
  DebugLogging.log_level = options["log_level"] if options["log_level"]
250
-
251
- # We always load the union_station_hooks_* gems and do not check for
252
- # `options["analytics"]` here. The gems don't actually initialize (and
253
- # load the bulk of their code) unless they have determined that
254
- # `options["analytics"]` is true. Regardless of whether Union Station
255
- # support is enabled in Passenger, the UnionStationHooks namespace must
256
- # be available so that applications can call it, even though the actual
257
- # calls don't do anything when Union Station support is disabled.
258
- PhusionPassenger.require_passenger_lib 'vendor/union_station_hooks_core/lib/union_station_hooks_core'
259
- UnionStationHooks.vendored = true
260
- PhusionPassenger.require_passenger_lib 'vendor/union_station_hooks_rails/lib/union_station_hooks_rails'
261
- UnionStationHooksRails.vendored = true
262
160
  end
263
161
 
264
162
  def run_load_path_setup_code(options)
@@ -339,7 +237,6 @@ module PhusionPassenger
339
237
  # This method is to be called after loading the application code but
340
238
  # before forking a worker process.
341
239
  def after_loading_app_code(options)
342
- UnionStationHooks.check_initialized
343
240
  end
344
241
 
345
242
  # If the current working directory equals `app_root`, and `abs_path` is a
@@ -361,25 +258,35 @@ module PhusionPassenger
361
258
 
362
259
  def create_socket_address(protocol, address)
363
260
  if protocol == 'unix'
364
- return "unix:#{address}"
261
+ "unix:#{address}"
365
262
  elsif protocol == 'tcp'
366
- return "tcp://#{address}"
263
+ "tcp://#{address}"
367
264
  else
368
265
  raise ArgumentError, "Unknown protocol '#{protocol}'"
369
266
  end
370
267
  end
371
268
 
372
- def advertise_readiness
373
- # https://code.google.com/p/phusion-passenger/issues/detail?id=1039
374
- puts
269
+ def advertise_sockets(_options, request_handler)
270
+ json = { :sockets => [] }
271
+ request_handler.server_sockets.each_pair do |name, options|
272
+ concurrency = PhusionPassenger.advertised_concurrency_level || options[:concurrency]
273
+ json[:sockets] << {
274
+ :name => name,
275
+ :address => options[:address],
276
+ :protocol => options[:protocol],
277
+ :concurrency => concurrency,
278
+ :accept_http_requests => !!options[:accept_http_requests]
279
+ }
280
+ end
375
281
 
376
- puts "!> Ready"
282
+ File.open(ENV['PASSENGER_SPAWN_WORK_DIR'] + '/response/properties.json', 'w') do |f|
283
+ f.write(PhusionPassenger::Utils::JSON.generate(json))
284
+ end
377
285
  end
378
286
 
379
- def advertise_sockets(output, request_handler)
380
- request_handler.server_sockets.each_pair do |name, options|
381
- concurrency = PhusionPassenger.advertised_concurrency_level || options[:concurrency]
382
- output.puts "!> socket: #{name};#{options[:address]};#{options[:protocol]};#{concurrency}"
287
+ def advertise_readiness(options)
288
+ File.open(ENV['PASSENGER_SPAWN_WORK_DIR'] + '/response/finish', 'w') do |f|
289
+ f.write('1')
383
290
  end
384
291
  end
385
292
 
@@ -456,86 +363,587 @@ module PhusionPassenger
456
363
  require(library_name || gem_name)
457
364
  end
458
365
 
366
+
367
+ ##### Journey recording #####
368
+
369
+ def record_journey_step_begin(step, state, *args)
370
+ @main_app.record_journey_step_begin(step, state, *args)
371
+ end
372
+
373
+ def record_journey_step_end(step, state, *args)
374
+ @main_app.record_journey_step_end(step, state, *args)
375
+ end
376
+
377
+ def run_block_and_record_step_progress(step, *args)
378
+ record_journey_step_begin(step, 'STEP_IN_PROGRESS', *args)
379
+ begin
380
+ yield
381
+ rescue Exception => e
382
+ record_journey_step_end(step, 'STEP_ERRORED', *args)
383
+ raise e
384
+ else
385
+ record_journey_step_end(step, 'STEP_PERFORMED', *args)
386
+ end
387
+ end
388
+
389
+
390
+ ##### Error reporting #####
391
+
392
+ # To be called whenever the (pre)loader is about to abort with an error.
393
+ def about_to_abort(options, exception)
394
+ dump_all_information(options)
395
+ end
396
+
397
+ def record_and_print_exception(e)
398
+ record_error_category_based_on_exception(e)
399
+ record_and_print_error_summary(
400
+ "The application encountered the following error: #{e} (#{e.class})")
401
+ STDERR.write(" #{e.backtrace.join("\n ")}\n")
402
+ record_advanced_problem_details(format_exception(e))
403
+ if e.respond_to?(:problem_description_html)
404
+ record_problem_description_html(e.problem_description_html)
405
+ end
406
+ if e.respond_to?(:solution_description_html)
407
+ record_solution_description_html(e.solution_description_html)
408
+ end
409
+ end
410
+
411
+ def record_error_category(category)
412
+ dir = ENV['PASSENGER_SPAWN_WORK_DIR']
413
+ try_write_file("#{dir}/response/error/category", category)
414
+ end
415
+
416
+ def record_error_category_based_on_exception(e)
417
+ if e.is_a?(IOError)
418
+ record_error_category('IO_ERROR')
419
+ elsif e.is_a?(SystemCallError)
420
+ record_error_category('OPERATING_SYSTEM_ERROR')
421
+ else
422
+ record_error_category('INTERNAL_ERROR')
423
+ end
424
+ end
425
+
426
+ def record_error_summary(summary)
427
+ dir = ENV['PASSENGER_SPAWN_WORK_DIR']
428
+ try_write_file("#{dir}/response/error/summary", summary)
429
+ end
430
+
431
+ def record_and_print_error_summary(summary)
432
+ STDERR.puts "Error: #{summary}"
433
+ record_error_summary(summary)
434
+ end
435
+
436
+ def record_advanced_problem_details(message)
437
+ dir = ENV['PASSENGER_SPAWN_WORK_DIR']
438
+ try_write_file("#{dir}/response/error/advanced_problem_details", message)
439
+ end
440
+
441
+ def record_problem_description_html(html)
442
+ dir = ENV['PASSENGER_SPAWN_WORK_DIR']
443
+ try_write_file("#{dir}/response/error/problem_description.html", html)
444
+ end
445
+
446
+ def record_solution_description_html(html)
447
+ dir = ENV['PASSENGER_SPAWN_WORK_DIR']
448
+ try_write_file("#{dir}/response/error/solution_description.html", html)
449
+ end
450
+
451
+ def format_exception(e)
452
+ result = "#{e} (#{e.class})"
453
+ if !e.backtrace.empty?
454
+ result << "\n " << e.backtrace.join("\n ")
455
+ end
456
+ result
457
+ end
458
+
459
+
460
+ ##### Environment dumping #####
461
+
462
+ def dump_all_information(options)
463
+ dump_ruby_environment
464
+ dump_envvars
465
+ end
466
+
467
+ def dump_ruby_environment
468
+ dir = "#{ENV['PASSENGER_SPAWN_WORK_DIR']}/envdump/annotations"
469
+
470
+ File.open("#{dir}/ruby_info", "w") do |f|
471
+ f.puts "RUBY_VERSION = #{RUBY_VERSION}"
472
+ f.puts "RUBY_PLATFORM = #{RUBY_PLATFORM}"
473
+ f.puts "RUBY_ENGINE = #{defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'nil'}"
474
+ end
475
+ File.open("#{dir}/load_path", "wb") do |f|
476
+ $LOAD_PATH.each do |path|
477
+ f.puts path
478
+ end
479
+ end
480
+ File.open("#{dir}/loaded_libs", "wb") do |f|
481
+ $LOADED_FEATURES.each do |filename|
482
+ f.puts filename
483
+ end
484
+ end
485
+
486
+ # We write to these files last because the 'require' calls can fail.
487
+ require 'rbconfig' if !defined?(RbConfig::CONFIG)
488
+ File.open("#{dir}/rbconfig", "wb") do |f|
489
+ RbConfig::CONFIG.each_pair do |key, value|
490
+ f.puts "#{key} = #{value}"
491
+ end
492
+ end
493
+ begin
494
+ require 'rubygems' if !defined?(Gem)
495
+ rescue LoadError
496
+ end
497
+ if defined?(Gem)
498
+ File.open("#{dir}/ruby_info", "a") do |f|
499
+ f.puts "RubyGems version = #{Gem::VERSION}"
500
+ if Gem.respond_to?(:path)
501
+ f.puts "RubyGems paths = #{Gem.path.inspect}"
502
+ else
503
+ f.puts "RubyGems paths = unknown; incompatible RubyGems API"
504
+ end
505
+ end
506
+ File.open("#{dir}/activated_gems", "wb") do |f|
507
+ if Gem.respond_to?(:loaded_specs)
508
+ Gem.loaded_specs.each_pair do |name, spec|
509
+ f.puts "#{name} => #{spec.version}"
510
+ end
511
+ else
512
+ f.puts "Unable to query this information; incompatible RubyGems API."
513
+ end
514
+ end
515
+ end
516
+ rescue SystemCallError
517
+ # Don't care.
518
+ end
519
+
520
+ def dump_envvars
521
+ dir = "#{ENV['PASSENGER_SPAWN_WORK_DIR']}/envdump"
522
+ try_write_file("#{dir}/envvars", ENV.to_a.map { |k, v| "#{k} = #{v}" }.join("\n"))
523
+ end
524
+
459
525
  private
460
526
  def running_bundler(options)
461
527
  yield
462
528
  rescue Exception => e
463
529
  if (defined?(Bundler::GemNotFound) && e.is_a?(Bundler::GemNotFound)) ||
464
530
  (defined?(Bundler::GitError) && e.is_a?(Bundler::GitError))
465
- PhusionPassenger.require_passenger_lib 'platform_info/ruby'
466
- comment =
467
- "<p>It looks like Bundler could not find a gem. Maybe you didn't install all the " +
468
- "gems that this application needs. To install your gems, please run:</p>\n\n" +
469
- " <pre class=\"commands\">bundle install</pre>\n\n"
470
- ruby = options["ruby"]
531
+ ruby = PlatformInfo.ruby_command
532
+ e_as_str = "#{e}" # Certain classes like Interrupt don't like #to_s, so we use this
533
+ if Bundler.respond_to?(:settings) && Bundler.settings.respond_to?(:path)
534
+ bundle_path = Bundler.settings.path
535
+ end
536
+ case options['integration_mode']
537
+ when 'apache'
538
+ passenger_ruby = 'PassengerRuby'
539
+ passenger_ruby_doc = 'https://www.phusionpassenger.com/library/config/apache/reference/#passengerruby'
540
+ passenger_user = 'PassengerUser'
541
+ passenger_user_doc = 'https://www.phusionpassenger.com/library/config/apache/reference/#passengeruser'
542
+ when 'nginx'
543
+ passenger_ruby = 'passenger_ruby'
544
+ passenger_ruby_doc = 'https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_ruby'
545
+ passenger_user = 'passenger_user'
546
+ passenger_user_doc = 'https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_user'
547
+ when 'standalone'
548
+ passenger_ruby = '--ruby'
549
+ passenger_ruby_doc = 'https://www.phusionpassenger.com/library/config/standalone/reference/#--ruby-ruby'
550
+ else
551
+ raise "Unknown integration mode #{options['integration_mode'].inspect}"
552
+ end
553
+
554
+
555
+ problem_description = %Q{
556
+ <h2>Bundler was unable to find one of the gems defined in the Gemfile</h2>
557
+ <table class="table table-bordered table-hover problem-causes">
558
+ <thead>
559
+ <tr>
560
+ <th>Most common causes</th>
561
+ <th class="solution-preview">Solution finder</th>
562
+ </tr>
563
+ </thead>
564
+ <tbody>
565
+ }
566
+
567
+ problem_description << %Q{
568
+ <tr class="cause">
569
+ <td>
570
+ You may not have installed all the gems that this application needs.
571
+ </td>
572
+ <td class="solution-preview">
573
+ <a
574
+ href="javascript:void(0)"
575
+ data-toggle="collapse"
576
+ data-target="#bundle_install_solution">
577
+ Read solution
578
+ </a>
579
+ </td>
580
+ </tr>
581
+ <tr class="collapse solution-description" id="bundle_install_solution">
582
+ <td colspan="2" class="info">
583
+ <div class="single-solution">
584
+ <p>Run the following from the application directory:</p>
585
+ <pre>bundle install</pre>
586
+ </div>
587
+ </td>
588
+ </tr>
589
+ }
590
+
591
+ problem_description << %Q{
592
+ <tr class="cause">
593
+ <td>
594
+ If the necessary gems are installed, but Bundler may not have
595
+ permissions to access them.
596
+ }
597
+ if bundle_path
598
+ problem_description << %Q{
599
+ <br>
600
+ <small>Bundler tried to load the gems from <code>#{h bundle_path}</code>.</small>
601
+ }
602
+ end
603
+ problem_description << %Q{
604
+ </td>
605
+ <td class="solution-preview">
606
+ <a
607
+ href="javascript:void(0)"
608
+ data-toggle="collapse"
609
+ data-target="#check_exec_environment_solution">
610
+ Read solution
611
+ </a>
612
+ </td>
613
+ </tr>
614
+ <tr class="collapse solution-description" id="check_exec_environment_solution">
615
+ <td colspan="2" class="info">
616
+ <div class="multiple-solutions">
617
+ #{
618
+ check_execution_environment_solution_description(
619
+ passenger_user, passenger_user_doc, bundle_path)
620
+ }
621
+ </div>
622
+ </td>
623
+ </tr>
624
+ }
625
+
626
+ problem_description << %Q{
627
+ <tr class="cause">
628
+ <td>
629
+ The application may be run under the wrong user account or execution
630
+ environment.
631
+ <br>
632
+ <small>It is currently running as <code>#{h whoami}</code>.</small>
633
+ </td>
634
+ <td class="solution-preview">
635
+ <a
636
+ href="javascript:void(0)"
637
+ data-toggle="collapse"
638
+ data-target="#check_exec_environment_solution2">
639
+ Read solution
640
+ </a>
641
+ </td>
642
+ </tr>
643
+ <tr class="collapse solution-description" id="check_exec_environment_solution2">
644
+ <td colspan="2" class="info">
645
+ <div class="multiple-solutions">
646
+ #{
647
+ check_execution_environment_solution_description(
648
+ passenger_user, passenger_user_doc, bundle_path)
649
+ }
650
+ </div>
651
+ </td>
652
+ </tr>
653
+ }
654
+
655
+ problem_description << %Q{
656
+ <tr class="cause">
657
+ <td>
658
+ The application may be run under the wrong Ruby interpreter.
659
+ <br>
660
+ <small>It is currently being run under <code>#{h ruby}</code>.</small>
661
+ </td>
662
+ <td class="solution-preview">
663
+ <a
664
+ href="javascript:void(0)"
665
+ data-toggle="collapse"
666
+ data-target="#change_ruby_solution">
667
+ Read solution
668
+ </a>
669
+ </td>
670
+ </tr>
671
+ <tr class="collapse solution-description" id="change_ruby_solution">
672
+ <td colspan="2" class="info">
673
+ <div class="single-solution">
674
+ Use the <a href=\"#{h passenger_ruby_doc}\">#{h passenger_ruby}</a>
675
+ setting to change the Ruby interpreter that #{PROGRAM_NAME} uses.
676
+ </div>
677
+ </td>
678
+ </tr>
679
+ }
680
+
681
+ if PlatformInfo.in_rvm?
682
+ problem_description << %Q{
683
+ <tr class="cause">
684
+ <td>
685
+ The application may be run under the wrong RVM gemset.
686
+ <br>
687
+ <small>It is currently running under the
688
+ <code>#{h PlatformInfo.rvm_ruby_string}</code> gemset.</small>
689
+ </td>
690
+ <td class="solution-preview">
691
+ <a
692
+ href="javascript:void(0)"
693
+ data-toggle="collapse"
694
+ data-target="#change_rvm_gemset_solution">
695
+ Read solution
696
+ </a>
697
+ </td>
698
+ </tr>
699
+ <tr class="collapse solution-description" id="change_rvm_gemset_solution">
700
+ <td colspan="2" class="info">
701
+ <div class="single-solution">
702
+ Use the <a href=\"#{h passenger_ruby_doc}\">#{h passenger_ruby}</a>
703
+ setting. The documentation for that setting will teach you how to
704
+ refer to the proper gemset.
705
+ </div>
706
+ </td>
707
+ </tr>
708
+ }
709
+ end
710
+
471
711
  if ruby =~ %r(^/usr/local/rvm/)
472
- comment <<
473
- "<p>If that didn't work, then maybe the problem is that your gems are installed " +
474
- "to <code>#{h home_dir}/.rvm/gems</code>, while at the same time you set " +
475
- "<code>PassengerRuby</code> (Apache) or <code>passenger_ruby</code> (Nginx) to " +
476
- "<code>#{h ruby}</code>. Because of the latter, RVM does not load gems from the " +
477
- "home directory.</p>\n\n" +
478
- "<p>To make RVM load gems from the home directory, you need to set " +
479
- "<code>PassengerRuby</code>/<code>passenger_ruby</code> to an RVM wrapper script " +
480
- "inside the home directory:</p>\n\n" +
481
- "<ol>\n" +
482
- " <li>Login as #{h whoami}.</li>\n"
712
+ problem_description << %Q{
713
+ <tr class="cause">
714
+ <td>
715
+ You are using a system-wide-installed RVM Ruby installation.
716
+ It is possible that, at the same time, your gems are installed
717
+ to the home directory (#{h home_dir}/.rvm/gems). If this is the
718
+ case then RVM will not be able to use those gems.
719
+ <br>
720
+ <small>You are currently using this Ruby interpreter: <code>#{h ruby}</code></small>
721
+ </td>
722
+ <td class="solution-preview">
723
+ <a
724
+ href="javascript:void(0)"
725
+ data-toggle="collapse"
726
+ data-target="#use_home_rvm_solution">
727
+ Read solution
728
+ </a>
729
+ </td>
730
+ </tr>
731
+ <tr class="collapse solution-description" id="use_home_rvm_solution">
732
+ <td colspan="2" class="info">
733
+ <div class="single-solution">
734
+ <p>
735
+ To make Bundler and RVM able to load gems from the home directory, set
736
+ <a href="#{h passenger_ruby_doc}">#{h passenger_ruby}</a> to an RVM
737
+ wrapper script inside the home directory:
738
+ </p>
739
+ <ol>
740
+ <li>Login as #{h whoami}.</li>
741
+ }
483
742
  if PlatformInfo.rvm_installation_mode == :multi
484
- comment <<
485
- " <li>Enable RVM mixed mode by running:\n" +
486
- " <pre class=\"commands\">rvm user gemsets</pre></li>\n"
743
+ problem_description << %Q{
744
+ <li>
745
+ Enable RVM mixed mode by running:
746
+ <pre>rvm user gemsets</pre>
747
+ </li>
748
+ }
487
749
  end
488
- comment <<
489
- " <li>Run this to find out what to set <code>PassengerRuby</code>/<code>passenger_ruby</code> to:\n" +
490
- " <pre class=\"commands\">#{PlatformInfo.ruby_command} \\\n" +
491
- "#{PhusionPassenger.bin_dir}/passenger-config --detect-ruby</pre></li>\n" +
492
- "</ol>\n\n" +
493
- "<p>If that didn't help either, then maybe your application is being run under a " +
494
- "different environment than it's supposed to. Please check the following:</p>\n\n"
750
+ problem_description << %Q{
751
+ <li>
752
+ Run this to find out what to set
753
+ <a href="#{h passenger_ruby_doc}">#{h passenger_ruby}</a> to:
754
+ <pre>#{h PlatformInfo.ruby_command} #{PhusionPassenger.bin_dir}/passenger-config about ruby-command</pre>
755
+ </li>
756
+ </ol>
757
+ </div>
758
+ </td>
759
+ </tr>
760
+ }
761
+ end
762
+
763
+ if PlatformInfo.in_rvm?
764
+ problem_description << %Q{
765
+ <tr class="cause">
766
+ <td>
767
+ The RVM gemset may be broken.
768
+ </td>
769
+ <td class="solution-preview">
770
+ <a href="https://github.com/phusion/passenger/wiki/Resetting-RVM-gemsets" target="_blank">
771
+ Read solution
772
+ </a>
773
+ </td>
774
+ </tr>
775
+ }
776
+ end
777
+
778
+ problem_description << %Q{
779
+ </tbody>
780
+ </table>
781
+
782
+ <h3>Raw Bundler exception</h3>
783
+ <p>Exception message:</p>
784
+ <pre>#{h e_as_str} (#{h e.class.to_s})</pre>
785
+ <p>Backtrace:<p>
786
+ <pre>#{h e.backtrace.join("\n")}</pre>
787
+ }
788
+ attach_problem_description_html_to_exception(e, problem_description)
789
+
790
+
791
+ solution_description =
792
+ "<div class=\"multiple-solutions\">" \
793
+ \
794
+ "<h3>Make sure the gem bundle is installed</h3>" \
795
+ "<p>Run the following from the application directory:</p>" \
796
+ "<pre>bundle install</pre>" \
797
+ \
798
+ "<h3>Check the application process's execution environment</h3>" \
799
+ "<p>Is the application running under the expected execution environment?" \
800
+ " A common problem is that the application runs under a different user than" \
801
+ " it is supposed to. The application is currently running as the <code>#{h whoami}</code>" \
802
+ " user &mdash; is this expected? Also, check the 'Detailed diagnostics'" \
803
+ " &raquo; 'Subprocess' tab and double check all information there &mdash; is" \
804
+ " everything as expected? If not, please fix that.</p>"
805
+ if passenger_user
806
+ solution_description <<
807
+ "<p>If the application is not supposed to run as <code>#{h whoami}</code>," \
808
+ " then you can configure this via the" \
809
+ " <a href=\"#{h passenger_user_doc}\">#{h passenger_user}</a>" \
810
+ " setting.</p>"
811
+ end
812
+ solution_description <<
813
+ "<h3>Check that the application has permissions to access the directory from which Bundler loads gems</h3>" \
814
+ "<p>Please check whether the application, which is running as the" \
815
+ " <code>#{h whoami}</code> user, has permissions to access"
816
+ if bundle_path
817
+ solution_description <<
818
+ " <code>#{h bundle_path}</code>."
495
819
  else
496
- comment <<
497
- "<p>If that didn't work, then the problem is probably caused by your " +
498
- "application being run under a different environment than it's supposed to. " +
499
- "Please check the following:</p>\n\n"
820
+ solution_description <<
821
+ " the directory that Bundler tries to load gems from. Unfortunately" \
822
+ " #{SHORT_PROGRAM_NAME} was unable to figure out which directory this"
823
+ " is because Bundler is too old, so you need to figure out the" \
824
+ " directory yourself (or you can upgrade Bundler so that #{SHORT_PROGRAM_NAME}" \
825
+ " can figure out the path for you)."
500
826
  end
501
- comment << "<ol>\n"
502
- comment <<
503
- " <li>Is this app supposed to be run as the <code>#{h whoami}</code> user?</li>\n" +
504
- " <li>Is this app being run on the correct Ruby interpreter? Below you will\n" +
505
- " see which Ruby interpreter Phusion Passenger attempted to use.</li>\n"
827
+ solution_description <<
828
+ "</p>" \
829
+ \
830
+ "<h3>Check whether the application is being run under the correct Ruby interpreter</h3>" \
831
+ "<p>Is the application supposed to be run with <code>#{h ruby}</code>?" \
832
+ " If not, please change the <a href=\"#{h passenger_ruby_doc}\">#{h passenger_ruby}</a>" \
833
+ " setting.</p>"
506
834
  if PlatformInfo.in_rvm?
507
- comment <<
508
- " <li>Please check whether the correct RVM gemset is being used.</li>\n" +
509
- " <li>Sometimes, RVM gemsets may be broken.\n" +
510
- " <a href=\"https://github.com/phusion/passenger/wiki/Resetting-RVM-gemsets\">Try resetting them.</a></li>\n"
835
+ solution_description <<
836
+ "<h3>Check whether the application is being run under the correct RVM gemset</h3>" \
837
+ "<p>Is the application supposed to run under the <code>#{h PlatformInfo.rvm_ruby_string}</code>" \
838
+ " gemset? If not, please change the <a href=\"#{h passenger_ruby_doc}\">#{h passenger_ruby}</a>" \
839
+ " setting. The documentation for that setting will teach you how to refer" \
840
+ " to the proper gemset.</p>"
511
841
  end
512
- comment << "</ol>\n"
513
- prepend_exception_html_comment(e, comment)
842
+ if ruby =~ %r(^/usr/local/rvm/)
843
+ solution_description <<
844
+ "<h3>Is your gem bundle installed to the home directory, while at the same" \
845
+ " time you are using a Ruby that is installed by RVM in a system-wide manner?</h3>" \
846
+ "<p>Your Ruby interpreter is installed by RVM in a system-wide manner: it is" \
847
+ " located in #{h ruby}. If Bundler tries to load gems from " \
848
+ "<code>#{h home_dir}</code>/.rvm/gems, then that won't work.</p>" \
849
+ "<p>To make Bundler and RVM able to load gems from the home directory, set " \
850
+ "<a href=\"#{h passenger_ruby_doc}\">#{h passenger_ruby}</a> to an RVM wrapper script " \
851
+ "inside the home directory:</p>\n\n" \
852
+ "<ol>\n" \
853
+ " <li>Login as #{h whoami}.</li>\n"
854
+ if PlatformInfo.rvm_installation_mode == :multi
855
+ solution_description <<
856
+ " <li>Enable RVM mixed mode by running:\n" \
857
+ " <pre>rvm user gemsets</pre></li>\n"
858
+ end
859
+ solution_description <<
860
+ " <li>Run this to find out what to set" \
861
+ " <a href=\"#{h passenger_ruby_doc}\">#{h passenger_ruby}</a> to:\n" \
862
+ " <pre>#{h PlatformInfo.ruby_command} \\\n" \
863
+ "#{PhusionPassenger.bin_dir}/passenger-config about ruby-command</pre></li>\n" \
864
+ "</ol>\n\n"
865
+ end
866
+ if PlatformInfo.in_rvm?
867
+ solution_description <<
868
+ "<h3>Reset your RVM gemset</h3>" \
869
+ "<p>Sometimes, RVM gemsets maybe be broken. " \
870
+ "<a href=\"https://github.com/phusion/passenger/wiki/Resetting-RVM-gemsets\">" \
871
+ "Try resetting them.</a></p>"
872
+ end
873
+ attach_solution_description_html_to_exception(e, solution_description)
514
874
  end
515
875
  raise e
516
876
  end
517
877
 
518
- def prepend_exception_html_comment(e, comment)
519
- # Since Exception doesn't allow changing the message, we monkeypatch
520
- # the #message and #to_s methods.
521
- separator = "\n<p>-------- The exception is as follows: -------</p>\n"
522
- new_message = comment + separator + h(e.message)
523
- new_s = comment + separator + h(e.to_s)
524
- metaclass = class << e; self; end
525
- metaclass.send(:define_method, :message) do
526
- new_message
878
+ def check_execution_environment_solution_description(passenger_user, passenger_user_doc, bundle_path)
879
+ result = ''
880
+ result << %Q{
881
+ <h3>Check the application process's execution environment</h3>
882
+ <p>
883
+ Is the application running under the expected execution environment?
884
+ A common problem is that the application runs under a different user than
885
+ it is supposed to. The application is currently running as the <code>#{h whoami}</code>
886
+ user &mdash; is this expected? Also, check the 'Detailed diagnostics'
887
+ &raquo; 'Subprocess' tab and double check all information there &mdash; is
888
+ everything as expected?
889
+ </p>
890
+ }
891
+ if passenger_user
892
+ result << %Q{
893
+ <p>
894
+ If the application is not supposed to run as <code>#{h whoami}</code>,
895
+ then you can configure this via the
896
+ <a href="#{h passenger_user_doc}">#{h passenger_user}</a>
897
+ setting.
898
+ </p>
899
+ }
527
900
  end
528
- metaclass.send(:define_method, :to_s) do
529
- new_s
901
+ result << %Q{
902
+ <h3>Check that the application has permissions to access the directory from which Bundler loads gems</h3>
903
+ <p>
904
+ Please check whether the application, which is running as the
905
+ <code>#{h whoami}</code> user, has permissions to access
906
+ }
907
+ if bundle_path
908
+ result << %Q{
909
+ <code>#{h bundle_path}</code>.
910
+ }
911
+ else
912
+ result << %Q{
913
+ the directory that Bundler tries to load gems from. Unfortunately
914
+ #{SHORT_PROGRAM_NAME} was unable to figure out which directory this
915
+ is because Bundler is too old, so you need to figure out the
916
+ directory yourself (or you can upgrade Bundler so that #{SHORT_PROGRAM_NAME}
917
+ can figure out the path for you).
918
+ }
919
+ end
920
+ result << %Q{
921
+ </p>
922
+ }
923
+ result
924
+ end
925
+
926
+ def attach_problem_description_html_to_exception(e, html)
927
+ metaclass = class << e; self; end
928
+ metaclass.send(:define_method, :problem_description_html) do
929
+ html
530
930
  end
531
- metaclass.send(:define_method, :html?) do
532
- true
931
+ end
932
+
933
+ def attach_solution_description_html_to_exception(e, html)
934
+ metaclass = class << e; self; end
935
+ metaclass.send(:define_method, :solution_description_html) do
936
+ html
533
937
  end
534
938
  end
535
939
 
940
+ def try_write_file(path, contents)
941
+ @main_app.try_write_file(path, contents)
942
+ end
943
+
536
944
  def h(text)
537
945
  require 'erb' if !defined?(ERB)
538
- return ERB::Util.h(text)
946
+ ERB::Util.h(text)
539
947
  end
540
948
 
541
949
  def whoami
@@ -546,14 +954,14 @@ module PhusionPassenger
546
954
  user = nil
547
955
  end
548
956
  if user
549
- return user.name
957
+ user.name
550
958
  else
551
- return "##{Process.uid}"
959
+ "##{Process.uid}"
552
960
  end
553
961
  end
554
962
 
555
963
  def home_dir
556
- return PhusionPassenger.home_dir
964
+ PhusionPassenger.home_dir
557
965
  end
558
966
  end
559
967