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
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZTQ0MDViNGU5MDc1Y2NiOTY1YThiMjQ3MjBlYTUwYjUxOWM0NGU5OA==
4
+ YWY1YWQzNTEzOGZmMDA4YmI2YTEwNjdkZTExMDllZDE5MWIzMGQ3ZA==
5
5
  data.tar.gz: !binary |-
6
- N2ZiYTc1ZTAzOGY1ZmU1YWZmODU1NDg5ZjRiNTI4ZjgyZDQyZTZlNg==
6
+ ZGQzYjM2ZDZiNjc1YjA5NDMzN2NkMGQwZWUwYTk0NjU5MWRjYmMyNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzNiODkxN2U5ODU5ODRlYWRjOTdjYjUwZjcyNmE3NjA2NDI4ZGNlNmNhOTVi
10
- YmZlOTdlZWI5M2E2NmU1MDBlMDhmYTQwMGMyNjJkYzI2NGMxZmJlOGZhNWVm
11
- NDFkMWUwMTM3MDUxNGI3YWM2MGEyMzJiNTc3ZjQwYmQ2YWY2YWE=
9
+ OGU1OGZmNDAzZDY4MThmY2YxNTFlNGY5OWEwZTFiYzhjMmU1MTAxN2UwYWIw
10
+ M2NhYjA2NmU5N2UwMWQyNzQ4NmUxYjcwMGIxM2E2MjI5OWQ4NDhmNDRlM2Ux
11
+ M2I1ZDEwMzBhNjJiNDNlZTI3MDc1OGQ5MDZlMzA2Zjg5NzlkNDU=
12
12
  data.tar.gz: !binary |-
13
- MGQxNjFkZDJlNTY3MzFlNzg0OTg3M2FkZGQyOGM3NWFlMTEwZTE5MzNjYmNj
14
- YzJlYzYxMjY0ZTFiY2U1NGI4NzBmMWE2NDhjMWM3YTM2YzM2NzAzYzExOWEw
15
- ZTJiYWJmMzVkODRiYzkzNGZmYmRhZjQwYjQ3NmEzN2QxZmM0MTM=
13
+ MWQ0YTYxZGRiNWZjNDAxZTFlYTgzNzU2YTgyZmFhODJmYjg3MjE1ODI4YzE4
14
+ MmFhNGM4OTEzNDQ4M2U5MmZiMzQ1OTk1NzYyZDdjOTU0ZjQxNThiMjM3OTJk
15
+ ODEwZTExZGY2YWU0MTVkOTUxY2U3NGE5M2Y3MjdhYjkwNjRhYzI=
checksums.yaml.gz.asc CHANGED
@@ -2,11 +2,11 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQEcBAABAgAGBQJU2MfxAAoJECrHRaUKISqMefAIALEqsDj8171WM+YPJkMt0Nx+
6
- MPGtiPoLrhwO0ctDfFz+AFOTmFC4/VZMmozBC6dgHPKMhDyTcg0q9h0OvIsOncjM
7
- eWx/V9t/9km1EeYVLY+9ZbMa2UtYFZv9PQeWSN9h3czv3O9mWNlK9WsyMEfag1xO
8
- 3+aLjce9Zb8KCwEX/CoeE/X637ZADlEUk2homyg10xwfRloOUqQQWNQrWdU1I/XR
9
- 3cjfwVQPbta+D5jJj7Ub6yXfOEZOtU5qTwFnHWelznfVo+PiFRN1wu6IBqfixZRl
10
- ddg4MkM1ywbzoMeRsG8rKrxOosJg7u+tk5YqSYP1jiG0GwfH8VHAsIhiHnGNjw4=
11
- =c49l
5
+ iQEcBAABAgAGBQJU5fgMAAoJECrHRaUKISqMdiEH/A95x8IXUvRhHFkvyoaspc4/
6
+ CfFfHjwfljWhjwstBpwSuAcFrv4QYMBV331qzQRZM2yI9gln/HaOfaeDSVX7rlyM
7
+ 1gd1c/o6GWlbymy/81+3lC4oNy1/nkP37gZH+QQ+42Nv+UHpY6qzMt1TFztqhOfv
8
+ 5n1dPZtJMOpsdo1mGgcZeebDuvKsRt1j6PixU2vVJc90L/bd27kcZnKjXn73daol
9
+ idBO8GEKfoUxm7VsoAxESHZLloUI7RWHRntvfW39+EnOyzduZBUFLUCWgpHDewJI
10
+ r3zkbbcrC0q77lVwGDlZMN5s03TuxFWTTIcxhGtkOIkC7fnzD6qm+/eXDPOp/48=
11
+ =arpK
12
12
  -----END PGP SIGNATURE-----
data.tar.gz.asc CHANGED
@@ -2,11 +2,11 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQEcBAABAgAGBQJU2MfxAAoJECrHRaUKISqMa4oH/11YAlJ8yVRBplmhZNqOtsZ5
6
- glzpkrNE/2TSl82occQKHW/qZz8ay1iUOTjPrRiUkYJkgEYn7j8f3WmLUEoEjqNp
7
- ZZX3eTEOb6/x86A5Ejr2FZqjEmqxLv3v4MdiG8rXj2Cl9iRvK0MIDSBKhckPaMj7
8
- M+JFrJSvGWbpAuU1rilsmSK27oCrQDOYATd0U0J+muAckWkzUiTYK6XUmp894iXD
9
- +QV4FsEe7pTptQOHZuewWtn8n+kwcrHfVP/iL4aqMJOh7LyK3KTAgFr6R4efiNL+
10
- 3O4opHc1qg8TBXMf9DUl7s43HoyY4vY5MDWKwiUzPl8Z32t1Y1h0zrlbnTtcPtY=
11
- =2KEK
5
+ iQEcBAABAgAGBQJU5fgMAAoJECrHRaUKISqMhBQH/i667vaEo5PDWPZTprBUD5Xu
6
+ lYLsnc4g5TyWYG309u3aOfd3GnZ+hI8gkR3daBZ2SmJWLI3uLfNpNielH8j9m+G8
7
+ JgjLgKw/UiIwrfvqyQHSaCiN7UDx8qM56kYePUFA3GL4WgsTB5nXFq6TUaXp2CqR
8
+ tOB38iLPL978foqMhu1kNiT+7IFj4OZ/L037EZYSGsOvmGF/fSQkQ4eEFa6AH4md
9
+ lLaeEvqaFQculPUFrg2GNjv39fnCNrmDsm+XuMDNf55SX1hma5LOVXnbIufesr//
10
+ ls5lAVBzlmdE9GlCuj4UfdW8MceHvUqm98/dFt5btoB5kaz0xEVPWeEfQMN8FAE=
11
+ =HsCD
12
12
  -----END PGP SIGNATURE-----
data/.editorconfig CHANGED
@@ -7,8 +7,9 @@ end_of_line = lf
7
7
  charset = utf-8
8
8
 
9
9
  [bin/*]
10
- indent_style=tab
11
- indent_size=4
10
+ indent_style=space
11
+ indent_size=2
12
+ trim_trailing_whitespace = true
12
13
 
13
14
  [doc/*.txt]
14
15
  indent_style=tab
@@ -43,11 +44,11 @@ trim_trailing_whitespace = true
43
44
  insert_final_newline = true
44
45
 
45
46
  [*.rb]
46
- indent_style = tab
47
- indent_size = 4
47
+ indent_style = space
48
+ indent_size = 2
48
49
  trim_trailing_whitespace = true
49
50
 
50
- [lib/phusion_passenger/utils/json.rb]
51
+ [config.ru]
51
52
  indent_style = space
52
53
  indent_size = 2
53
54
  trim_trailing_whitespace = true
@@ -74,3 +75,8 @@ trim_trailing_whitespace = false
74
75
  indent_style = space
75
76
  indent_size = 2
76
77
  trim_trailing_whitespace = false
78
+
79
+ [resources/templates/standalone/config.erb]
80
+ indent_style = space
81
+ indent_size = 4
82
+ trim_trailing_whitespace = true
data/CHANGELOG CHANGED
@@ -1,3 +1,25 @@
1
+ Release 5.0.0 release candidate 1
2
+ ---------------------------------
3
+
4
+ * Fixed Date headers not being formatted in the GMT timezone. Closes GH-1367.
5
+ * Fixed Passengerfile.json/passenger-standalone.json not being properly loaded in Passenger Standalone.
6
+ * Fixed support for sticky sessions.
7
+ * Fixed an infinite loop if the ApplicationPool garbage collector fails due to an exception. Closes GH-1360.
8
+ * Fixed Passenger Standalone exiting prematurely when the HelperAgent crashes. Exiting prematurely is not supposed to happen because the watchdog will restart the HelperAgent. Closes GH-1339.
9
+ * Fixed a crash that occurs when using a non-standard startup file value. Closes GH-1378.
10
+ * When dumping system metrics during error page generation, the `passenger-config` command is now invoked under the same Ruby interpreter as the app, instead of the one in PATH. Closes GH-1381.
11
+ * When a Ruby process crashes due to an uncaught exception, this fact is now properly logged.
12
+ * Specifying 0 for the `max_pool_size` config option no longer results in a crash. Closes GH-1334.
13
+ * The timeouts when downloading Passenger Standalone binaries and source files are now customizable. Closes GH-1295.
14
+ * The `envvars` option is now supported in Passengerfile.json, for passing environment variables to the application. Closes GH-1377.
15
+ * Introduced `hook_queue_full_error` for request queue overflows. Closes GH-1358.
16
+ * [Ruby] Fixed handling of "transfer-encoding chunked" response bodies which contain zero-sized chunks.
17
+ * [Nginx] It is no longer necessary to re-specify `passenger_enabled` in `location` contexts. Closes GH-1338.
18
+ * [Enterprise] Fixed a bug in mass deployment reloading.
19
+ * [Enterprise] Fixed a bug in mass deployment daemonization.
20
+ * [Enterprise] The mass deployment mode now supports the `app_type` and `startup_file` configuration options in Passengerfile.json/passenger-standalone.json. Closes GH-1366.
21
+
22
+
1
23
  Release 5.0.0 beta 3
2
24
  --------------------
3
25
 
@@ -60,6 +82,22 @@ Minor changes:
60
82
  * [Standalone] `passenger-standalone.json`/`Passengerfile.json` no longer overrides command line options. Instead, command line options now have the highest priority.
61
83
 
62
84
 
85
+ Release 4.0.60
86
+ --------------
87
+
88
+ * Fixed the password protection of internal Phusion Passenger processes.
89
+
90
+ For security reasons, Phusion Passenger limits access to internal processes, by using Unix file permissions and randomly generated passwords that only authorized internal processes know. It turns out that this password wasn't set correctly, which has now been fixed. There was no security vulnerability, because the file permissions already provide sufficient security. The password only serves as an extra layer of security just in case there is a problem with the former.
91
+
92
+ This issue is not at all related to any application-level security or application-level passwords. Any database passwords, keys, or secrets used and generated by applications have got nothing to do with the nature of this issue. This issue only relates to some randomly generated passwords that Passenger uses internally, for its internal operations.
93
+
94
+
95
+ Release 4.0.59
96
+ --------------
97
+
98
+ * [Enterprise] Fixed support for free-style Node.js apps.
99
+
100
+
63
101
  Release 4.0.58
64
102
  --------------
65
103
 
data/CONTRIBUTING.md CHANGED
@@ -329,10 +329,7 @@ Less important directories:
329
329
  <a name="ruby_coding_style"></a>
330
330
  ### Ruby coding style
331
331
 
332
- The usual Ruby coding style applies, with some exceptions:
333
-
334
- * Use 4-space tabs for indentation.
335
- * Return values explicitly with `return`.
332
+ The usual Ruby coding style applies. That is, 2 spaces for indenting.
336
333
 
337
334
  <a name="systems_programming_fundamentals"></a>
338
335
  ### Systems programming fundamentals
data/Gemfile CHANGED
@@ -3,7 +3,6 @@ source 'https://rubygems.org/'
3
3
  group :base do
4
4
  gem 'mime-types', '1.25'
5
5
  gem 'rspec', '2.14.1'
6
- gem 'daemon_controller'
7
6
  gem 'rake'
8
7
  gem 'drake'
9
8
  gem 'json'
data/Gemfile.lock CHANGED
@@ -3,7 +3,6 @@ GEM
3
3
  specs:
4
4
  bluecloth (2.2.0)
5
5
  comp_tree (1.1.3)
6
- daemon_controller (1.2.0)
7
6
  diff-lcs (1.2.5)
8
7
  drake (0.9.2.0.3.1)
9
8
  comp_tree (>= 1.1.3)
@@ -30,7 +29,6 @@ PLATFORMS
30
29
 
31
30
  DEPENDENCIES
32
31
  bluecloth
33
- daemon_controller
34
32
  drake
35
33
  json
36
34
  mime-types (= 1.25)
data/Rakefile CHANGED
@@ -22,58 +22,58 @@ $LOAD_PATH.unshift("#{source_root}/lib")
22
22
  # Otherwise all Ruby commands will take slightly longer to start, which messes up
23
23
  # timing-sensitive tests like those in the C++ test suite.
24
24
  if defined?(Bundler)
25
- clean_env = nil
26
- Bundler.with_clean_env do
27
- clean_env = ENV.to_hash
28
- end
29
- ENV.replace(clean_env)
30
- ARGV.each do |arg|
31
- if arg =~ /^(\w+)=(.*)$/m
32
- ENV[$1] = $2
33
- end
34
- end
25
+ clean_env = nil
26
+ Bundler.with_clean_env do
27
+ clean_env = ENV.to_hash
28
+ end
29
+ ENV.replace(clean_env)
30
+ ARGV.each do |arg|
31
+ if arg =~ /^(\w+)=(.*)$/m
32
+ ENV[$1] = $2
33
+ end
34
+ end
35
35
  end
36
36
 
37
37
  require "#{source_root}/config" if File.exist?("#{source_root}/config.rb")
38
38
  require 'build/basics'
39
39
  if boolean_option('ONLY_RUBY')
40
- require 'build/ruby_extension'
40
+ require 'build/ruby_extension'
41
41
  else
42
- require 'build/ruby_extension'
43
- require 'build/common_library'
44
- require 'build/agents'
45
- require 'build/apache2'
46
- require 'build/nginx'
47
- require 'build/documentation'
48
- require 'build/packaging'
49
- require 'build/test_basics'
50
- require 'build/oxt_tests'
51
- require 'build/cxx_tests'
52
- require 'build/ruby_tests'
53
- require 'build/node_tests'
54
- require 'build/integration_tests'
55
- require 'build/misc'
56
- require 'build/debian'
42
+ require 'build/ruby_extension'
43
+ require 'build/common_library'
44
+ require 'build/agents'
45
+ require 'build/apache2'
46
+ require 'build/nginx'
47
+ require 'build/documentation'
48
+ require 'build/packaging'
49
+ require 'build/test_basics'
50
+ require 'build/oxt_tests'
51
+ require 'build/cxx_tests'
52
+ require 'build/ruby_tests'
53
+ require 'build/node_tests'
54
+ require 'build/integration_tests'
55
+ require 'build/misc'
56
+ require 'build/debian'
57
57
  end
58
58
 
59
59
  #### Default tasks
60
60
 
61
61
  task :default do
62
- abort "Please type one of:\n" +
63
- " rake apache2\n" +
64
- " rake nginx"
62
+ abort "Please type one of:\n" +
63
+ " rake apache2\n" +
64
+ " rake nginx"
65
65
  end
66
66
 
67
67
  desc "Remove compiled files"
68
68
  task :clean => 'clean:cache' do
69
- if OUTPUT_DIR == "buildout/"
70
- sh "rm -rf buildout"
71
- end
69
+ if OUTPUT_DIR == "buildout/"
70
+ sh "rm -rf buildout"
71
+ end
72
72
  end
73
73
 
74
74
  task 'common:clean' => 'clean:cache'
75
75
  task 'clean:cache' do
76
- sh "rm -rf #{OUTPUT_DIR}cache"
76
+ sh "rm -rf #{OUTPUT_DIR}cache"
77
77
  end
78
78
 
79
79
  desc "Remove all generated files"
data/bin/passenger CHANGED
@@ -26,7 +26,7 @@
26
26
  source_root = File.expand_path("..", File.dirname(__FILE__))
27
27
  $LOAD_PATH.unshift("#{source_root}/lib")
28
28
  begin
29
- require 'rubygems'
29
+ require 'rubygems'
30
30
  rescue LoadError
31
31
  end
32
32
  require 'phusion_passenger'
data/bin/passenger-config CHANGED
@@ -26,7 +26,7 @@
26
26
  source_root = File.expand_path("..", File.dirname(__FILE__))
27
27
  $LOAD_PATH.unshift("#{source_root}/lib")
28
28
  begin
29
- require 'rubygems'
29
+ require 'rubygems'
30
30
  rescue LoadError
31
31
  end
32
32
  require 'phusion_passenger'
@@ -27,7 +27,7 @@
27
27
  source_root = File.expand_path("..", File.dirname(__FILE__))
28
28
  $LOAD_PATH.unshift("#{source_root}/lib")
29
29
  begin
30
- require 'rubygems'
30
+ require 'rubygems'
31
31
  rescue LoadError
32
32
  end
33
33
  require 'phusion_passenger'
@@ -51,818 +51,818 @@ PhusionPassenger.require_passenger_lib 'abstract_installer'
51
51
  PhusionPassenger.require_passenger_lib 'utils/terminal_choice_menu'
52
52
 
53
53
  class Installer < PhusionPassenger::AbstractInstaller
54
- include PhusionPassenger
55
- TerminalChoiceMenu = PhusionPassenger::Utils::TerminalChoiceMenu
56
-
57
- AUTOINSTALL_BEGIN_LOAD_BLOCK = "### Begin automatically installed #{PROGRAM_NAME} load snippet ###"
58
- AUTOINSTALL_END_LOAD_BLOCK = "### End automatically installed #{PROGRAM_NAME} load snippet ###"
59
- AUTOINSTALL_BEGIN_CONF_BLOCK = "### Begin automatically installed #{PROGRAM_NAME} config snippet ###"
60
- AUTOINSTALL_END_CONF_BLOCK = "### End automatically installed #{PROGRAM_NAME} config snippet ###"
61
-
62
- def dependencies
63
- specs = [
64
- 'depcheck_specs/compiler_toolchain',
65
- 'depcheck_specs/ruby',
66
- 'depcheck_specs/gems',
67
- 'depcheck_specs/libs',
68
- 'depcheck_specs/apache2'
69
- ]
70
- ids = [
71
- 'cc',
72
- 'c++',
73
- 'libcurl-dev',
74
- 'openssl-dev',
75
- 'zlib-dev',
76
- 'apache2',
77
- 'apache2-dev',
78
- 'rake',
79
- 'ruby-openssl',
80
- 'rubygems'
81
- ]
82
- if @languages.include?("ruby")
83
- if PlatformInfo.passenger_needs_ruby_dev_header?
84
- ids << 'ruby-dev'
85
- end
86
- ids << 'rack'
87
- end
88
- # Some broken servers don't have apr-config or apu-config installed.
89
- # Nevertheless, it is possible to compile Apache modules if Apache
90
- # was configured with --included-apr. So here we check whether
91
- # apr-config and apu-config are available. If they're not available,
92
- # then we only register them as required dependency if no Apache
93
- # module can be compiled without their presence.
94
- if (PlatformInfo.apr_config && PlatformInfo.apu_config) ||
95
- PlatformInfo.apr_config_needed_for_building_apache_modules?
96
- ids << 'apr-dev'
97
- ids << 'apu-dev'
98
- end
99
- return [specs, ids]
100
- end
101
-
102
- def users_guide_path
103
- return PhusionPassenger.apache2_doc_path
104
- end
105
-
106
- def users_guide_url
107
- return APACHE2_DOC_URL
108
- end
109
-
110
- def run_steps
111
- if PhusionPassenger.build_system_dir.nil?
112
- # Invariant: PhusionPassenger.custom_packaged?
113
- if apache_module_available?
114
- notify_apache_module_installed
115
- show_deployment_example
116
- else
117
- install_apache_module_from_native_package || exit(1)
118
- end
119
- exit
120
- end
121
-
122
- Dir.chdir(PhusionPassenger.build_system_dir)
123
- show_welcome_screen
124
- query_interested_languages
125
- check_gem_install_permission_problems || exit(1)
126
- check_directory_accessible_by_web_server
127
- check_dependencies || exit(1)
128
- check_whether_there_are_multiple_apache_installs || exit
129
- check_whether_apache_uses_compatible_mpm
130
- check_whether_os_is_broken
131
- check_whether_system_has_enough_ram
132
- check_write_permission_to_passenger_root || exit(1)
133
- check_write_permission_to_web_server_config_files || exit(1)
134
- if compile_apache2_module
135
- install_apache2_config_snippets || exit(1)
136
- show_deployment_example
137
- else
138
- show_possible_solutions_for_compilation_and_installation_problems
139
- exit(1)
140
- end
141
- end
54
+ include PhusionPassenger
55
+ TerminalChoiceMenu = PhusionPassenger::Utils::TerminalChoiceMenu
56
+
57
+ AUTOINSTALL_BEGIN_LOAD_BLOCK = "### Begin automatically installed #{PROGRAM_NAME} load snippet ###"
58
+ AUTOINSTALL_END_LOAD_BLOCK = "### End automatically installed #{PROGRAM_NAME} load snippet ###"
59
+ AUTOINSTALL_BEGIN_CONF_BLOCK = "### Begin automatically installed #{PROGRAM_NAME} config snippet ###"
60
+ AUTOINSTALL_END_CONF_BLOCK = "### End automatically installed #{PROGRAM_NAME} config snippet ###"
61
+
62
+ def dependencies
63
+ specs = [
64
+ 'depcheck_specs/compiler_toolchain',
65
+ 'depcheck_specs/ruby',
66
+ 'depcheck_specs/gems',
67
+ 'depcheck_specs/libs',
68
+ 'depcheck_specs/apache2'
69
+ ]
70
+ ids = [
71
+ 'cc',
72
+ 'c++',
73
+ 'libcurl-dev',
74
+ 'openssl-dev',
75
+ 'zlib-dev',
76
+ 'apache2',
77
+ 'apache2-dev',
78
+ 'rake',
79
+ 'ruby-openssl',
80
+ 'rubygems'
81
+ ]
82
+ if @languages.include?("ruby")
83
+ if PlatformInfo.passenger_needs_ruby_dev_header?
84
+ ids << 'ruby-dev'
85
+ end
86
+ ids << 'rack'
87
+ end
88
+ # Some broken servers don't have apr-config or apu-config installed.
89
+ # Nevertheless, it is possible to compile Apache modules if Apache
90
+ # was configured with --included-apr. So here we check whether
91
+ # apr-config and apu-config are available. If they're not available,
92
+ # then we only register them as required dependency if no Apache
93
+ # module can be compiled without their presence.
94
+ if (PlatformInfo.apr_config && PlatformInfo.apu_config) ||
95
+ PlatformInfo.apr_config_needed_for_building_apache_modules?
96
+ ids << 'apr-dev'
97
+ ids << 'apu-dev'
98
+ end
99
+ return [specs, ids]
100
+ end
101
+
102
+ def users_guide_path
103
+ return PhusionPassenger.apache2_doc_path
104
+ end
105
+
106
+ def users_guide_url
107
+ return APACHE2_DOC_URL
108
+ end
109
+
110
+ def run_steps
111
+ if PhusionPassenger.build_system_dir.nil?
112
+ # Invariant: PhusionPassenger.custom_packaged?
113
+ if apache_module_available?
114
+ notify_apache_module_installed
115
+ show_deployment_example
116
+ else
117
+ install_apache_module_from_native_package || exit(1)
118
+ end
119
+ exit
120
+ end
121
+
122
+ Dir.chdir(PhusionPassenger.build_system_dir)
123
+ show_welcome_screen
124
+ query_interested_languages
125
+ check_gem_install_permission_problems || exit(1)
126
+ check_directory_accessible_by_web_server
127
+ check_dependencies || exit(1)
128
+ check_whether_there_are_multiple_apache_installs || exit
129
+ check_whether_apache_uses_compatible_mpm
130
+ check_whether_os_is_broken
131
+ check_whether_system_has_enough_ram
132
+ check_write_permission_to_passenger_root || exit(1)
133
+ check_write_permission_to_web_server_config_files || exit(1)
134
+ if compile_apache2_module
135
+ install_apache2_config_snippets || exit(1)
136
+ show_deployment_example
137
+ else
138
+ show_possible_solutions_for_compilation_and_installation_problems
139
+ exit(1)
140
+ end
141
+ end
142
142
 
143
143
  private
144
- def show_welcome_screen
145
- render_template 'apache2/welcome', :version => VERSION_STRING
146
- wait
147
- end
148
-
149
- def query_interested_languages
150
- menu = TerminalChoiceMenu.new(["Ruby", "Python", "Node.js", "Meteor"])
151
- menu["Ruby"].checked = interesting_language?('ruby')
152
- menu["Python"].checked = interesting_language?('python')
153
- menu["Node.js"].checked = interesting_language?('nodejs', 'node')
154
- menu["Meteor"].checked = interesting_language?('meteor')
155
-
156
- new_screen
157
- puts "<banner>Which languages are you interested in?</banner>"
158
- puts
159
- if interactive?
160
- puts "Use <space> to select."
161
- puts "<dgray>If the menu doesn't display correctly, press '!'</dgray>"
162
- else
163
- puts "Override selection with --languages."
164
- end
165
- puts
166
-
167
- if interactive?
168
- begin
169
- menu.query
170
- rescue Interrupt
171
- raise Abort
172
- end
173
- else
174
- menu.display_choices
175
- puts
176
- end
177
-
178
- @languages = menu.selected_choices.map{ |x| x.downcase.gsub(/\./, '') }
179
- end
180
-
181
- def interesting_language?(name, command = nil)
182
- if @languages
183
- return @languages.include?(name)
184
- else
185
- return !!PlatformInfo.find_command(command || name)
186
- end
187
- end
188
-
189
- def check_whether_there_are_multiple_apache_installs
190
- new_screen
191
- puts '<banner>Sanity checking Apache installation...</banner>'
192
-
193
- output = StringIO.new
194
- detector = PlatformInfo::ApacheDetector.new(output)
195
- begin
196
- detector.detect_all
197
- detector.report
198
- @apache2 = detector.result_for(PlatformInfo.apxs2)
199
- if @apache2.nil?
200
- render_template 'apache2/apache_install_broken',
201
- :apxs2 => PlatformInfo.apxs2,
202
- :sudo_s_e => PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E"),
203
- :ruby => PhusionPassenger::PlatformInfo.ruby_command,
204
- :passenger_config => "#{PhusionPassenger.bin_dir}/passenger-config"
205
- return false
206
- end
207
- if detector.results.size > 1
208
- other_installs = detector.results - [@apache2]
209
- render_template 'apache2/multiple_apache_installations_detected',
210
- :current => @apache2,
211
- :other_installs => other_installs
212
- puts
213
- if interactive?
214
- result = prompt_confirmation "Are you sure you want to install " +
215
- "against Apache #{@apache2.version} (#{@apache2.apxs2})?"
216
- if !result
217
- puts
218
- line
219
- render_template 'apache2/installing_against_a_different_apache',
220
- :other_installs => other_installs
221
- end
222
- return result
223
- else
224
- puts '<yellow>Continuing installation because --auto is given.</yellow>'
225
- return true
226
- end
227
- else
228
- puts '<green>All good!</green>'
229
- return true
230
- end
231
- ensure
232
- detector.finish
233
- end
234
- end
235
-
236
- def check_whether_apache_uses_compatible_mpm
237
- # 'httpd -V' output is in the form of:
238
- #
239
- # Server MPM: Prefork # <--- this line is not always available!
240
- # ...
241
- # Server compiled with....
242
- # -D APACHE_MPM_DIR="server/mpm/prefork"
243
- output = PlatformInfo.httpd_V
244
- output =~ /^Server MPM: +(.*)$/
245
- if $1
246
- mpm = $1.downcase
247
- else
248
- output =~ /APACHE_MPM_DIR="server\/mpm\/(.*)"/
249
- if $1
250
- mpm = $1.downcase
251
- else
252
- mpm = nil
253
- end
254
- end
255
- if mpm != "prefork" && mpm != "worker" && mpm != "event"
256
- new_screen
257
- render_template 'apache2/apache_must_be_compiled_with_compatible_mpm',
258
- :current_mpm => mpm
259
- wait
260
- end
261
- end
262
-
263
- def check_write_permission_to_passenger_root
264
- File.new("__test__.txt", "w").close
265
- return true
266
- rescue SystemCallError
267
- puts
268
- line
269
- if Process.uid == 0
270
- render_template 'installer_common/cannot_access_files_as_root',
271
- :type => "directory",
272
- :files => [PhusionPassenger.build_system_dir]
273
- else
274
- render_template 'installer_common/run_installer_as_root',
275
- :dir => PhusionPassenger.build_system_dir,
276
- :sudo => PhusionPassenger::PlatformInfo.ruby_sudo_command,
277
- :sudo_s_e => PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E"),
278
- :ruby => PhusionPassenger::PlatformInfo.ruby_command,
279
- :installer => "#{PhusionPassenger.bin_dir}/passenger-install-apache2-module #{ORIG_ARGV.join(' ')}"
280
- end
281
- return false
282
- ensure
283
- File.unlink("__test__.txt") rescue nil
284
- end
285
-
286
- def check_write_permission_to_web_server_config_files
287
- return true if !@update_config
288
- config_file = PlatformInfo.httpd_default_config_file
289
- return if !config_file || !File.exist?(config_file)
290
-
291
- all_config_files = PlatformInfo.httpd_included_config_files(config_file)
292
- if all_config_files[:unreadable_files].any?
293
- puts
294
- line
295
- if Process.uid == 0
296
- render_template 'installer_common/cannot_access_files_as_root',
297
- :access => "read from",
298
- :files => all_config_files[:unreadable_files]
299
- else
300
- render_template 'installer_common/run_installer_as_root',
301
- :access => "read from",
302
- :desc => "an Apache configuration file",
303
- :sudo => PhusionPassenger::PlatformInfo.ruby_sudo_command,
304
- :sudo_s_e => PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E"),
305
- :ruby => PhusionPassenger::PlatformInfo.ruby_command,
306
- :installer => "#{PhusionPassenger.bin_dir}/passenger-install-apache2-module #{ORIG_ARGV.join(' ')}"
307
- end
308
- puts
309
- render_template 'apache2/present_choice_for_no_update_config'
310
- return false
311
- end
312
-
313
- unwriteable_files = []
314
- all_config_files[:files].each do |filename|
315
- if !File.writable_real?(filename)
316
- unwriteable_files << filename
317
- end
318
- end
319
- if unwriteable_files.empty?
320
- return true
321
- else
322
- puts
323
- line
324
- if Process.uid == 0
325
- render_template 'installer_common/cannot_access_files_as_root',
326
- :files => unwriteable_files
327
- else
328
- render_template 'installer_common/run_installer_as_root',
329
- :desc => "an Apache configuration file",
330
- :sudo => PhusionPassenger::PlatformInfo.ruby_sudo_command,
331
- :sudo_s_e => PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E"),
332
- :ruby => PhusionPassenger::PlatformInfo.ruby_command,
333
- :installer => "#{PhusionPassenger.bin_dir}/passenger-install-apache2-module #{ORIG_ARGV.join(' ')}"
334
- end
335
- puts
336
- render_template 'apache2/present_choice_for_no_update_config'
337
- return false
338
- end
339
- end
340
-
341
- def compile_apache2_module
342
- puts
343
- line
344
- puts '<banner>Compiling and installing Apache 2 module...</banner>'
345
- if @compile
346
- puts "cd #{PhusionPassenger.build_system_dir}"
347
- if ENV['TRACE']
348
- rake = "#{PlatformInfo.rake_command} --trace RELEASE=yes"
349
- else
350
- rake = "#{PlatformInfo.rake_command} RELEASE=yes"
351
- end
352
- command = "env NOEXEC_DISABLE=1 #{rake} apache2:clean apache2"
353
- if PhusionPassenger.packaging_method == "homebrew"
354
- # Running apache2:clean deletes some object files needed
355
- # by passenger-install-nginx-module, so we ensure those
356
- # object files are compiled.
357
- command << " nginx"
358
- end
359
- return sh(command)
360
- else
361
- puts "Skipping compilation"
362
- return true
363
- end
364
- end
365
-
366
- def load_snippet
367
- return "LoadModule passenger_module #{PhusionPassenger.apache2_module_path}"
368
- end
369
-
370
- def config_snippet
371
- return "<IfModule mod_passenger.c>\n" +
372
- " PassengerRoot #{PhusionPassenger.install_spec}\n" +
373
- " PassengerDefaultRuby #{PlatformInfo.ruby_command}\n" +
374
- "</IfModule>"
375
- end
376
-
377
- def apache2_config_snippets
378
- return "#{load_snippet}\n#{config_snippet}\n"
379
- end
380
-
381
- def backup_config_files(config_file, all_config_files)
382
- now = Time.now.strftime("%Y-%m-%d-%H:%M:%S")
383
- archive = "#{config_file}.#{GLOBAL_NAMESPACE_DIRNAME}-backup-#{now}.tar.gz"
384
- backup_files = all_config_files.dup
385
-
386
- # Some people create a regular file in /etc/apache2/mods-enabled, for convenience
387
- # reasons. This file is not actually managed by a2enmod. We will remove such files
388
- # because we're going to use mods-eanbled ourselves, so we need to back them up.
389
- if (dir = PlatformInfo.httpd_mods_enabled_directory) && PlatformInfo.a2enmod
390
- if File.file?("#{dir}/#{APACHE2_MODULE_CONF_NAME}.load")
391
- backup_files << "#{dir}/#{APACHE2_MODULE_CONF_NAME}.load"
392
- end
393
- if File.file?("#{dir}/#{APACHE2_MODULE_CONF_NAME}.conf")
394
- backup_files << "#{dir}/#{APACHE2_MODULE_CONF_NAME}.conf"
395
- end
396
- end
397
-
398
- puts "Backing up existing configuration files to #{archive}..."
399
- backup_files.uniq!
400
- backup_files.map! { |x| x.sub(/^\//, '') }
401
- Dir.chdir("/") do
402
- sh! "tar", "-czf", archive, *backup_files
403
- end
404
- end
405
-
406
- def uninstall_or_comment_out_existing_config_snippets(all_config_files)
407
- files_containing_autoinstall_load_blocks = []
408
- files_containing_autoinstall_conf_blocks = []
409
-
410
- # Some people create a regular file in /etc/apache2/mods-enabled, for convenience
411
- # reasons. This file is not actually managed by a2enmod. We remove such files
412
- # because we're going to use mods-enabled ourselves. They've already been backed up.
413
- if (dir = PlatformInfo.httpd_mods_enabled_directory) && PlatformInfo.a2enmod
414
- filename = "#{dir}/#{APACHE2_MODULE_CONF_NAME}.load"
415
- if File.file?(filename) && !File.symlink?(filename)
416
- puts "Removing #{filename}"
417
- File.unlink(filename)
418
- end
419
- filename = "#{dir}/#{APACHE2_MODULE_CONF_NAME}.conf"
420
- if File.file?(filename) && !File.symlink?(filename)
421
- puts "Removing #{filename}"
422
- File.unlink(filename)
423
- end
424
- end
425
-
426
- # Uncomment Phusion Passenger config snippets.
427
- all_config_files.each do |filename|
428
- next if !File.exist?(filename)
429
-
430
- contents = File.open(filename, "rb") do |f|
431
- f.read
432
- end
433
- if contents =~ /#{Regexp.escape AUTOINSTALL_BEGIN_LOAD_BLOCK}.*?#{Regexp.escape AUTOINSTALL_END_LOAD_BLOCK}/m
434
- files_containing_autoinstall_load_blocks << filename
435
- end
436
- if contents =~ /#{Regexp.escape AUTOINSTALL_BEGIN_CONF_BLOCK}.*?#{Regexp.escape AUTOINSTALL_END_CONF_BLOCK}/m
437
- files_containing_autoinstall_conf_blocks << filename
438
- end
439
- subst1 = contents.gsub!(/^([ \t]*LoadModule[ \t]+passenger_module[ \t]+.*)$/i, '# \1')
440
- subst2 = contents.gsub!(/^([ \t]*PassengerRoot[ \t]+.*)$/i, '# \1')
441
- subst3 = contents.gsub!(/^([ \t]*PassengerDefaultRuby[ \t]+.*)$/i, '# \1')
442
- if subst1 || subst2 || subst3
443
- puts "Uninstalling previous #{PROGRAM_NAME} from #{filename}..."
444
- File.open(filename, "wb") do |f|
445
- f.write(contents)
446
- end
447
- end
448
- end
449
-
450
- # If there are multiple auto-install comment blocks, remove the duplicates.
451
- # First, we remove all comment blocks from all files besides the first one.
452
- if files_containing_autoinstall_load_blocks.size > 1
453
- files_containing_autoinstall_load_blocks[1..-1].each do |filename|
454
- puts "Removing duplicate load snippets from #{filename}..."
455
- remove_comment_blocks(filename,
456
- AUTOINSTALL_BEGIN_LOAD_BLOCK,
457
- AUTOINSTALL_END_LOAD_BLOCK)
458
- end
459
- end
460
- if files_containing_autoinstall_conf_blocks.size > 1
461
- files_containing_autoinstall_conf_blocks[1..-1].each do |filename|
462
- puts "Removing duplicate conf snippets from #{filename}..."
463
- remove_comment_blocks(filename,
464
- AUTOINSTALL_BEGIN_CONF_BLOCK,
465
- AUTOINSTALL_END_CONF_BLOCK)
466
- end
467
- end
468
-
469
- # Then we are left with exactly 0 or exactly 1 file with comment blocks
470
- # of each type. There may be duplicates inside that single file, so
471
- # remove duplicates there too.
472
- if files_containing_autoinstall_load_blocks.size > 0
473
- filename = files_containing_autoinstall_load_blocks[0]
474
- puts "Removing duplicate load snippets inside #{filename}..."
475
- remove_duplicate_comment_blocks(filename,
476
- AUTOINSTALL_BEGIN_LOAD_BLOCK,
477
- AUTOINSTALL_END_LOAD_BLOCK)
478
- end
479
- if files_containing_autoinstall_conf_blocks.size > 0
480
- filename = files_containing_autoinstall_conf_blocks[0]
481
- puts "Removing duplicate configuration snippets inside #{filename}..."
482
- remove_duplicate_comment_blocks(filename,
483
- AUTOINSTALL_BEGIN_CONF_BLOCK,
484
- AUTOINSTALL_END_CONF_BLOCK)
485
- end
486
-
487
- # One or more files may have been removed, so filter out the ones
488
- # that are left.
489
- all_config_files.reject! do |filename|
490
- !File.exist?(filename)
491
- end
492
- end
493
-
494
- def remove_comment_blocks(filename, begin_marker, end_marker)
495
- contents = File.open(filename, "rb") do |f|
496
- f.read
497
- end
498
- regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}\n?/m
499
- contents.gsub!(regexp, '')
500
- File.open(filename, "wb") do |f|
501
- f.write(contents)
502
- end
503
- end
504
-
505
- def remove_duplicate_comment_blocks(filename, begin_marker, end_marker)
506
- contents = File.open(filename, "rb") do |f|
507
- f.read
508
- end
509
- regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}\n?/m
510
- if m = regexp.match(contents)
511
- offset = m.end(0)
512
- rest = contents.slice!(m.end(0) .. -1)
513
- rest.gsub!(regexp, '')
514
- contents << rest
515
- File.open(filename, "wb") do |f|
516
- f.write(contents)
517
- end
518
- end
519
- end
520
-
521
- def add_new_config_snippets(all_config_files)
522
- # Look for the file containing the auto-install load and conf comment blocks.
523
- # The uninstall_or_comment_out_existing_config_snippets method has already
524
- # guaranteed that there is at most 1 file per comment block type, and that
525
- # inside each file there are no duplicate comment blocks.
526
- load_block_file = find_config_file_containing_comment_block(all_config_files,
527
- AUTOINSTALL_BEGIN_LOAD_BLOCK,
528
- AUTOINSTALL_END_LOAD_BLOCK)
529
- conf_block_file = find_config_file_containing_comment_block(all_config_files,
530
- AUTOINSTALL_BEGIN_CONF_BLOCK,
531
- AUTOINSTALL_END_CONF_BLOCK)
532
- if load_block_file && conf_block_file
533
- puts "Updating #{PROGRAM_NAME} module load snippet inside #{load_block_file}..."
534
- update_comment_block(load_block_file,
535
- AUTOINSTALL_BEGIN_LOAD_BLOCK,
536
- AUTOINSTALL_END_LOAD_BLOCK,
537
- load_snippet)
538
- puts "Updating #{PROGRAM_NAME} configuration snippet inside #{conf_block_file}..."
539
- update_comment_block(conf_block_file,
540
- AUTOINSTALL_BEGIN_CONF_BLOCK,
541
- AUTOINSTALL_END_CONF_BLOCK,
542
- config_snippet)
543
- elsif !load_block_file && !conf_block_file
544
- create_load_snippet_file(:maybe_in_mods_available)
545
- create_conf_snippet_file(:maybe_in_mods_available)
546
- if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
547
- sh! "#{PlatformInfo.a2enmod} #{APACHE2_MODULE_CONF_NAME}"
548
- end
549
- # It looks like either the load or conf file isn't available.
550
- # If the file that is available is inside mods-available, then it
551
- # means that the mods-available files are broken.
552
- elsif is_file_inside_mods_available?(load_block_file, "#{APACHE2_MODULE_CONF_NAME}.load") ||
553
- is_file_inside_mods_available?(conf_block_file, "#{APACHE2_MODULE_CONF_NAME}.conf")
554
- # We fix it if a2enmod is available. Otherwise, we remove the block.
555
- if PlatformInfo.a2enmod
556
- if !load_block_file
557
- create_load_snippet_file(:must_be_in_mods_available)
558
- else
559
- create_conf_snippet_file(:must_be_in_mods_available)
560
- end
561
- else
562
- if load_block_file
563
- puts "Removing load snippets from #{filename}..."
564
- remove_comment_blocks(load_block_file,
565
- AUTOINSTALL_BEGIN_LOAD_BLOCK,
566
- AUTOINSTALL_END_LOAD_BLOCK)
567
- else
568
- puts "Removing configuration snippets from #{filename}..."
569
- remove_comment_blocks(conf_block_file,
570
- AUTOINSTALL_BEGIN_CONF_BLOCK,
571
- AUTOINSTALL_END_CONF_BLOCK)
572
- end
573
- create_load_snippet_file(:must_be_in_mods_available)
574
- create_conf_snippet_file(:must_be_in_mods_available)
575
- end
576
- sh! "#{PlatformInfo.a2enmod} passenger"
577
- else
578
- if !load_block_file
579
- create_load_snippet_file(:not_in_mods_available)
580
- puts "Updating #{PROGRAM_NAME} configuration snippet inside #{conf_block_file}..."
581
- update_comment_block(conf_block_file,
582
- AUTOINSTALL_BEGIN_CONF_BLOCK,
583
- AUTOINSTALL_END_CONF_BLOCK,
584
- config_snippet)
585
- else
586
- create_conf_snippet_file(:not_in_mods_available)
587
- puts "Updating #{PROGRAM_NAME} module load snippet inside #{load_block_file}..."
588
- update_comment_block(load_block_file,
589
- AUTOINSTALL_BEGIN_LOAD_BLOCK,
590
- AUTOINSTALL_END_LOAD_BLOCK,
591
- load_snippet)
592
- end
593
- end
594
- end
595
-
596
- def find_config_file_containing_comment_block(all_config_files, begin_marker, end_marker)
597
- regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}/m
598
- all_config_files.each do |filename|
599
- contents = File.open(filename, "rb") do |f|
600
- f.read
601
- end
602
- if contents =~ regexp
603
- return filename
604
- end
605
- end
606
- return nil
607
- end
608
-
609
- def update_comment_block(filename, begin_marker, end_marker, block_contents)
610
- regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}\n?/m
611
- contents = File.open(filename, "rb") do |f|
612
- f.read
613
- end
614
- if contents.sub!(regexp, "#{begin_marker}\n#{block_contents}\n#{end_marker}\n")
615
- File.open(filename, "wb") do |f|
616
- f.write(contents)
617
- end
618
- return true
619
- else
620
- return false
621
- end
622
- end
623
-
624
- def remove_comment_blocks(filename, begin_marker, end_marker)
625
- regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}\n?/m
626
- contents = File.open(filename, "rb") do |f|
627
- f.read
628
- end
629
- contents.gsub!(regexp, "")
630
- File.open(filename, "wb") do |f|
631
- f.write(contents)
632
- end
633
- end
634
-
635
- def is_file_inside_mods_available?(filename, basename)
636
- if dir = PlatformInfo.httpd_mods_available_directory
637
- return filename == "#{dir}/#{basename}"
638
- else
639
- return false
640
- end
641
- end
642
-
643
- def create_load_snippet_file(where)
644
- case where
645
- when :maybe_in_mods_available
646
- if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
647
- filename = "#{PlatformInfo.httpd_mods_available_directory}/#{APACHE2_MODULE_CONF_NAME}.load"
648
- else
649
- filename = PlatformInfo.httpd_default_config_file
650
- end
651
- when :must_be_in_mods_available
652
- if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
653
- filename = "#{PlatformInfo.httpd_mods_available_directory}/#{APACHE2_MODULE_CONF_NAME}.load"
654
- else
655
- raise "Apache does not support the mods-available directory"
656
- end
657
- when :not_in_mods_available
658
- filename = PlatformInfo.httpd_default_config_file
659
- else
660
- raise ArgumentError
661
- end
662
-
663
- if File.exist?(filename)
664
- # If this is a file inside mods-available, and the file didn't have a symlink
665
- # in mods-enabled, then the uninstall phase did not remove duplicates from this
666
- # file. So here we remove duplicates again.
667
- puts "Removing duplicate load snippets inside #{filename}..."
668
- remove_duplicate_comment_blocks(filename,
669
- AUTOINSTALL_BEGIN_LOAD_BLOCK,
670
- AUTOINSTALL_END_LOAD_BLOCK)
671
-
672
- puts "Installing #{PROGRAM_NAME} module load snippet to #{filename}..."
673
- should_add = !update_comment_block(filename,
674
- AUTOINSTALL_BEGIN_LOAD_BLOCK,
675
- AUTOINSTALL_END_LOAD_BLOCK,
676
- load_snippet)
677
- else
678
- puts "Installing #{PROGRAM_NAME} module load snippet to #{filename}..."
679
- should_add = true
680
- end
681
- if should_add
682
- File.open(filename, "ab") do |f|
683
- f.write("\n#{AUTOINSTALL_BEGIN_LOAD_BLOCK}\n" +
684
- "#{load_snippet}\n" +
685
- "#{AUTOINSTALL_END_LOAD_BLOCK}\n")
686
- end
687
- end
688
- end
689
-
690
- def create_conf_snippet_file(where)
691
- case where
692
- when :maybe_in_mods_available
693
- if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
694
- filename = "#{PlatformInfo.httpd_mods_available_directory}/#{APACHE2_MODULE_CONF_NAME}.conf"
695
- else
696
- filename = PlatformInfo.httpd_default_config_file
697
- end
698
- when :must_be_in_mods_available
699
- if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
700
- filename = "#{PlatformInfo.httpd_mods_available_directory}/#{APACHE2_MODULE_CONF_NAME}.conf"
701
- else
702
- raise "Apache does not support the mods-available directory"
703
- end
704
- when :not_in_mods_available
705
- filename = PlatformInfo.httpd_default_config_file
706
- else
707
- raise ArgumentError
708
- end
709
-
710
- if File.exist?(filename)
711
- # If this is a file inside mods-available, and the file didn't have a symlink
712
- # in mods-enabled, then the uninstall phase did not remove duplicates from this
713
- # file. So here we remove duplicates again.
714
- puts "Removing duplicate configuration snippets inside #{filename}..."
715
- remove_duplicate_comment_blocks(filename,
716
- AUTOINSTALL_BEGIN_CONF_BLOCK,
717
- AUTOINSTALL_END_CONF_BLOCK)
718
-
719
- puts "Installing #{PROGRAM_NAME} module configuration snippet to #{filename}..."
720
- should_add = !update_comment_block(filename,
721
- AUTOINSTALL_BEGIN_CONF_BLOCK,
722
- AUTOINSTALL_END_CONF_BLOCK,
723
- config_snippet)
724
- else
725
- puts "Installing #{PROGRAM_NAME} module configuration snippet to #{filename}..."
726
- should_add = true
727
- end
728
- if should_add
729
- File.open(filename, "ab") do |f|
730
- f.write("\n#{AUTOINSTALL_BEGIN_CONF_BLOCK}\n" +
731
- "#{config_snippet}\n" +
732
- "#{AUTOINSTALL_END_CONF_BLOCK}\n")
733
- end
734
- end
735
- end
736
-
737
- def install_apache2_config_snippets
738
- if !@update_config
739
- show_apache2_config_snippets
740
- return true
741
- end
742
-
743
- config_file = PlatformInfo.httpd_default_config_file
744
- if config_file && File.exist?(config_file)
745
- puts
746
- line
747
- puts "<banner>Updating Apache configuration files...</banner>"
748
- config_file = PlatformInfo.httpd_default_config_file
749
- all_config_files = PlatformInfo.httpd_included_config_files(config_file)[:files]
750
- backup_config_files(config_file, all_config_files) if @backup_config
751
- uninstall_or_comment_out_existing_config_snippets(all_config_files)
752
- add_new_config_snippets(all_config_files)
753
- return true
754
- else
755
- show_apache2_config_snippets
756
- return true
757
- end
758
- end
759
-
760
- def show_apache2_config_snippets
761
- puts
762
- line
763
- render_template 'apache2/config_snippets',
764
- :snippet => apache2_config_snippets
765
- wait
766
- end
767
-
768
- def show_deployment_example
769
- new_screen
770
- render_template 'apache2/deployment_example',
771
- :users_guide_path => users_guide_path,
772
- :users_guide_url => users_guide_url,
773
- :phusion_website => PHUSION_WEBSITE,
774
- :passenger_website => PASSENGER_WEBSITE,
775
- :languages => @languages
776
- end
777
-
778
- def show_possible_solutions_for_compilation_and_installation_problems
779
- new_screen
780
- render_template 'apache2/possible_solutions_for_compilation_and_installation_problems',
781
- :users_guide_path => users_guide_path,
782
- :users_guide_url => users_guide_url,
783
- :support_url => SUPPORT_URL
784
- end
785
-
786
- def apache_module_available?
787
- return File.exist?(PhusionPassenger.apache2_module_path)
788
- end
789
-
790
- def install_apache_module_from_native_package
791
- case PhusionPassenger.packaging_method
792
- when 'deb'
793
- sh! "sudo apt-get update"
794
- sh! "sudo apt-get install #{DEB_APACHE_MODULE_PACKAGE}"
795
- return true
796
- when 'rpm'
797
- sh! "sudo yum install #{RPM_APACHE_MODULE_PACKAGE}-#{VERSION_STRING}"
798
- return true
799
- else
800
- puts "<red>The #{PROGRAM_NAME} Apache module package is not installed.</red>"
801
- puts "Please ask your packager or operating system vendor how to install it."
802
- return false
803
- end
804
- end
805
-
806
- def notify_apache_module_installed
807
- render_template 'apache2/notify_apache_module_installed'
808
- wait
809
- end
144
+ def show_welcome_screen
145
+ render_template 'apache2/welcome', :version => VERSION_STRING
146
+ wait
147
+ end
148
+
149
+ def query_interested_languages
150
+ menu = TerminalChoiceMenu.new(["Ruby", "Python", "Node.js", "Meteor"])
151
+ menu["Ruby"].checked = interesting_language?('ruby')
152
+ menu["Python"].checked = interesting_language?('python')
153
+ menu["Node.js"].checked = interesting_language?('nodejs', 'node')
154
+ menu["Meteor"].checked = interesting_language?('meteor')
155
+
156
+ new_screen
157
+ puts "<banner>Which languages are you interested in?</banner>"
158
+ puts
159
+ if interactive?
160
+ puts "Use <space> to select."
161
+ puts "<dgray>If the menu doesn't display correctly, press '!'</dgray>"
162
+ else
163
+ puts "Override selection with --languages."
164
+ end
165
+ puts
166
+
167
+ if interactive?
168
+ begin
169
+ menu.query
170
+ rescue Interrupt
171
+ raise Abort
172
+ end
173
+ else
174
+ menu.display_choices
175
+ puts
176
+ end
177
+
178
+ @languages = menu.selected_choices.map{ |x| x.downcase.gsub(/\./, '') }
179
+ end
180
+
181
+ def interesting_language?(name, command = nil)
182
+ if @languages
183
+ return @languages.include?(name)
184
+ else
185
+ return !!PlatformInfo.find_command(command || name)
186
+ end
187
+ end
188
+
189
+ def check_whether_there_are_multiple_apache_installs
190
+ new_screen
191
+ puts '<banner>Sanity checking Apache installation...</banner>'
192
+
193
+ output = StringIO.new
194
+ detector = PlatformInfo::ApacheDetector.new(output)
195
+ begin
196
+ detector.detect_all
197
+ detector.report
198
+ @apache2 = detector.result_for(PlatformInfo.apxs2)
199
+ if @apache2.nil?
200
+ render_template 'apache2/apache_install_broken',
201
+ :apxs2 => PlatformInfo.apxs2,
202
+ :sudo_s_e => PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E"),
203
+ :ruby => PhusionPassenger::PlatformInfo.ruby_command,
204
+ :passenger_config => "#{PhusionPassenger.bin_dir}/passenger-config"
205
+ return false
206
+ end
207
+ if detector.results.size > 1
208
+ other_installs = detector.results - [@apache2]
209
+ render_template 'apache2/multiple_apache_installations_detected',
210
+ :current => @apache2,
211
+ :other_installs => other_installs
212
+ puts
213
+ if interactive?
214
+ result = prompt_confirmation "Are you sure you want to install " +
215
+ "against Apache #{@apache2.version} (#{@apache2.apxs2})?"
216
+ if !result
217
+ puts
218
+ line
219
+ render_template 'apache2/installing_against_a_different_apache',
220
+ :other_installs => other_installs
221
+ end
222
+ return result
223
+ else
224
+ puts '<yellow>Continuing installation because --auto is given.</yellow>'
225
+ return true
226
+ end
227
+ else
228
+ puts '<green>All good!</green>'
229
+ return true
230
+ end
231
+ ensure
232
+ detector.finish
233
+ end
234
+ end
235
+
236
+ def check_whether_apache_uses_compatible_mpm
237
+ # 'httpd -V' output is in the form of:
238
+ #
239
+ # Server MPM: Prefork # <--- this line is not always available!
240
+ # ...
241
+ # Server compiled with....
242
+ # -D APACHE_MPM_DIR="server/mpm/prefork"
243
+ output = PlatformInfo.httpd_V
244
+ output =~ /^Server MPM: +(.*)$/
245
+ if $1
246
+ mpm = $1.downcase
247
+ else
248
+ output =~ /APACHE_MPM_DIR="server\/mpm\/(.*)"/
249
+ if $1
250
+ mpm = $1.downcase
251
+ else
252
+ mpm = nil
253
+ end
254
+ end
255
+ if mpm != "prefork" && mpm != "worker" && mpm != "event"
256
+ new_screen
257
+ render_template 'apache2/apache_must_be_compiled_with_compatible_mpm',
258
+ :current_mpm => mpm
259
+ wait
260
+ end
261
+ end
262
+
263
+ def check_write_permission_to_passenger_root
264
+ File.new("__test__.txt", "w").close
265
+ return true
266
+ rescue SystemCallError
267
+ puts
268
+ line
269
+ if Process.uid == 0
270
+ render_template 'installer_common/cannot_access_files_as_root',
271
+ :type => "directory",
272
+ :files => [PhusionPassenger.build_system_dir]
273
+ else
274
+ render_template 'installer_common/run_installer_as_root',
275
+ :dir => PhusionPassenger.build_system_dir,
276
+ :sudo => PhusionPassenger::PlatformInfo.ruby_sudo_command,
277
+ :sudo_s_e => PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E"),
278
+ :ruby => PhusionPassenger::PlatformInfo.ruby_command,
279
+ :installer => "#{PhusionPassenger.bin_dir}/passenger-install-apache2-module #{ORIG_ARGV.join(' ')}"
280
+ end
281
+ return false
282
+ ensure
283
+ File.unlink("__test__.txt") rescue nil
284
+ end
285
+
286
+ def check_write_permission_to_web_server_config_files
287
+ return true if !@update_config
288
+ config_file = PlatformInfo.httpd_default_config_file
289
+ return if !config_file || !File.exist?(config_file)
290
+
291
+ all_config_files = PlatformInfo.httpd_included_config_files(config_file)
292
+ if all_config_files[:unreadable_files].any?
293
+ puts
294
+ line
295
+ if Process.uid == 0
296
+ render_template 'installer_common/cannot_access_files_as_root',
297
+ :access => "read from",
298
+ :files => all_config_files[:unreadable_files]
299
+ else
300
+ render_template 'installer_common/run_installer_as_root',
301
+ :access => "read from",
302
+ :desc => "an Apache configuration file",
303
+ :sudo => PhusionPassenger::PlatformInfo.ruby_sudo_command,
304
+ :sudo_s_e => PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E"),
305
+ :ruby => PhusionPassenger::PlatformInfo.ruby_command,
306
+ :installer => "#{PhusionPassenger.bin_dir}/passenger-install-apache2-module #{ORIG_ARGV.join(' ')}"
307
+ end
308
+ puts
309
+ render_template 'apache2/present_choice_for_no_update_config'
310
+ return false
311
+ end
312
+
313
+ unwriteable_files = []
314
+ all_config_files[:files].each do |filename|
315
+ if !File.writable_real?(filename)
316
+ unwriteable_files << filename
317
+ end
318
+ end
319
+ if unwriteable_files.empty?
320
+ return true
321
+ else
322
+ puts
323
+ line
324
+ if Process.uid == 0
325
+ render_template 'installer_common/cannot_access_files_as_root',
326
+ :files => unwriteable_files
327
+ else
328
+ render_template 'installer_common/run_installer_as_root',
329
+ :desc => "an Apache configuration file",
330
+ :sudo => PhusionPassenger::PlatformInfo.ruby_sudo_command,
331
+ :sudo_s_e => PhusionPassenger::PlatformInfo.ruby_sudo_shell_command("-E"),
332
+ :ruby => PhusionPassenger::PlatformInfo.ruby_command,
333
+ :installer => "#{PhusionPassenger.bin_dir}/passenger-install-apache2-module #{ORIG_ARGV.join(' ')}"
334
+ end
335
+ puts
336
+ render_template 'apache2/present_choice_for_no_update_config'
337
+ return false
338
+ end
339
+ end
340
+
341
+ def compile_apache2_module
342
+ puts
343
+ line
344
+ puts '<banner>Compiling and installing Apache 2 module...</banner>'
345
+ if @compile
346
+ puts "cd #{PhusionPassenger.build_system_dir}"
347
+ if ENV['TRACE']
348
+ rake = "#{PlatformInfo.rake_command} --trace RELEASE=yes"
349
+ else
350
+ rake = "#{PlatformInfo.rake_command} RELEASE=yes"
351
+ end
352
+ command = "env NOEXEC_DISABLE=1 #{rake} apache2:clean apache2"
353
+ if PhusionPassenger.packaging_method == "homebrew"
354
+ # Running apache2:clean deletes some object files needed
355
+ # by passenger-install-nginx-module, so we ensure those
356
+ # object files are compiled.
357
+ command << " nginx"
358
+ end
359
+ return sh(command)
360
+ else
361
+ puts "Skipping compilation"
362
+ return true
363
+ end
364
+ end
365
+
366
+ def load_snippet
367
+ return "LoadModule passenger_module #{PhusionPassenger.apache2_module_path}"
368
+ end
369
+
370
+ def config_snippet
371
+ return "<IfModule mod_passenger.c>\n" +
372
+ " PassengerRoot #{PhusionPassenger.install_spec}\n" +
373
+ " PassengerDefaultRuby #{PlatformInfo.ruby_command}\n" +
374
+ "</IfModule>"
375
+ end
376
+
377
+ def apache2_config_snippets
378
+ return "#{load_snippet}\n#{config_snippet}\n"
379
+ end
380
+
381
+ def backup_config_files(config_file, all_config_files)
382
+ now = Time.now.strftime("%Y-%m-%d-%H:%M:%S")
383
+ archive = "#{config_file}.#{GLOBAL_NAMESPACE_DIRNAME}-backup-#{now}.tar.gz"
384
+ backup_files = all_config_files.dup
385
+
386
+ # Some people create a regular file in /etc/apache2/mods-enabled, for convenience
387
+ # reasons. This file is not actually managed by a2enmod. We will remove such files
388
+ # because we're going to use mods-eanbled ourselves, so we need to back them up.
389
+ if (dir = PlatformInfo.httpd_mods_enabled_directory) && PlatformInfo.a2enmod
390
+ if File.file?("#{dir}/#{APACHE2_MODULE_CONF_NAME}.load")
391
+ backup_files << "#{dir}/#{APACHE2_MODULE_CONF_NAME}.load"
392
+ end
393
+ if File.file?("#{dir}/#{APACHE2_MODULE_CONF_NAME}.conf")
394
+ backup_files << "#{dir}/#{APACHE2_MODULE_CONF_NAME}.conf"
395
+ end
396
+ end
397
+
398
+ puts "Backing up existing configuration files to #{archive}..."
399
+ backup_files.uniq!
400
+ backup_files.map! { |x| x.sub(/^\//, '') }
401
+ Dir.chdir("/") do
402
+ sh! "tar", "-czf", archive, *backup_files
403
+ end
404
+ end
405
+
406
+ def uninstall_or_comment_out_existing_config_snippets(all_config_files)
407
+ files_containing_autoinstall_load_blocks = []
408
+ files_containing_autoinstall_conf_blocks = []
409
+
410
+ # Some people create a regular file in /etc/apache2/mods-enabled, for convenience
411
+ # reasons. This file is not actually managed by a2enmod. We remove such files
412
+ # because we're going to use mods-enabled ourselves. They've already been backed up.
413
+ if (dir = PlatformInfo.httpd_mods_enabled_directory) && PlatformInfo.a2enmod
414
+ filename = "#{dir}/#{APACHE2_MODULE_CONF_NAME}.load"
415
+ if File.file?(filename) && !File.symlink?(filename)
416
+ puts "Removing #{filename}"
417
+ File.unlink(filename)
418
+ end
419
+ filename = "#{dir}/#{APACHE2_MODULE_CONF_NAME}.conf"
420
+ if File.file?(filename) && !File.symlink?(filename)
421
+ puts "Removing #{filename}"
422
+ File.unlink(filename)
423
+ end
424
+ end
425
+
426
+ # Uncomment Phusion Passenger config snippets.
427
+ all_config_files.each do |filename|
428
+ next if !File.exist?(filename)
429
+
430
+ contents = File.open(filename, "rb") do |f|
431
+ f.read
432
+ end
433
+ if contents =~ /#{Regexp.escape AUTOINSTALL_BEGIN_LOAD_BLOCK}.*?#{Regexp.escape AUTOINSTALL_END_LOAD_BLOCK}/m
434
+ files_containing_autoinstall_load_blocks << filename
435
+ end
436
+ if contents =~ /#{Regexp.escape AUTOINSTALL_BEGIN_CONF_BLOCK}.*?#{Regexp.escape AUTOINSTALL_END_CONF_BLOCK}/m
437
+ files_containing_autoinstall_conf_blocks << filename
438
+ end
439
+ subst1 = contents.gsub!(/^([ \t]*LoadModule[ \t]+passenger_module[ \t]+.*)$/i, '# \1')
440
+ subst2 = contents.gsub!(/^([ \t]*PassengerRoot[ \t]+.*)$/i, '# \1')
441
+ subst3 = contents.gsub!(/^([ \t]*PassengerDefaultRuby[ \t]+.*)$/i, '# \1')
442
+ if subst1 || subst2 || subst3
443
+ puts "Uninstalling previous #{PROGRAM_NAME} from #{filename}..."
444
+ File.open(filename, "wb") do |f|
445
+ f.write(contents)
446
+ end
447
+ end
448
+ end
449
+
450
+ # If there are multiple auto-install comment blocks, remove the duplicates.
451
+ # First, we remove all comment blocks from all files besides the first one.
452
+ if files_containing_autoinstall_load_blocks.size > 1
453
+ files_containing_autoinstall_load_blocks[1..-1].each do |filename|
454
+ puts "Removing duplicate load snippets from #{filename}..."
455
+ remove_comment_blocks(filename,
456
+ AUTOINSTALL_BEGIN_LOAD_BLOCK,
457
+ AUTOINSTALL_END_LOAD_BLOCK)
458
+ end
459
+ end
460
+ if files_containing_autoinstall_conf_blocks.size > 1
461
+ files_containing_autoinstall_conf_blocks[1..-1].each do |filename|
462
+ puts "Removing duplicate conf snippets from #{filename}..."
463
+ remove_comment_blocks(filename,
464
+ AUTOINSTALL_BEGIN_CONF_BLOCK,
465
+ AUTOINSTALL_END_CONF_BLOCK)
466
+ end
467
+ end
468
+
469
+ # Then we are left with exactly 0 or exactly 1 file with comment blocks
470
+ # of each type. There may be duplicates inside that single file, so
471
+ # remove duplicates there too.
472
+ if files_containing_autoinstall_load_blocks.size > 0
473
+ filename = files_containing_autoinstall_load_blocks[0]
474
+ puts "Removing duplicate load snippets inside #{filename}..."
475
+ remove_duplicate_comment_blocks(filename,
476
+ AUTOINSTALL_BEGIN_LOAD_BLOCK,
477
+ AUTOINSTALL_END_LOAD_BLOCK)
478
+ end
479
+ if files_containing_autoinstall_conf_blocks.size > 0
480
+ filename = files_containing_autoinstall_conf_blocks[0]
481
+ puts "Removing duplicate configuration snippets inside #{filename}..."
482
+ remove_duplicate_comment_blocks(filename,
483
+ AUTOINSTALL_BEGIN_CONF_BLOCK,
484
+ AUTOINSTALL_END_CONF_BLOCK)
485
+ end
486
+
487
+ # One or more files may have been removed, so filter out the ones
488
+ # that are left.
489
+ all_config_files.reject! do |filename|
490
+ !File.exist?(filename)
491
+ end
492
+ end
493
+
494
+ def remove_comment_blocks(filename, begin_marker, end_marker)
495
+ contents = File.open(filename, "rb") do |f|
496
+ f.read
497
+ end
498
+ regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}\n?/m
499
+ contents.gsub!(regexp, '')
500
+ File.open(filename, "wb") do |f|
501
+ f.write(contents)
502
+ end
503
+ end
504
+
505
+ def remove_duplicate_comment_blocks(filename, begin_marker, end_marker)
506
+ contents = File.open(filename, "rb") do |f|
507
+ f.read
508
+ end
509
+ regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}\n?/m
510
+ if m = regexp.match(contents)
511
+ offset = m.end(0)
512
+ rest = contents.slice!(m.end(0) .. -1)
513
+ rest.gsub!(regexp, '')
514
+ contents << rest
515
+ File.open(filename, "wb") do |f|
516
+ f.write(contents)
517
+ end
518
+ end
519
+ end
520
+
521
+ def add_new_config_snippets(all_config_files)
522
+ # Look for the file containing the auto-install load and conf comment blocks.
523
+ # The uninstall_or_comment_out_existing_config_snippets method has already
524
+ # guaranteed that there is at most 1 file per comment block type, and that
525
+ # inside each file there are no duplicate comment blocks.
526
+ load_block_file = find_config_file_containing_comment_block(all_config_files,
527
+ AUTOINSTALL_BEGIN_LOAD_BLOCK,
528
+ AUTOINSTALL_END_LOAD_BLOCK)
529
+ conf_block_file = find_config_file_containing_comment_block(all_config_files,
530
+ AUTOINSTALL_BEGIN_CONF_BLOCK,
531
+ AUTOINSTALL_END_CONF_BLOCK)
532
+ if load_block_file && conf_block_file
533
+ puts "Updating #{PROGRAM_NAME} module load snippet inside #{load_block_file}..."
534
+ update_comment_block(load_block_file,
535
+ AUTOINSTALL_BEGIN_LOAD_BLOCK,
536
+ AUTOINSTALL_END_LOAD_BLOCK,
537
+ load_snippet)
538
+ puts "Updating #{PROGRAM_NAME} configuration snippet inside #{conf_block_file}..."
539
+ update_comment_block(conf_block_file,
540
+ AUTOINSTALL_BEGIN_CONF_BLOCK,
541
+ AUTOINSTALL_END_CONF_BLOCK,
542
+ config_snippet)
543
+ elsif !load_block_file && !conf_block_file
544
+ create_load_snippet_file(:maybe_in_mods_available)
545
+ create_conf_snippet_file(:maybe_in_mods_available)
546
+ if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
547
+ sh! "#{PlatformInfo.a2enmod} #{APACHE2_MODULE_CONF_NAME}"
548
+ end
549
+ # It looks like either the load or conf file isn't available.
550
+ # If the file that is available is inside mods-available, then it
551
+ # means that the mods-available files are broken.
552
+ elsif is_file_inside_mods_available?(load_block_file, "#{APACHE2_MODULE_CONF_NAME}.load") ||
553
+ is_file_inside_mods_available?(conf_block_file, "#{APACHE2_MODULE_CONF_NAME}.conf")
554
+ # We fix it if a2enmod is available. Otherwise, we remove the block.
555
+ if PlatformInfo.a2enmod
556
+ if !load_block_file
557
+ create_load_snippet_file(:must_be_in_mods_available)
558
+ else
559
+ create_conf_snippet_file(:must_be_in_mods_available)
560
+ end
561
+ else
562
+ if load_block_file
563
+ puts "Removing load snippets from #{filename}..."
564
+ remove_comment_blocks(load_block_file,
565
+ AUTOINSTALL_BEGIN_LOAD_BLOCK,
566
+ AUTOINSTALL_END_LOAD_BLOCK)
567
+ else
568
+ puts "Removing configuration snippets from #{filename}..."
569
+ remove_comment_blocks(conf_block_file,
570
+ AUTOINSTALL_BEGIN_CONF_BLOCK,
571
+ AUTOINSTALL_END_CONF_BLOCK)
572
+ end
573
+ create_load_snippet_file(:must_be_in_mods_available)
574
+ create_conf_snippet_file(:must_be_in_mods_available)
575
+ end
576
+ sh! "#{PlatformInfo.a2enmod} passenger"
577
+ else
578
+ if !load_block_file
579
+ create_load_snippet_file(:not_in_mods_available)
580
+ puts "Updating #{PROGRAM_NAME} configuration snippet inside #{conf_block_file}..."
581
+ update_comment_block(conf_block_file,
582
+ AUTOINSTALL_BEGIN_CONF_BLOCK,
583
+ AUTOINSTALL_END_CONF_BLOCK,
584
+ config_snippet)
585
+ else
586
+ create_conf_snippet_file(:not_in_mods_available)
587
+ puts "Updating #{PROGRAM_NAME} module load snippet inside #{load_block_file}..."
588
+ update_comment_block(load_block_file,
589
+ AUTOINSTALL_BEGIN_LOAD_BLOCK,
590
+ AUTOINSTALL_END_LOAD_BLOCK,
591
+ load_snippet)
592
+ end
593
+ end
594
+ end
595
+
596
+ def find_config_file_containing_comment_block(all_config_files, begin_marker, end_marker)
597
+ regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}/m
598
+ all_config_files.each do |filename|
599
+ contents = File.open(filename, "rb") do |f|
600
+ f.read
601
+ end
602
+ if contents =~ regexp
603
+ return filename
604
+ end
605
+ end
606
+ return nil
607
+ end
608
+
609
+ def update_comment_block(filename, begin_marker, end_marker, block_contents)
610
+ regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}\n?/m
611
+ contents = File.open(filename, "rb") do |f|
612
+ f.read
613
+ end
614
+ if contents.sub!(regexp, "#{begin_marker}\n#{block_contents}\n#{end_marker}\n")
615
+ File.open(filename, "wb") do |f|
616
+ f.write(contents)
617
+ end
618
+ return true
619
+ else
620
+ return false
621
+ end
622
+ end
623
+
624
+ def remove_comment_blocks(filename, begin_marker, end_marker)
625
+ regexp = /#{Regexp.escape begin_marker}.*?#{Regexp.escape end_marker}\n?/m
626
+ contents = File.open(filename, "rb") do |f|
627
+ f.read
628
+ end
629
+ contents.gsub!(regexp, "")
630
+ File.open(filename, "wb") do |f|
631
+ f.write(contents)
632
+ end
633
+ end
634
+
635
+ def is_file_inside_mods_available?(filename, basename)
636
+ if dir = PlatformInfo.httpd_mods_available_directory
637
+ return filename == "#{dir}/#{basename}"
638
+ else
639
+ return false
640
+ end
641
+ end
642
+
643
+ def create_load_snippet_file(where)
644
+ case where
645
+ when :maybe_in_mods_available
646
+ if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
647
+ filename = "#{PlatformInfo.httpd_mods_available_directory}/#{APACHE2_MODULE_CONF_NAME}.load"
648
+ else
649
+ filename = PlatformInfo.httpd_default_config_file
650
+ end
651
+ when :must_be_in_mods_available
652
+ if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
653
+ filename = "#{PlatformInfo.httpd_mods_available_directory}/#{APACHE2_MODULE_CONF_NAME}.load"
654
+ else
655
+ raise "Apache does not support the mods-available directory"
656
+ end
657
+ when :not_in_mods_available
658
+ filename = PlatformInfo.httpd_default_config_file
659
+ else
660
+ raise ArgumentError
661
+ end
662
+
663
+ if File.exist?(filename)
664
+ # If this is a file inside mods-available, and the file didn't have a symlink
665
+ # in mods-enabled, then the uninstall phase did not remove duplicates from this
666
+ # file. So here we remove duplicates again.
667
+ puts "Removing duplicate load snippets inside #{filename}..."
668
+ remove_duplicate_comment_blocks(filename,
669
+ AUTOINSTALL_BEGIN_LOAD_BLOCK,
670
+ AUTOINSTALL_END_LOAD_BLOCK)
671
+
672
+ puts "Installing #{PROGRAM_NAME} module load snippet to #{filename}..."
673
+ should_add = !update_comment_block(filename,
674
+ AUTOINSTALL_BEGIN_LOAD_BLOCK,
675
+ AUTOINSTALL_END_LOAD_BLOCK,
676
+ load_snippet)
677
+ else
678
+ puts "Installing #{PROGRAM_NAME} module load snippet to #{filename}..."
679
+ should_add = true
680
+ end
681
+ if should_add
682
+ File.open(filename, "ab") do |f|
683
+ f.write("\n#{AUTOINSTALL_BEGIN_LOAD_BLOCK}\n" +
684
+ "#{load_snippet}\n" +
685
+ "#{AUTOINSTALL_END_LOAD_BLOCK}\n")
686
+ end
687
+ end
688
+ end
689
+
690
+ def create_conf_snippet_file(where)
691
+ case where
692
+ when :maybe_in_mods_available
693
+ if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
694
+ filename = "#{PlatformInfo.httpd_mods_available_directory}/#{APACHE2_MODULE_CONF_NAME}.conf"
695
+ else
696
+ filename = PlatformInfo.httpd_default_config_file
697
+ end
698
+ when :must_be_in_mods_available
699
+ if PlatformInfo.httpd_mods_available_directory && PlatformInfo.a2enmod
700
+ filename = "#{PlatformInfo.httpd_mods_available_directory}/#{APACHE2_MODULE_CONF_NAME}.conf"
701
+ else
702
+ raise "Apache does not support the mods-available directory"
703
+ end
704
+ when :not_in_mods_available
705
+ filename = PlatformInfo.httpd_default_config_file
706
+ else
707
+ raise ArgumentError
708
+ end
709
+
710
+ if File.exist?(filename)
711
+ # If this is a file inside mods-available, and the file didn't have a symlink
712
+ # in mods-enabled, then the uninstall phase did not remove duplicates from this
713
+ # file. So here we remove duplicates again.
714
+ puts "Removing duplicate configuration snippets inside #{filename}..."
715
+ remove_duplicate_comment_blocks(filename,
716
+ AUTOINSTALL_BEGIN_CONF_BLOCK,
717
+ AUTOINSTALL_END_CONF_BLOCK)
718
+
719
+ puts "Installing #{PROGRAM_NAME} module configuration snippet to #{filename}..."
720
+ should_add = !update_comment_block(filename,
721
+ AUTOINSTALL_BEGIN_CONF_BLOCK,
722
+ AUTOINSTALL_END_CONF_BLOCK,
723
+ config_snippet)
724
+ else
725
+ puts "Installing #{PROGRAM_NAME} module configuration snippet to #{filename}..."
726
+ should_add = true
727
+ end
728
+ if should_add
729
+ File.open(filename, "ab") do |f|
730
+ f.write("\n#{AUTOINSTALL_BEGIN_CONF_BLOCK}\n" +
731
+ "#{config_snippet}\n" +
732
+ "#{AUTOINSTALL_END_CONF_BLOCK}\n")
733
+ end
734
+ end
735
+ end
736
+
737
+ def install_apache2_config_snippets
738
+ if !@update_config
739
+ show_apache2_config_snippets
740
+ return true
741
+ end
742
+
743
+ config_file = PlatformInfo.httpd_default_config_file
744
+ if config_file && File.exist?(config_file)
745
+ puts
746
+ line
747
+ puts "<banner>Updating Apache configuration files...</banner>"
748
+ config_file = PlatformInfo.httpd_default_config_file
749
+ all_config_files = PlatformInfo.httpd_included_config_files(config_file)[:files]
750
+ backup_config_files(config_file, all_config_files) if @backup_config
751
+ uninstall_or_comment_out_existing_config_snippets(all_config_files)
752
+ add_new_config_snippets(all_config_files)
753
+ return true
754
+ else
755
+ show_apache2_config_snippets
756
+ return true
757
+ end
758
+ end
759
+
760
+ def show_apache2_config_snippets
761
+ puts
762
+ line
763
+ render_template 'apache2/config_snippets',
764
+ :snippet => apache2_config_snippets
765
+ wait
766
+ end
767
+
768
+ def show_deployment_example
769
+ new_screen
770
+ render_template 'apache2/deployment_example',
771
+ :users_guide_path => users_guide_path,
772
+ :users_guide_url => users_guide_url,
773
+ :phusion_website => PHUSION_WEBSITE,
774
+ :passenger_website => PASSENGER_WEBSITE,
775
+ :languages => @languages
776
+ end
777
+
778
+ def show_possible_solutions_for_compilation_and_installation_problems
779
+ new_screen
780
+ render_template 'apache2/possible_solutions_for_compilation_and_installation_problems',
781
+ :users_guide_path => users_guide_path,
782
+ :users_guide_url => users_guide_url,
783
+ :support_url => SUPPORT_URL
784
+ end
785
+
786
+ def apache_module_available?
787
+ return File.exist?(PhusionPassenger.apache2_module_path)
788
+ end
789
+
790
+ def install_apache_module_from_native_package
791
+ case PhusionPassenger.packaging_method
792
+ when 'deb'
793
+ sh! "sudo apt-get update"
794
+ sh! "sudo apt-get install #{DEB_APACHE_MODULE_PACKAGE}"
795
+ return true
796
+ when 'rpm'
797
+ sh! "sudo yum install #{RPM_APACHE_MODULE_PACKAGE}-#{VERSION_STRING}"
798
+ return true
799
+ else
800
+ puts "<red>The #{PROGRAM_NAME} Apache module package is not installed.</red>"
801
+ puts "Please ask your packager or operating system vendor how to install it."
802
+ return false
803
+ end
804
+ end
805
+
806
+ def notify_apache_module_installed
807
+ render_template 'apache2/notify_apache_module_installed'
808
+ wait
809
+ end
810
810
  end
811
811
 
812
812
  ORIG_ARGV = ARGV.dup
813
813
  options = { :compile => true, :update_config => false, :backup_config => true }
814
814
  parser = OptionParser.new do |opts|
815
- opts.banner = "Usage: passenger-install-apache2-module [options]"
816
- opts.separator ""
817
-
818
- indent = ' ' * 37
819
- opts.separator "Options:"
820
- opts.on("-a", "--auto", String, "Automatically build the Apache module,\n" <<
821
- "#{indent}without interactively asking for user\n" <<
822
- "#{indent}input.") do
823
- options[:auto] = true
824
- end
825
- opts.on("--apxs2-path PATH", String, "Path to 'apxs2' command.") do |value|
826
- ENV['APXS2'] = value
827
- end
828
- opts.on("--apr-config-path PATH", String, "Path to 'apr-config' command.") do |value|
829
- ENV['APR_CONFIG'] = value
830
- end
831
- opts.on("--languages NAMES", "Comma-separated list of interested\n" <<
832
- "#{indent}languages (e.g.\n" <<
833
- "#{indent}'ruby,python,nodejs,meteor')") do |value|
834
- options[:languages] = value.split(",")
835
- end
836
- opts.on("--no-compile", "Skip compilation.") do
837
- options[:compile] = false
838
- end
839
- #opts.on("--no-update-config", "Do not automatically update Apache config\n" <<
840
- # "#{indent}files.") do
841
- # options[:update_config] = false
842
- #end
843
- #opts.on("--no-backup-config", "When updating Apache config files, do not\n" <<
844
- # "#{indent}create backups of the existing files.") do
845
- # options[:backup_config] = false
846
- #end
847
- opts.on("--force-colors", "Display colors even if stdout is not a TTY") do
848
- options[:colorize] = true
849
- end
850
- opts.on("--snippet", "Show just the Apache config snippet.") do
851
- options[:snippet] = true
852
- end
815
+ opts.banner = "Usage: passenger-install-apache2-module [options]"
816
+ opts.separator ""
817
+
818
+ indent = ' ' * 37
819
+ opts.separator "Options:"
820
+ opts.on("-a", "--auto", String, "Automatically build the Apache module,\n" <<
821
+ "#{indent}without interactively asking for user\n" <<
822
+ "#{indent}input.") do
823
+ options[:auto] = true
824
+ end
825
+ opts.on("--apxs2-path PATH", String, "Path to 'apxs2' command.") do |value|
826
+ ENV['APXS2'] = value
827
+ end
828
+ opts.on("--apr-config-path PATH", String, "Path to 'apr-config' command.") do |value|
829
+ ENV['APR_CONFIG'] = value
830
+ end
831
+ opts.on("--languages NAMES", "Comma-separated list of interested\n" <<
832
+ "#{indent}languages (e.g.\n" <<
833
+ "#{indent}'ruby,python,nodejs,meteor')") do |value|
834
+ options[:languages] = value.split(",")
835
+ end
836
+ opts.on("--no-compile", "Skip compilation.") do
837
+ options[:compile] = false
838
+ end
839
+ #opts.on("--no-update-config", "Do not automatically update Apache config\n" <<
840
+ # "#{indent}files.") do
841
+ # options[:update_config] = false
842
+ #end
843
+ #opts.on("--no-backup-config", "When updating Apache config files, do not\n" <<
844
+ # "#{indent}create backups of the existing files.") do
845
+ # options[:backup_config] = false
846
+ #end
847
+ opts.on("--force-colors", "Display colors even if stdout is not a TTY") do
848
+ options[:colorize] = true
849
+ end
850
+ opts.on("--snippet", "Show just the Apache config snippet.") do
851
+ options[:snippet] = true
852
+ end
853
853
  end
854
854
  begin
855
- parser.parse!
855
+ parser.parse!
856
856
  rescue OptionParser::ParseError => e
857
- puts e
858
- puts
859
- puts "Please see '--help' for valid options."
860
- exit 1
857
+ puts e
858
+ puts
859
+ puts "Please see '--help' for valid options."
860
+ exit 1
861
861
  end
862
862
 
863
863
  installer = Installer.new(options)
864
864
  if options[:snippet]
865
- puts installer.send(:apache2_config_snippets)
865
+ puts installer.send(:apache2_config_snippets)
866
866
  else
867
- installer.run
867
+ installer.run
868
868
  end