passenger 4.0.33 → 4.0.34

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 (112) hide show
  1. checksums.yaml +15 -0
  2. checksums.yaml.gz.asc +12 -0
  3. data.tar.gz.asc +7 -7
  4. data/NEWS +60 -0
  5. data/bin/passenger-config +1 -1
  6. data/bin/passenger-install-apache2-module +510 -40
  7. data/bin/passenger-install-nginx-module +26 -2
  8. data/build/cxx_tests.rb +1 -1
  9. data/build/documentation.rb +19 -21
  10. data/build/integration_tests.rb +39 -12
  11. data/build/misc.rb +18 -0
  12. data/build/packaging.rb +116 -56
  13. data/build/rpm.rb +20 -11
  14. data/build/ruby_tests.rb +2 -3
  15. data/build/test_basics.rb +9 -0
  16. data/debian.template/passenger.conf +2 -0
  17. data/debian.template/passenger.load +2 -0
  18. data/dev/run_travis.sh +3 -5
  19. data/dev/test_rpm_packaging.sh +28 -0
  20. data/doc/Users guide Apache.idmap.txt +6 -4
  21. data/doc/users_guide_snippets/installation.txt +20 -2
  22. data/doc/users_guide_snippets/tips.txt +1 -1
  23. data/ext/common/ApplicationPool2/Pool.h +1 -1
  24. data/ext/common/Constants.h +5 -1
  25. data/ext/common/agents/HelperAgent/RequestHandler.h +1 -1
  26. data/ext/common/agents/Watchdog/AgentWatcher.cpp +20 -0
  27. data/ext/common/agents/Watchdog/Main.cpp +10 -0
  28. data/ext/ruby/passenger_native_support.c +23 -11
  29. data/helper-scripts/classic-rails-loader.rb +9 -3
  30. data/helper-scripts/classic-rails-preloader.rb +10 -4
  31. data/helper-scripts/download_binaries/extconf.rb +46 -22
  32. data/helper-scripts/meteor-loader.rb +0 -1
  33. data/helper-scripts/node-loader.js +2 -1
  34. data/helper-scripts/prespawn +7 -1
  35. data/helper-scripts/rack-loader.rb +32 -3
  36. data/helper-scripts/rack-preloader.rb +10 -4
  37. data/lib/phusion_passenger.rb +40 -21
  38. data/lib/phusion_passenger/abstract_installer.rb +7 -4
  39. data/lib/phusion_passenger/analytics_logger.rb +4 -3
  40. data/lib/phusion_passenger/config/about_command.rb +27 -6
  41. data/lib/phusion_passenger/{config.rb → config/main.rb} +3 -2
  42. data/lib/phusion_passenger/config/restart_app_command.rb +1 -1
  43. data/lib/phusion_passenger/config/validate_install_command.rb +231 -0
  44. data/lib/phusion_passenger/constants.rb +2 -0
  45. data/lib/phusion_passenger/loader_shared_helpers.rb +92 -19
  46. data/lib/phusion_passenger/native_support.rb +33 -11
  47. data/lib/phusion_passenger/packaging.rb +1 -0
  48. data/lib/phusion_passenger/platform_info.rb +5 -2
  49. data/lib/phusion_passenger/platform_info/apache.rb +229 -60
  50. data/lib/phusion_passenger/platform_info/apache_detector.rb +26 -31
  51. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +4 -4
  52. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  53. data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +1 -1
  54. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +1 -1
  55. data/lib/phusion_passenger/platform_info/linux.rb +2 -1
  56. data/lib/phusion_passenger/platform_info/ruby.rb +7 -0
  57. data/lib/phusion_passenger/preloader_shared_helpers.rb +2 -1
  58. data/lib/phusion_passenger/request_handler.rb +2 -1
  59. data/lib/phusion_passenger/request_handler/thread_handler.rb +2 -1
  60. data/lib/phusion_passenger/standalone/runtime_installer.rb +35 -13
  61. data/lib/phusion_passenger/standalone/start_command.rb +2 -2
  62. data/lib/phusion_passenger/utils.rb +1 -23
  63. data/lib/phusion_passenger/utils/ansi_colors.rb +7 -1
  64. data/lib/phusion_passenger/utils/download.rb +36 -2
  65. data/lib/phusion_passenger/utils/native_support_utils.rb +65 -0
  66. data/resources/templates/apache2/apache_install_broken.txt.erb +20 -0
  67. data/resources/templates/apache2/config_snippets.txt.erb +2 -4
  68. data/resources/templates/apache2/present_choice_for_no_update_config.txt.erb +5 -0
  69. data/resources/templates/installer_common/cannot_access_files_as_root.txt.erb +15 -0
  70. data/resources/templates/installer_common/run_installer_as_root.txt.erb +6 -3
  71. data/resources/templates/nginx/nginx_module_sources_not_available.txt.erb +1 -1
  72. data/resources/templates/nginx/other_nginx_installations_exist.txt.erb +17 -0
  73. data/rpm/apache-passenger.conf.in +26 -0
  74. data/rpm/config.json +30 -0
  75. data/rpm/passenger.logrotate +7 -0
  76. data/rpm/passenger.spec.template +456 -0
  77. data/rpm/passenger_dynamic_thread_group.patch +16 -0
  78. data/rpm/passenger_tests_default_config_example.patch +44 -0
  79. data/rpm/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +21 -0
  80. data/rpm/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +45 -0
  81. data/test/config.json.rpm-automation +15 -0
  82. data/test/integration_tests/downloaded_binaries_tests.rb +80 -2
  83. data/test/integration_tests/native_packaging_spec.rb +136 -44
  84. data/test/integration_tests/standalone_tests.rb +2 -11
  85. data/test/ruby/analytics_logger_spec.rb +65 -19
  86. data/test/ruby/utils_spec.rb +2 -0
  87. metadata +532 -548
  88. metadata.gz.asc +7 -7
  89. data/resources/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -9
  90. data/rpm/README.rdoc +0 -117
  91. data/rpm/config/apache-passenger.conf.in +0 -19
  92. data/rpm/config/nginx-passenger.conf.in +0 -10
  93. data/rpm/config/rubygem-passenger.te +0 -10
  94. data/rpm/doc/README.nginx-alternatives +0 -5
  95. data/rpm/doc/example_yum_repository_htaccess +0 -5
  96. data/rpm/doc/footer.shtml +0 -12
  97. data/rpm/doc/header.shtml +0 -156
  98. data/rpm/nginx-alternatives.spec +0 -97
  99. data/rpm/passenger-release.spec +0 -91
  100. data/rpm/passenger.spec +0 -667
  101. data/rpm/patches/passenger-force-native.patch +0 -63
  102. data/rpm/release/RPM-GPG-KEY-stealthymonkeys +0 -33
  103. data/rpm/release/build-release.sh +0 -35
  104. data/rpm/release/build.rb +0 -301
  105. data/rpm/release/create-mirrors.sh +0 -16
  106. data/rpm/release/mirrors +0 -1
  107. data/rpm/release/mock-repo/comps.xml +0 -21
  108. data/rpm/release/mock-repo/rubygem-daemon_controller-0.2.5-1.noarch.rpm +0 -0
  109. data/rpm/release/mock-repo/rubygem-file-tail-1.0.5-1.noarch.rpm +0 -0
  110. data/rpm/release/mock-repo/rubygem-spruz-0.2.2-1.noarch.rpm +0 -0
  111. data/rpm/release/mocksetup-first.sh +0 -102
  112. data/rpm/release/mocksetup.sh +0 -67
@@ -1,5 +1,5 @@
1
1
  # Phusion Passenger - https://www.phusionpassenger.com/
2
- # Copyright (c) 2010-2013 Phusion
2
+ # Copyright (c) 2010-2014 Phusion
3
3
  #
4
4
  # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
5
5
  #
@@ -37,7 +37,7 @@ class AboutCommand < Command
37
37
  puts "Show information about #{PROGRAM_NAME}."
38
38
  puts
39
39
  puts "Available subcommands:"
40
- puts " root Show #{PROGRAM_NAME}'s root directory."
40
+ puts " root Show #{PROGRAM_NAME}'s root."
41
41
  puts " ruby-libdir Show #{PROGRAM_NAME}'s Ruby library directory."
42
42
  puts " includedir Show the Nginx runtime library headers directory."
43
43
  puts " nginx-addon-dir Show #{PROGRAM_NAME}'s Nginx addon directory."
@@ -101,27 +101,48 @@ class AboutCommand < Command
101
101
  exit 1
102
102
  end
103
103
  when "--make-locations-ini"
104
+ if @argv[1] =~ /^--for-native-packaging-method=(.*)/
105
+ native_packaging_method = $1
106
+ else
107
+ native_packaging_method = nil
108
+ end
109
+
104
110
  puts "[locations]"
105
- puts "natively_packaged=#{PhusionPassenger.natively_packaged?}"
106
- if PhusionPassenger.natively_packaged?
107
- puts "native_packaging_method=#{PhusionPassenger.native_packaging_method}"
111
+ if native_packaging_method
112
+ puts "natively_packaged=true"
113
+ puts "native_packaging_method=#{native_packaging_method}"
114
+ else
115
+ puts "natively_packaged=#{PhusionPassenger.natively_packaged?}"
116
+ if PhusionPassenger.natively_packaged?
117
+ puts "native_packaging_method=#{PhusionPassenger.native_packaging_method}"
118
+ end
108
119
  end
109
120
  PhusionPassenger::REQUIRED_LOCATIONS_INI_FIELDS.each do |field|
110
121
  puts "#{field}=#{PhusionPassenger.send(field)}"
111
122
  end
112
123
  PhusionPassenger::OPTIONAL_LOCATIONS_INI_FIELDS.each do |field|
113
- if value = PhusionPassenger.send(field)
124
+ value = PhusionPassenger.send(field)
125
+ should_print = value &&
126
+ (!ORIGINALLY_PACKAGED_LOCATIONS_INI_FIELDS.include?(field) || (
127
+ PhusionPassenger.originally_packaged? &&
128
+ !native_packaging_method
129
+ ))
130
+ if should_print
114
131
  puts "#{field}=#{value}"
115
132
  end
116
133
  end
117
134
  when "--detect-apache2"
118
135
  PhusionPassenger.require_passenger_lib 'platform_info/apache_detector'
119
136
  detector = PhusionPassenger::PlatformInfo::ApacheDetector.new(STDOUT)
137
+ STDOUT.write(Utils::AnsiColors::DEFAULT_TERMINAL_COLOR)
138
+ STDOUT.flush
120
139
  begin
121
140
  detector.detect_all
122
141
  detector.report
123
142
  ensure
124
143
  detector.finish
144
+ STDOUT.write(Utils::AnsiColors::RESET)
145
+ STDOUT.flush
125
146
  end
126
147
  when "--ruby-command"
127
148
  PhusionPassenger.require_passenger_lib 'platform_info/ruby'
@@ -1,5 +1,5 @@
1
1
  # Phusion Passenger - https://www.phusionpassenger.com/
2
- # Copyright (c) 2013 Phusion
2
+ # Copyright (c) 2013-2014 Phusion
3
3
  #
4
4
  # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
5
5
  #
@@ -29,6 +29,7 @@ module PhusionPassenger
29
29
  module Config
30
30
  KNOWN_COMMANDS = [
31
31
  ["restart-app", "RestartAppCommand"],
32
+ ["validate-install", "ValidateInstallCommand"],
32
33
  ["about", "AboutCommand"]
33
34
  ]
34
35
 
@@ -69,7 +70,7 @@ module Config
69
70
  puts "Available commands:"
70
71
  KNOWN_COMMANDS.each do |props|
71
72
  command_class = lookup_command_class_by_class_name(props[1])
72
- printf " %-15s %s\n", props[0], command_class.description
73
+ printf " %-18s %s\n", props[0], command_class.description
73
74
  end
74
75
  puts
75
76
  puts "Type 'passenger-config <COMMAND> --help' for more information."
@@ -1,5 +1,5 @@
1
1
  # Phusion Passenger - https://www.phusionpassenger.com/
2
- # Copyright (c) 2010-2013 Phusion
2
+ # Copyright (c) 2013 Phusion
3
3
  #
4
4
  # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
5
5
  #
@@ -0,0 +1,231 @@
1
+ # encoding: utf-8
2
+ # Phusion Passenger - https://www.phusionpassenger.com/
3
+ # Copyright (c) 2014 Phusion
4
+ #
5
+ # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ PhusionPassenger.require_passenger_lib 'constants'
26
+ PhusionPassenger.require_passenger_lib 'config/command'
27
+
28
+ module PhusionPassenger
29
+ module Config
30
+
31
+ class ValidateInstallCommand < Command
32
+ # Signifies that there is at least 1 error.
33
+ FAIL_EXIT_CODE = 1
34
+ # Signifies that there are no error, but at least 1 warning.
35
+ WARN_EXIT_CODE = 2
36
+
37
+ def self.description
38
+ return "Validate this #{PROGRAM_NAME} installation"
39
+ end
40
+
41
+ def self.help
42
+ puts "Usage: passenger-config validate-install"
43
+ puts "Validate this #{PROGRAM_NAME} installation."
44
+ puts
45
+ puts "Exit codes:"
46
+ puts " 0 - All checks passed. No errors, no warnings."
47
+ puts " #{FAIL_EXIT_CODE} - There are some errors."
48
+ puts " #{WARN_EXIT_CODE} - There are no errors, but there are some warnings."
49
+ end
50
+
51
+ def run
52
+ if @argv[0] == '--help'
53
+ self.class.help
54
+ exit
55
+ elsif @argv.size > 0
56
+ self.class.help
57
+ exit 1
58
+ end
59
+
60
+ begin
61
+ require 'rubygems'
62
+ rescue LoadError
63
+ end
64
+ PhusionPassenger.require_passenger_lib 'utils/ansi_colors'
65
+ PhusionPassenger.require_passenger_lib 'platform_info'
66
+
67
+ @error_count = 0
68
+ @warning_count = 0
69
+
70
+ prepare_terminal
71
+ begin
72
+ check_tools_in_path
73
+ check_no_other_installs_in_path
74
+
75
+ exit(FAIL_EXIT_CODE) if @error_count > 0
76
+ exit(WARN_EXIT_CODE) if @warning_count > 0
77
+ ensure
78
+ reset_terminal
79
+ end
80
+ end
81
+
82
+ private
83
+ def prepare_terminal
84
+ STDOUT.write(Utils::AnsiColors::DEFAULT_TERMINAL_COLOR)
85
+ STDOUT.flush
86
+ end
87
+
88
+ def reset_terminal
89
+ STDOUT.write(Utils::AnsiColors::RESET)
90
+ STDOUT.flush
91
+ end
92
+
93
+ def check_tools_in_path
94
+ checking "whether this #{PROGRAM_NAME} install is in PATH"
95
+ paths = ENV['PATH'].to_s.split(':')
96
+ if paths.include?(gem_bindir) ||
97
+ paths.include?(homebrew_bindir) ||
98
+ paths.include?(PhusionPassenger.bin_dir)
99
+ check_ok
100
+ else
101
+ check_warning
102
+ suggest %Q{
103
+ Please add #{PhusionPassenger.bin_dir} to PATH.
104
+ Otherwise you will get "command not found" errors upon running
105
+ passenger-status and other tools.
106
+
107
+ Learn more at about PATH at:
108
+
109
+ #{NGINX_DOC_URL}#_the_path_environment_variable
110
+ }
111
+ end
112
+ end
113
+
114
+ def check_no_other_installs_in_path
115
+ logn " * Checking whether there are no other #{PROGRAM_NAME} installations... "
116
+
117
+ paths = ENV['PATH'].to_s.split(':')
118
+ if Process.uid == 0 &&
119
+ (sudo_user = ENV['SUDO_USER']) &&
120
+ (bash = PlatformInfo.find_command("bash")) &&
121
+ PlatformInfo.find_command("sudo")
122
+ # If we were invoked through sudo then we need to check the original user's PATH too.
123
+ output = `sudo -u #{sudo_user} #{bash} -lc 'echo; echo PATH FOLLOWS; echo "$PATH"' 2>&1`
124
+ output.sub!(/.*\nPATH FOLLOWS\n/m, '')
125
+ output.strip!
126
+ paths.concat(output.split(':'))
127
+ end
128
+
129
+ paths.delete(gem_bindir)
130
+ paths.delete(homebrew_bindir)
131
+ paths.delete(PhusionPassenger.bin_dir)
132
+ # These may not be in PATH if the user did not run this command through sudo.
133
+ paths << "/usr/bin"
134
+ paths << "/usr/sbin"
135
+ paths.uniq!
136
+
137
+ other_installs = []
138
+ paths.each do |path|
139
+ filename = "#{path}/passenger-config"
140
+ if File.exist?(filename)
141
+ other_installs << filename
142
+ end
143
+ end
144
+ if other_installs.empty?
145
+ check_ok
146
+ else
147
+ check_warning
148
+ suggest %Q{
149
+ Besides this #{PROGRAM_NAME} installation, the following other
150
+ #{PROGRAM_NAME} installations have been detected:
151
+
152
+ #{other_installs.join("\n\t\t\t\t ")}
153
+
154
+ Please uninstall them to avoid confusion or conflicts.
155
+ }
156
+ end
157
+ end
158
+
159
+ # Returns the RubyGems bin dir, if Phusion Passenger is installed through RubyGems.
160
+ def gem_bindir
161
+ if defined?(Gem) &&
162
+ PhusionPassenger.originally_packaged? &&
163
+ PhusionPassenger.source_root =~ /^#{Regexp.escape Gem.dir}\// &&
164
+ File.exist?("#{Gem.bindir}/passenger-config")
165
+ return Gem.bindir
166
+ else
167
+ return nil
168
+ end
169
+ end
170
+
171
+ # Returns the Homebrew bin dir, if Phusion Passenger is installed through Homebrew.
172
+ def homebrew_bindir
173
+ if PhusionPassenger.native_packaging_method == "homebrew"
174
+ return "/usr/local/bin"
175
+ else
176
+ return nil
177
+ end
178
+ end
179
+
180
+ def logn(message)
181
+ if STDOUT.tty?
182
+ STDOUT.write(Utils::AnsiColors.ansi_colorize(message))
183
+ else
184
+ STDOUT.write(Utils::AnsiColors.strip_color_tags(message))
185
+ end
186
+ STDOUT.flush
187
+ end
188
+
189
+ def log(message)
190
+ if STDOUT.tty?
191
+ STDOUT.puts(Utils::AnsiColors.ansi_colorize(message))
192
+ else
193
+ STDOUT.puts(Utils::AnsiColors.strip_color_tags(message))
194
+ end
195
+ end
196
+
197
+ def checking(message)
198
+ logn " * Checking #{message}... "
199
+ end
200
+
201
+ def check_ok(message = "✓")
202
+ log "<green>#{message}</green>"
203
+ end
204
+
205
+ def check_error(message = "✗")
206
+ log "<red>#{message}</red>"
207
+ @error_count += 1
208
+ end
209
+
210
+ def check_warning(message = "(!)")
211
+ log "<yellow>#{message}</yellow>"
212
+ @warning_count += 1
213
+ end
214
+
215
+ def suggest(message)
216
+ puts
217
+ log reindent(unindent(message), 3)
218
+ puts
219
+ end
220
+
221
+ def unindent(text)
222
+ return PlatformInfo.send(:unindent, text)
223
+ end
224
+
225
+ def reindent(text, level)
226
+ return PlatformInfo.send(:reindent, text, level)
227
+ end
228
+ end
229
+
230
+ end # module Config
231
+ end # module PhusionPassenger
@@ -73,9 +73,11 @@ module PhusionPassenger
73
73
  STANDALONE_DOC_URL = "http://www.modrails.com/documentation/Users%20guide%20Standalone.html"
74
74
  SUPPORT_URL = "http://www.phusionpassenger.com/support"
75
75
  ENTERPRISE_URL = "http://www.phusionpassenger.com/enterprise"
76
+ DEB_MAIN_PACKAGE = "passenger"
76
77
  DEB_DEV_PACKAGE = "passenger-dev"
77
78
  DEB_APACHE_MODULE_PACKAGE = "libapache2-mod-passenger"
78
79
  DEB_NGINX_PACKAGE = "nginx-extras"
80
+ RPM_MAIN_PACKAGE = "passenger"
79
81
  RPM_DEV_PACKAGE = "passenger-devel"
80
82
  RPM_APACHE_MODULE_PACKAGE = "mod_passenger"
81
83
  RPM_NGINX_PACKAGE = "nginx"
@@ -22,6 +22,7 @@
22
22
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
  # THE SOFTWARE.
24
24
 
25
+ PhusionPassenger.require_passenger_lib 'constants'
25
26
  PhusionPassenger.require_passenger_lib 'public_api'
26
27
  PhusionPassenger.require_passenger_lib 'debug_logging'
27
28
 
@@ -32,11 +33,29 @@ module LoaderSharedHelpers
32
33
  extend self
33
34
 
34
35
  # To be called by the (pre)loader as soon as possible.
35
- def init
36
+ def init(options)
36
37
  Thread.main[:name] = "Main thread"
37
38
  # We don't dump PATH info because at this point it's
38
39
  # unlikely to be changed.
39
40
  dump_ruby_environment
41
+ check_rvm_using_wrapper_script(options)
42
+ return sanitize_spawn_options(options)
43
+ 7 end
44
+
45
+ def check_rvm_using_wrapper_script(options)
46
+ ruby = options["ruby"]
47
+ if ruby =~ %r(/\.?rvm/) && ruby =~ %r(/bin/ruby$)
48
+ raise "You've set the `PassengerRuby` (Apache) or `passenger_ruby` (Nginx) option to '#{ruby}'. " +
49
+ "However, because you are using RVM, this is not allowed: the option must point to " +
50
+ "an RVM wrapper script, not a raw Ruby binary. This is because RVM is implemented " +
51
+ "through various environment variables, which are set through the wrapper script.\n" +
52
+ "\n" +
53
+ "To find out the correct value for `PassengerRuby`/`passenger_ruby`, please read:\n\n" +
54
+ " #{APACHE2_DOC_URL}#PassengerRuby\n\n" +
55
+ " #{NGINX_DOC_URL}#PassengerRuby\n\n" +
56
+ "Scroll to section 'RVM helper tool'.\n" +
57
+ "\n-------------------------\n"
58
+ end
40
59
  end
41
60
 
42
61
  # To be called whenever the (pre)loader is about to abort with an error.
@@ -201,7 +220,7 @@ module LoaderSharedHelpers
201
220
  # exists then there's a 99.9% chance that loading it is the correct
202
221
  # thing to do.
203
222
  elsif File.exist?('.bundle/environment.rb')
204
- running_bundler do
223
+ running_bundler(options) do
205
224
  require File.expand_path('.bundle/environment')
206
225
  end
207
226
 
@@ -221,7 +240,7 @@ module LoaderSharedHelpers
221
240
  # harmless. If this isn't the correct thing to do after all then
222
241
  # there's always the load_path_setup_file option and
223
242
  # setup_load_paths.rb.
224
- running_bundler do
243
+ running_bundler(options) do
225
244
  require 'rubygems'
226
245
  require 'bundler/setup'
227
246
  end
@@ -325,31 +344,70 @@ module LoaderSharedHelpers
325
344
  end
326
345
 
327
346
  private
328
- def running_bundler
347
+ def running_bundler(options)
329
348
  yield
330
349
  rescue Exception => e
331
350
  if (defined?(Bundler::GemNotFound) && e.is_a?(Bundler::GemNotFound)) ||
332
351
  (defined?(Bundler::GitError) && e.is_a?(Bundler::GitError))
333
- prepend_exception_comment(e, "It looks like Bundler could not find a gem. This " +
334
- "is probably because your\n" +
335
- "application is being run under a different environment than it's supposed to.\n" +
336
- "Please check the following:\n\n" +
337
- " * Is this app supposed to be run as the `#{whoami}` user?\n" +
338
- " * Is this app being run on the correct Ruby interpreter? Below you will\n" +
339
- " see which Ruby interpreter Phusion Passenger attempted to use.\n" +
340
- " * Are you using RVM? Please check whether the correct gemset is being used.\n" +
341
- " * If all of the above fails, try resetting your RVM gemsets:\n" +
342
- " https://github.com/phusion/passenger/wiki/Resetting-RVM-gemsets\n")
352
+ PhusionPassenger.require_passenger_lib 'platform_info/ruby'
353
+ comment =
354
+ "<p>It looks like Bundler could not find a gem. Maybe you didn't install all the " +
355
+ "gems that this application needs. To install your gems, please run:</p>\n\n" +
356
+ " <pre class=\"commands\">bundle install</pre>\n\n"
357
+ ruby = options["ruby"]
358
+ if ruby =~ %r(^/usr/local/rvm/)
359
+ comment <<
360
+ "<p>If that didn't work, then maybe the problem is that your gems are installed " +
361
+ "to <code>#{h home_dir}/.rvm/gems</code>, while at the same time you set " +
362
+ "<code>PassengerRuby</code> (Apache) or <code>passenger_ruby</code> (Nginx) to " +
363
+ "<code>#{h ruby}</code>. Because of the latter, RVM does not load gems from the " +
364
+ "home directory.</p>\n\n" +
365
+ "<p>To make RVM load gems from the home directory, you need to set " +
366
+ "<code>PassengerRuby</code>/<code>passenger_ruby</code> to an RVM wrapper script " +
367
+ "inside the home directory:</p>\n\n" +
368
+ "<ol>\n" +
369
+ " <li>Login as #{h whoami}.</li>\n"
370
+ if PlatformInfo.rvm_installation_mode == :multi
371
+ comment <<
372
+ " <li>Enable RVM mixed mode by running:\n" +
373
+ " <pre class=\"commands\">rvm user gemsets</pre></li>\n"
374
+ end
375
+ comment <<
376
+ " <li>Run this to find out what to set <code>PassengerRuby</code>/<code>passenger_ruby</code> to:\n" +
377
+ " <pre class=\"commands\">#{PlatformInfo.ruby_command} \\\n" +
378
+ "#{PhusionPassenger.bin_dir}/passenger-config --detect-ruby</pre></li>\n" +
379
+ "</ol>\n\n" +
380
+ "<p>If that didn't help either, then maybe your application is being run under a " +
381
+ "different environment than it's supposed to. Please check the following:</p>\n\n"
382
+ else
383
+ comment <<
384
+ "<p>If that didn't work, then the problem is probably caused by your " +
385
+ "application being run under a different environment than it's supposed to. " +
386
+ "Please check the following:</p>\n\n"
387
+ end
388
+ comment << "<ol>\n"
389
+ comment <<
390
+ " <li>Is this app supposed to be run as the <code>#{h whoami}</code> user?</li>\n" +
391
+ " <li>Is this app being run on the correct Ruby interpreter? Below you will\n" +
392
+ " see which Ruby interpreter Phusion Passenger attempted to use.</li>\n"
393
+ if PlatformInfo.in_rvm?
394
+ comment <<
395
+ " <li>Please check whether the correct RVM gemset is being used.</li>\n" +
396
+ " <li>Sometimes, RVM gemsets may be broken.\n" +
397
+ " <a href=\"https://github.com/phusion/passenger/wiki/Resetting-RVM-gemsets\">Try resetting them.</a></li>\n"
398
+ end
399
+ comment << "</ol>\n"
400
+ prepend_exception_html_comment(e, comment)
343
401
  end
344
402
  raise e
345
403
  end
346
404
 
347
- def prepend_exception_comment(e, comment)
405
+ def prepend_exception_html_comment(e, comment)
348
406
  # Since Exception doesn't allow changing the message, we monkeypatch
349
407
  # the #message and #to_s methods.
350
- separator = "\n-------- The exception is as follows: -------\n"
351
- new_message = comment + separator + e.message
352
- new_s = comment + separator + e.to_s
408
+ separator = "\n<p>-------- The exception is as follows: -------</p>\n"
409
+ new_message = comment + separator + h(e.message)
410
+ new_s = comment + separator + h(e.to_s)
353
411
  metaclass = class << e; self; end
354
412
  metaclass.send(:define_method, :message) do
355
413
  new_message
@@ -357,10 +415,18 @@ private
357
415
  metaclass.send(:define_method, :to_s) do
358
416
  new_s
359
417
  end
418
+ metaclass.send(:define_method, :html?) do
419
+ true
420
+ end
421
+ end
422
+
423
+ def h(text)
424
+ require 'erb' if !defined?(ERB)
425
+ return ERB::Util.h(text)
360
426
  end
361
427
 
362
428
  def whoami
363
- require 'etc'
429
+ require 'etc' if !defined?(Etc)
364
430
  begin
365
431
  user = Etc.getpwuid(Process.uid)
366
432
  rescue ArgumentError
@@ -372,6 +438,13 @@ private
372
438
  return "##{Process.uid}"
373
439
  end
374
440
  end
441
+
442
+ def home_dir
443
+ @home_dir ||= begin
444
+ require 'etc' if !defined?(Etc)
445
+ Etc.getpwuid(Process.uid).dir
446
+ end
447
+ end
375
448
  end
376
449
 
377
450
  end # module PhusionPassenger