passenger 4.0.10 → 4.0.13

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 (224) hide show
  1. data.tar.gz.asc +7 -7
  2. data/.gitignore +66 -0
  3. data/.travis.yml +2 -5
  4. data/CONTRIBUTORS +2 -1
  5. data/NEWS +24 -0
  6. data/README.md +5 -10
  7. data/bin/passenger +1 -0
  8. data/bin/passenger-config +29 -3
  9. data/bin/passenger-install-nginx-module +1 -1
  10. data/build/basics.rb +8 -2
  11. data/build/debian.rb +22 -0
  12. data/build/integration_tests.rb +16 -2
  13. data/build/misc.rb +3 -0
  14. data/build/packaging.rb +77 -29
  15. data/build/preprocessor.rb +13 -10
  16. data/build/test_basics.rb +6 -0
  17. data/debian.template/locations.ini.template +13 -0
  18. data/debian.template/ruby-passenger-dev.install.template +3 -0
  19. data/debian.template/ruby-passenger-doc.install.template +2 -0
  20. data/debian.template/ruby-passenger.install.template +12 -0
  21. data/debian.template/rules.template +1 -0
  22. data/dev/run_travis.sh +46 -14
  23. data/doc/Architectural overview.html +25 -34
  24. data/doc/Packaging.html +31 -23
  25. data/doc/Packaging.txt.md +32 -23
  26. data/doc/Security of user switching support.html +16 -18
  27. data/doc/Users guide Apache.html +231 -239
  28. data/doc/Users guide Nginx.html +219 -227
  29. data/doc/Users guide Standalone.html +12 -15
  30. data/doc/users_guide_snippets/installation.txt +3 -2
  31. data/ext/common/ApplicationPool2/Implementation.cpp +6 -16
  32. data/ext/common/Constants.h +1 -1
  33. data/ext/common/ResourceLocator.h +6 -6
  34. data/ext/common/UnionStation.h +11 -15
  35. data/ext/common/Utils/ProcessMetricsCollector.h +7 -4
  36. data/ext/common/agents/HelperAgent/AgentOptions.h +6 -0
  37. data/ext/common/agents/HelperAgent/Main.cpp +5 -0
  38. data/ext/common/agents/HelperAgent/RequestHandler.h +9 -1
  39. data/ext/common/agents/LoggingAgent/Main.cpp +4 -0
  40. data/ext/common/agents/Watchdog/Main.cpp +7 -0
  41. data/ext/nginx/config +1 -1
  42. data/ext/oxt/Readme.txt +15 -0
  43. data/helper-scripts/download_binaries/extconf.rb +83 -0
  44. data/lib/phusion_passenger.rb +78 -80
  45. data/lib/phusion_passenger/abstract_installer.rb +22 -8
  46. data/lib/phusion_passenger/console_text_template.rb +1 -1
  47. data/lib/phusion_passenger/loader_shared_helpers.rb +2 -1
  48. data/lib/phusion_passenger/native_support.rb +22 -9
  49. data/lib/phusion_passenger/packaging.rb +7 -2
  50. data/lib/phusion_passenger/platform_info.rb +28 -1
  51. data/lib/phusion_passenger/platform_info/apache.rb +246 -26
  52. data/lib/phusion_passenger/platform_info/apache_detector.rb +232 -0
  53. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +4 -0
  54. data/lib/phusion_passenger/platform_info/linux.rb +7 -0
  55. data/lib/phusion_passenger/public_api.rb +11 -2
  56. data/lib/phusion_passenger/standalone/command.rb +11 -14
  57. data/lib/phusion_passenger/standalone/runtime_installer.rb +313 -275
  58. data/lib/phusion_passenger/standalone/runtime_locator.rb +163 -0
  59. data/lib/phusion_passenger/standalone/start_command.rb +38 -46
  60. data/lib/phusion_passenger/utils/json.rb +329 -0
  61. data/lib/phusion_passenger/utils/tmpio.rb +1 -0
  62. data/passenger.gemspec +4 -0
  63. data/resources/mime.types +1 -0
  64. data/resources/oss-binaries.phusionpassenger.com.crt +84 -0
  65. data/resources/release.txt +0 -0
  66. data/resources/templates/standalone/download_tool_missing.txt.erb +18 -0
  67. data/rpm/README.rdoc +117 -0
  68. data/rpm/config/apache-passenger.conf.in +19 -0
  69. data/rpm/config/nginx-passenger.conf.in +10 -0
  70. data/rpm/config/rubygem-passenger.te +10 -0
  71. data/rpm/doc/README.nginx-alternatives +5 -0
  72. data/rpm/doc/example_yum_repository_htaccess +5 -0
  73. data/rpm/doc/footer.shtml +12 -0
  74. data/rpm/doc/header.shtml +156 -0
  75. data/rpm/nginx-alternatives.spec +97 -0
  76. data/rpm/passenger-release.spec +91 -0
  77. data/rpm/passenger.spec +667 -0
  78. data/rpm/patches/passenger-force-native.patch +63 -0
  79. data/rpm/release/RPM-GPG-KEY-stealthymonkeys +33 -0
  80. data/rpm/release/build-release.sh +35 -0
  81. data/rpm/release/build.rb +301 -0
  82. data/rpm/release/create-mirrors.sh +16 -0
  83. data/rpm/release/mirrors +1 -0
  84. data/rpm/release/mock-repo/comps.xml +21 -0
  85. data/rpm/release/mock-repo/rubygem-daemon_controller-0.2.5-1.noarch.rpm +0 -0
  86. data/rpm/release/mock-repo/rubygem-file-tail-1.0.5-1.noarch.rpm +0 -0
  87. data/rpm/release/mock-repo/rubygem-spruz-0.2.2-1.noarch.rpm +0 -0
  88. data/rpm/release/mocksetup-first.sh +102 -0
  89. data/rpm/release/mocksetup.sh +67 -0
  90. data/test/integration_tests/apache2_tests.rb +1 -1
  91. data/test/integration_tests/downloaded_binaries_tests.rb +76 -0
  92. data/test/integration_tests/native_packaging_spec.rb +38 -6
  93. data/test/integration_tests/source_packaging_test.rb +198 -0
  94. data/test/integration_tests/standalone_tests.rb +275 -0
  95. data/test/ruby/admin_tools_spec.rb +1 -1
  96. data/test/ruby/rails4.0/loader_spec.rb +28 -0
  97. data/test/ruby/rails4.0/preloader_spec.rb +34 -0
  98. data/test/ruby/spec_helper.rb +5 -1
  99. data/test/ruby/standalone/runtime_installer_spec.rb +399 -0
  100. data/test/ruby/standalone/runtime_locator_spec.rb +214 -0
  101. data/test/stub/apache2/httpd.conf.erb +18 -1
  102. data/test/stub/rack/tmp/.gitignore +0 -0
  103. data/test/stub/rails2.3/log/.gitignore +1 -0
  104. data/test/stub/rails2.3/public/.gitignore +1 -0
  105. data/test/stub/rails2.3/tmp/cache/.gitignore +1 -0
  106. data/test/stub/rails2.3/tmp/pids/.gitignore +1 -0
  107. data/test/stub/rails2.3/tmp/sessions/.gitignore +1 -0
  108. data/test/stub/rails2.3/tmp/sockets/.gitignore +1 -0
  109. data/test/stub/rails3.0/.gitignore +4 -0
  110. data/test/stub/rails3.0/Gemfile +1 -1
  111. data/test/stub/rails3.0/Gemfile.lock +1 -1
  112. data/test/stub/rails3.0/lib/tasks/.gitkeep +0 -0
  113. data/test/stub/rails3.0/log/.gitignore +0 -0
  114. data/test/stub/rails3.0/public/stylesheets/.gitkeep +0 -0
  115. data/test/stub/rails3.0/vendor/plugins/.gitkeep +0 -0
  116. data/test/stub/rails3.1/.gitignore +15 -0
  117. data/test/stub/rails3.1/Gemfile +1 -1
  118. data/test/stub/rails3.1/Gemfile.lock +1 -1
  119. data/test/stub/rails3.1/app/mailers/.gitkeep +0 -0
  120. data/test/stub/rails3.1/app/models/.gitkeep +0 -0
  121. data/test/stub/rails3.1/lib/assets/.gitkeep +0 -0
  122. data/test/stub/rails3.1/lib/tasks/.gitkeep +0 -0
  123. data/test/stub/rails3.1/log/.gitkeep +0 -0
  124. data/test/stub/rails3.1/test/fixtures/.gitkeep +0 -0
  125. data/test/stub/rails3.1/test/functional/.gitkeep +0 -0
  126. data/test/stub/rails3.1/test/integration/.gitkeep +0 -0
  127. data/test/stub/rails3.1/test/unit/.gitkeep +0 -0
  128. data/test/stub/rails3.1/vendor/assets/stylesheets/.gitkeep +0 -0
  129. data/test/stub/rails3.1/vendor/plugins/.gitkeep +0 -0
  130. data/test/stub/rails3.2/.gitignore +15 -0
  131. data/test/stub/rails3.2/app/mailers/.gitkeep +0 -0
  132. data/test/stub/rails3.2/app/models/.gitkeep +0 -0
  133. data/test/stub/rails3.2/lib/assets/.gitkeep +0 -0
  134. data/test/stub/rails3.2/lib/tasks/.gitkeep +0 -0
  135. data/test/stub/rails3.2/log/.gitkeep +0 -0
  136. data/test/stub/rails3.2/test/fixtures/.gitkeep +0 -0
  137. data/test/stub/rails3.2/test/functional/.gitkeep +0 -0
  138. data/test/stub/rails3.2/test/integration/.gitkeep +0 -0
  139. data/test/stub/rails3.2/test/unit/.gitkeep +0 -0
  140. data/test/stub/rails3.2/vendor/assets/stylesheets/.gitkeep +0 -0
  141. data/test/stub/rails3.2/vendor/plugins/.gitkeep +0 -0
  142. data/test/stub/rails4.0/.gitignore +16 -0
  143. data/test/stub/rails4.0/Gemfile +45 -0
  144. data/test/stub/rails4.0/Gemfile.lock +126 -0
  145. data/test/stub/rails4.0/README.rdoc +28 -0
  146. data/test/stub/rails4.0/Rakefile +6 -0
  147. data/test/stub/rails4.0/app/assets/images/.keep +0 -0
  148. data/test/stub/rails4.0/app/assets/javascripts/application.js +16 -0
  149. data/test/stub/rails4.0/app/assets/stylesheets/application.css +13 -0
  150. data/test/stub/rails4.0/app/controllers/application_controller.rb +5 -0
  151. data/test/stub/rails4.0/app/controllers/concerns/.keep +0 -0
  152. data/test/stub/rails4.0/app/helpers/application_helper.rb +2 -0
  153. data/test/stub/rails4.0/app/mailers/.keep +0 -0
  154. data/test/stub/rails4.0/app/models/.keep +0 -0
  155. data/test/stub/rails4.0/app/models/concerns/.keep +0 -0
  156. data/test/stub/rails4.0/app/views/layouts/application.html.erb +14 -0
  157. data/test/stub/rails4.0/bin/bundle +3 -0
  158. data/test/stub/rails4.0/bin/rails +4 -0
  159. data/test/stub/rails4.0/bin/rake +4 -0
  160. data/test/stub/rails4.0/config.ru +4 -0
  161. data/test/stub/rails4.0/config/application.rb +23 -0
  162. data/test/stub/rails4.0/config/boot.rb +4 -0
  163. data/test/stub/rails4.0/config/database.yml +25 -0
  164. data/test/stub/rails4.0/config/environment.rb +5 -0
  165. data/test/stub/rails4.0/config/environments/development.rb +29 -0
  166. data/test/stub/rails4.0/config/environments/production.rb +80 -0
  167. data/test/stub/rails4.0/config/environments/test.rb +36 -0
  168. data/test/stub/rails4.0/config/initializers/backtrace_silencers.rb +7 -0
  169. data/test/stub/rails4.0/config/initializers/filter_parameter_logging.rb +4 -0
  170. data/test/stub/rails4.0/config/initializers/inflections.rb +16 -0
  171. data/test/stub/rails4.0/config/initializers/mime_types.rb +5 -0
  172. data/test/stub/rails4.0/config/initializers/passenger.rb +1 -0
  173. data/test/stub/rails4.0/config/initializers/secret_token.rb +12 -0
  174. data/test/stub/rails4.0/config/initializers/session_store.rb +3 -0
  175. data/test/stub/rails4.0/config/initializers/wrap_parameters.rb +14 -0
  176. data/test/stub/rails4.0/config/locales/en.yml +23 -0
  177. data/test/stub/rails4.0/config/routes.rb +57 -0
  178. data/test/stub/rails4.0/db/seeds.rb +7 -0
  179. data/test/stub/rails4.0/lib/assets/.keep +0 -0
  180. data/test/stub/rails4.0/lib/tasks/.keep +0 -0
  181. data/test/stub/rails4.0/log/.keep +0 -0
  182. data/test/stub/rails4.0/public/404.html +58 -0
  183. data/test/stub/rails4.0/public/422.html +58 -0
  184. data/test/stub/rails4.0/public/500.html +57 -0
  185. data/test/stub/rails4.0/public/favicon.ico +0 -0
  186. data/test/stub/rails4.0/public/robots.txt +5 -0
  187. data/test/stub/rails4.0/test/controllers/.keep +0 -0
  188. data/test/stub/rails4.0/test/fixtures/.keep +0 -0
  189. data/test/stub/rails4.0/test/helpers/.keep +0 -0
  190. data/test/stub/rails4.0/test/integration/.keep +0 -0
  191. data/test/stub/rails4.0/test/mailers/.keep +0 -0
  192. data/test/stub/rails4.0/test/models/.keep +0 -0
  193. data/test/stub/rails4.0/test/test_helper.rb +15 -0
  194. data/test/stub/rails4.0/vendor/assets/javascripts/.keep +0 -0
  195. data/test/stub/rails4.0/vendor/assets/stylesheets/.keep +0 -0
  196. data/test/stub/rails_apps/1.2/empty/.gitignore +3 -0
  197. data/test/stub/rails_apps/1.2/empty/app/models/.gitignore +0 -0
  198. data/test/stub/rails_apps/1.2/empty/db/.gitignore +0 -0
  199. data/test/stub/rails_apps/1.2/empty/public/.htaccess +40 -0
  200. data/test/stub/rails_apps/1.2/empty/public/stylesheets/.gitignore +0 -0
  201. data/test/stub/rails_apps/2.0/empty/.gitignore +3 -0
  202. data/test/stub/rails_apps/2.0/empty/app/models/.gitignore +0 -0
  203. data/test/stub/rails_apps/2.0/empty/db/.gitignore +0 -0
  204. data/test/stub/rails_apps/2.0/empty/public/.htaccess +40 -0
  205. data/test/stub/rails_apps/2.0/empty/public/stylesheets/.gitignore +0 -0
  206. data/test/stub/rails_apps/2.2/empty/.gitignore +3 -0
  207. data/test/stub/rails_apps/2.2/empty/app/models/.gitignore +0 -0
  208. data/test/stub/rails_apps/2.2/empty/db/.gitignore +0 -0
  209. data/test/stub/rails_apps/2.2/empty/public/stylesheets/.gitignore +0 -0
  210. data/test/stub/rails_apps/2.3/empty/.gitignore +3 -0
  211. data/test/stub/rails_apps/2.3/empty/app/models/.gitignore +0 -0
  212. data/test/stub/rails_apps/2.3/empty/db/.gitignore +0 -0
  213. data/test/stub/rails_apps/2.3/empty/public/stylesheets/.gitignore +0 -0
  214. data/test/stub/rails_apps/2.3/mycook/public/.htaccess +42 -0
  215. data/test/stub/rails_apps/2.3/mycook/public/uploads/.gitignore +0 -0
  216. data/test/stub/wsgi/tmp/.gitignore +0 -0
  217. data/test/valgrind-osx.supp +7 -0
  218. metadata +162 -8
  219. metadata.gz.asc +7 -7
  220. data/debian.template/locations.ini +0 -12
  221. data/debian.template/ruby-passenger-dev.install +0 -3
  222. data/debian.template/ruby-passenger-doc.install +0 -2
  223. data/debian.template/ruby-passenger.install +0 -11
  224. data/resources/templates/installer_common/freebsd9_broken_cxx_runtime.txt.erb +0 -19
@@ -0,0 +1,163 @@
1
+ # encoding: utf-8
2
+ # Phusion Passenger - https://www.phusionpassenger.com/
3
+ # Copyright (c) 2013 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
+ require 'phusion_passenger/platform_info/binary_compatibility'
26
+ require 'phusion_passenger/utils/json'
27
+ require 'etc'
28
+
29
+ module PhusionPassenger
30
+ module Standalone
31
+
32
+ # Helper class for locating runtime files used by Passenger Standalone.
33
+ class RuntimeLocator
34
+ attr_reader :runtime_dir
35
+
36
+ def initialize(runtime_dir, nginx_version = PhusionPassenger::PREFERRED_NGINX_VERSION)
37
+ @runtime_dir = runtime_dir || default_runtime_dir
38
+ @nginx_version = nginx_version
39
+ end
40
+
41
+ def self.looks_like_support_dir?(dir)
42
+ File.exist?("#{dir}/agents/PassengerWatchdog") &&
43
+ File.exist?("#{dir}/common/libboost_oxt.a") &&
44
+ File.exist?("#{dir}/common/libpassenger_common/ApplicationPool2/Implementation.o")
45
+ end
46
+
47
+ def reload
48
+ @has_support_dir = @has_nginx_binary = false
49
+ end
50
+
51
+ # Returns the directory in which Passenger Standalone
52
+ # support binaries are stored, or nil if not installed.
53
+ def find_support_dir
54
+ return @support_dir if @has_support_dir
55
+
56
+ if PhusionPassenger.originally_packaged?
57
+ if debugging?
58
+ @support_dir = "#{PhusionPassenger.source_root}/buildout"
59
+ else
60
+ dir = "#{@runtime_dir}/#{version}/support-#{cxx_compat_id}"
61
+ if self.class.looks_like_support_dir?(dir)
62
+ @support_dir = dir
63
+ else
64
+ @support_dir = nil
65
+ end
66
+ end
67
+ else
68
+ @support_dir = PhusionPassenger.lib_dir
69
+ end
70
+ @has_support_dir = true
71
+ return @support_dir
72
+ end
73
+
74
+ # Returns the path to the Nginx binary that Passenger Standalone
75
+ # may use, or nil if not installed.
76
+ def find_nginx_binary
77
+ return @nginx_binary if @has_nginx_binary
78
+
79
+ if File.exist?(config_filename)
80
+ config = PhusionPassenger::Utils::JSON.parse(File.read(config_filename))
81
+ else
82
+ config = {}
83
+ end
84
+ if result = config["nginx_binary"]
85
+ @nginx_binary = result
86
+ elsif PhusionPassenger.natively_packaged? && @nginx_version == PhusionPassenger::PREFERRED_NGINX_VERSION
87
+ @nginx_binary = "#{PhusionPassenger.lib_dir}/nginx"
88
+ else
89
+ filename = "#{@runtime_dir}/#{version}/nginx-#{@nginx_version}-#{cxx_compat_id}/nginx"
90
+ if File.exist?(filename)
91
+ @nginx_binary = filename
92
+ else
93
+ @nginx_binary = nil
94
+ end
95
+ end
96
+ @has_nginx_binary = true
97
+ return @nginx_binary
98
+ end
99
+
100
+ def find_agents_dir
101
+ return "#{find_support_dir}/agents"
102
+ end
103
+
104
+ def find_lib_dir
105
+ return find_support_dir
106
+ end
107
+
108
+ def everything_installed?
109
+ return find_support_dir && find_nginx_binary
110
+ end
111
+
112
+ def install_targets
113
+ result = []
114
+ result << :nginx if find_nginx_binary.nil?
115
+ result << :support_binaries if find_support_dir.nil?
116
+ return result
117
+ end
118
+
119
+ # Returns the directory to which support binaries may be installed,
120
+ # in case the RuntimeInstaller is to be invoked.
121
+ def support_dir_install_destination
122
+ if PhusionPassenger.originally_packaged?
123
+ if debugging?
124
+ return "#{PhusionPassenger.lib_dir}/common/libpassenger_common"
125
+ else
126
+ return "#{@runtime_dir}/#{version}/support-#{cxx_compat_id}"
127
+ end
128
+ else
129
+ return nil
130
+ end
131
+ end
132
+
133
+ # Returns the directory to which the Nginx binary may be installed,
134
+ # in case the RuntimeInstaller is to be invoked.
135
+ def nginx_binary_install_destination
136
+ return "#{@runtime_dir}/#{version}/nginx-#{@nginx_version}-#{cxx_compat_id}"
137
+ end
138
+
139
+ private
140
+ def default_runtime_dir
141
+ home = Etc.getpwuid.dir
142
+ return "#{home}/#{USER_NAMESPACE_DIRNAME}/standalone"
143
+ end
144
+
145
+ def debugging?
146
+ return ['yes', 'y', 'true', '1'].include?(ENV['PASSENGER_DEBUG'].to_s.downcase)
147
+ end
148
+
149
+ def version
150
+ return PhusionPassenger::VERSION_STRING
151
+ end
152
+
153
+ def cxx_compat_id
154
+ return PlatformInfo.cxx_binary_compatibility_id
155
+ end
156
+
157
+ def config_filename
158
+ return "#{@runtime_dir}/config.json"
159
+ end
160
+ end
161
+
162
+ end # module Standalone
163
+ end # module PhusionPassenger
@@ -30,10 +30,6 @@ require 'phusion_passenger/standalone/command'
30
30
  # We lazy load as many libraries as possible not only to improve startup performance,
31
31
  # but also to ensure that we don't require libraries before we've passed the dependency
32
32
  # checking stage of the runtime installer.
33
- #
34
- # IMPORTANT: do not directly or indirectly require native_support; we can't compile
35
- # it yet until we have a compiler, and the runtime installer is supposed to check whether
36
- # a compiler is installed.
37
33
 
38
34
  module PhusionPassenger
39
35
  module Standalone
@@ -56,8 +52,11 @@ class StartCommand < Command
56
52
  parse_my_options
57
53
  sanity_check_options
58
54
 
59
- @runtime_dirs = determine_runtime_dirs
60
- ensure_nginx_installed
55
+ require 'phusion_passenger/standalone/runtime_locator'
56
+ @runtime_locator = RuntimeLocator.new(@options[:runtime_dir],
57
+ @options[:nginx_version])
58
+ ensure_runtime_installed
59
+ exit if @options[:runtime_check_only]
61
60
  determine_various_resource_locations
62
61
  require_app_finder
63
62
  @app_finder = AppFinder.new(@args, @options)
@@ -204,6 +203,8 @@ private
204
203
  wrap_desc("Where to store the PID file")) do |value|
205
204
  @options[:pid_file] = value
206
205
  end
206
+
207
+ opts.separator ""
207
208
  opts.on("--nginx-bin FILENAME", String,
208
209
  wrap_desc("Nginx binary to use as core")) do |value|
209
210
  @options[:nginx_bin] = value
@@ -222,10 +223,22 @@ private
222
223
  "checked for binaries prior to a local build.")) do |value|
223
224
  @options[:binaries_url_root] = value
224
225
  end
226
+ opts.on("--no-download-binaries",
227
+ wrap_desc("Never download binaries")) do
228
+ @options[:download_binaries] = false
229
+ end
225
230
  opts.on("--runtime-dir DIRECTORY", String,
226
231
  wrap_desc("Directory to use for Phusion Passenger Standalone runtime files")) do |value|
227
232
  @options[:runtime_dir] = File.expand_path(value)
228
233
  end
234
+ opts.on("--runtime-check-only",
235
+ wrap_desc("Quit after checking whether the Phusion Passenger Standalone runtime files are installed")) do
236
+ @options[:runtime_check_only] = true
237
+ end
238
+ opts.on("--no-compile-runtime",
239
+ wrap_desc("Abort if runtime must be compiled")) do
240
+ @options[:dont_compile_runtime] = true
241
+ end
229
242
  end
230
243
  @plugin.call_hook(:done_parsing_options)
231
244
  end
@@ -362,58 +375,37 @@ private
362
375
  end
363
376
  end
364
377
 
365
- def install_runtime(runtime_dirs)
378
+ def install_runtime(runtime_locator)
366
379
  require 'phusion_passenger/standalone/runtime_installer'
367
380
  installer = RuntimeInstaller.new(
368
- :targets => [:nginx, :ruby, :support_binaries],
369
- :support_dir => runtime_dirs[:support_dir],
370
- :nginx_dir => runtime_dirs[:nginx_dir],
371
- :ruby_dir => runtime_dirs[:ruby_dir],
381
+ :targets => runtime_locator.install_targets,
382
+ :support_dir => runtime_locator.support_dir_install_destination,
383
+ :nginx_dir => runtime_locator.nginx_binary_install_destination,
384
+ :lib_dir => runtime_locator.find_lib_dir || runtime_locator.support_dir_install_destination,
372
385
  :nginx_version => @options[:nginx_version],
373
386
  :nginx_tarball => @options[:nginx_tarball],
374
387
  :binaries_url_root => @options[:binaries_url_root],
388
+ :download_binaries => @options.fetch(:download_binaries, true),
389
+ :dont_compile_runtime => @options[:dont_compile_runtime],
375
390
  :plugin => @plugin)
376
391
  return installer.run
377
392
  end
378
393
 
379
- def determine_runtime_dirs
380
- require_platform_info_binary_compatibility
381
- if root = @options[:runtime_dir]
382
- nginx_dir = determine_nginx_runtime_dir(root)
383
- else
384
- root = "#{GLOBAL_STANDALONE_RESOURCE_DIR}/#{PhusionPassenger::VERSION_STRING}"
385
- nginx_dir = determine_nginx_runtime_dir(root)
386
- if !File.exist?("#{nginx_dir}/nginx") && Process.euid != 0
387
- home = Etc.getpwuid.dir
388
- root = "#{home}/#{LOCAL_STANDALONE_RESOURCE_DIR}/#{PhusionPassenger::VERSION_STRING}"
389
- nginx_dir = determine_nginx_runtime_dir(root)
390
- end
391
- end
392
- nginx_bin = @options[:nginx_bin] || "#{nginx_dir}/nginx"
393
- result = {
394
- :root => root,
395
- :support_dir => "#{root}/support-#{PlatformInfo.cxx_binary_compatibility_id}",
396
- :nginx_dir => nginx_dir,
397
- :ruby_dir => "#{root}/rubyext-#{PlatformInfo.ruby_extension_binary_compatibility_id}",
398
- :nginx_installed => File.exist?(nginx_bin)
399
- }
400
- result[:support_dir_installed] = File.exist?(result[:support_dir] + "/agents/PassengerWatchdog")
401
- result[:everything_installed] = result[:nginx_installed] && result[:support_dir_installed]
402
- return result
403
- end
404
-
405
- def determine_nginx_runtime_dir(runtime_dir)
406
- return "#{runtime_dir}/nginx-#{@options[:nginx_version]}-#{PlatformInfo.cxx_binary_compatibility_id}"
407
- end
408
-
409
- def ensure_nginx_installed
410
- if !@runtime_dirs[:everything_installed]
411
- if !@runtime_dirs[:nginx_installed] && @options[:nginx_bin]
412
- error "The given Nginx binary '#{@options[:nginx_bin]}' does not exist."
394
+ def ensure_runtime_installed
395
+ if @runtime_locator.everything_installed?
396
+ if !File.exist?(@runtime_locator.find_nginx_binary)
397
+ error "The Nginx binary '#{@runtime_locator.find_nginx_binary}' does not exist."
413
398
  exit 1
414
- elsif !install_runtime(@runtime_dirs)
399
+ end
400
+ else
401
+ if !@runtime_locator.find_support_dir && PhusionPassenger.natively_packaged?
402
+ error "Your Phusion Passenger Standalone installation is broken: the support " +
403
+ "files could not be found. Please reinstall Phusion Passenger Standalone. " +
404
+ "If this problem persists, please contact your packager."
415
405
  exit 1
416
406
  end
407
+ install_runtime(@runtime_locator) || exit(1)
408
+ @runtime_locator.reload
417
409
  end
418
410
  end
419
411
 
@@ -0,0 +1,329 @@
1
+ # encoding: utf-8
2
+ #
3
+ ## Stupid small pure Ruby JSON parser & generator.
4
+ #
5
+ # Copyright © 2013 Mislav Marohnić
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this
8
+ # software and associated documentation files (the “Software”), to deal in the Software
9
+ # without restriction, including without limitation the rights to use, copy, modify,
10
+ # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to the following
12
+ # conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all copies or
15
+ # substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21
+ # OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ # OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ # We use this in Phusion Passenger at places where we cannot depend on the JSON
25
+ # gem being available, for example in 'passenger start' before the RuntimeInstaller
26
+ # has run.
27
+
28
+ require 'strscan'
29
+ require 'forwardable'
30
+
31
+ module PhusionPassenger
32
+ module Utils
33
+
34
+ # Usage:
35
+ #
36
+ # JSON.parse(json_string) => Array/Hash
37
+ # JSON.generate(object) => json string
38
+ #
39
+ # Run tests by executing this file directly. Pipe standard input to the script to have it
40
+ # parsed as JSON and to display the result in Ruby.
41
+ #
42
+ class JSON
43
+ def self.parse(data) new(data).parse end
44
+
45
+ WSP = /\s+/
46
+ OBJ = /[{\[]/; HEN = /\}/; AEN = /\]/
47
+ COL = /\s*:\s*/; KEY = /\s*,\s*/
48
+ NUM = /-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/
49
+ BOL = /true|false/; NUL = /null/
50
+
51
+ extend Forwardable
52
+
53
+ attr_reader :scanner
54
+ alias_method :s, :scanner
55
+ def_delegators :scanner, :scan, :matched
56
+ private :s, :scan, :matched
57
+
58
+ def initialize data
59
+ @scanner = StringScanner.new data.to_s
60
+ end
61
+
62
+ def parse
63
+ space
64
+ object
65
+ end
66
+
67
+ private
68
+
69
+ def space() scan WSP end
70
+
71
+ def endkey() scan(KEY) or space end
72
+
73
+ def object
74
+ matched == '{' ? hash : array if scan(OBJ)
75
+ end
76
+
77
+ def value
78
+ object or string or
79
+ scan(NUL) ? nil :
80
+ scan(BOL) ? matched.size == 4:
81
+ scan(NUM) ? eval(matched) :
82
+ error
83
+ end
84
+
85
+ def hash
86
+ obj = {}
87
+ space
88
+ repeat_until(HEN) { k = string; scan(COL); obj[k] = value; endkey }
89
+ obj
90
+ end
91
+
92
+ def array
93
+ ary = []
94
+ space
95
+ repeat_until(AEN) { ary << value; endkey }
96
+ ary
97
+ end
98
+
99
+ SPEC = {'b' => "\b", 'f' => "\f", 'n' => "\n", 'r' => "\r", 't' => "\t"}
100
+ UNI = 'u'; CODE = /[a-fA-F0-9]{4}/
101
+ STR = /"/; STE = '"'
102
+ ESC = '\\'
103
+
104
+ def string
105
+ if scan(STR)
106
+ str, esc = '', false
107
+ while c = s.getch
108
+ if esc
109
+ str << (c == UNI ? (s.scan(CODE) || error).to_i(16).chr : SPEC[c] || c)
110
+ esc = false
111
+ else
112
+ case c
113
+ when ESC then esc = true
114
+ when STE then break
115
+ else str << c
116
+ end
117
+ end
118
+ end
119
+ str
120
+ end
121
+ end
122
+
123
+ def error
124
+ raise "parse error at: #{scan(/.{1,10}/m).inspect}"
125
+ end
126
+
127
+ def repeat_until reg
128
+ until scan(reg)
129
+ pos = s.pos
130
+ yield
131
+ error unless s.pos > pos
132
+ end
133
+ end
134
+
135
+ module Generator
136
+ def generate(obj)
137
+ raise ArgumentError unless obj.is_a? Array or obj.is_a? Hash
138
+ generate_type(obj)
139
+ end
140
+ alias dump generate
141
+
142
+ private
143
+
144
+ def generate_type(obj)
145
+ type = obj.is_a?(Numeric) ? :Numeric : obj.class.name
146
+ begin send(:"generate_#{type}", obj)
147
+ rescue NoMethodError; raise ArgumentError, "can't serialize #{type}"
148
+ end
149
+ end
150
+
151
+ ESC_MAP = Hash.new {|h,k| k }.update \
152
+ "\r" => 'r',
153
+ "\n" => 'n',
154
+ "\f" => 'f',
155
+ "\t" => 't',
156
+ "\b" => 'b'
157
+
158
+ def quote(str) %("#{str}") end
159
+
160
+ def generate_String(str)
161
+ quote str.gsub(/[\r\n\f\t\b"\\]/) { "\\#{ESC_MAP[$&]}"}
162
+ end
163
+
164
+ def generate_simple(obj) obj.inspect end
165
+ alias generate_Numeric generate_simple
166
+ alias generate_TrueClass generate_simple
167
+ alias generate_FalseClass generate_simple
168
+
169
+ def generate_Symbol(sym) generate_String(sym.to_s) end
170
+
171
+ def generate_Time(time)
172
+ quote time.strftime(time.utc? ? "%F %T UTC" : "%F %T %z")
173
+ end
174
+ def generate_Date(date) quote date.to_s end
175
+
176
+ def generate_NilClass(*) 'null' end
177
+
178
+ def generate_Array(ary) '[%s]' % ary.map {|o| generate_type(o) }.join(', ') end
179
+
180
+ def generate_Hash(hash)
181
+ '{%s}' % hash.map { |key, value|
182
+ "#{generate_String(key.to_s)}: #{generate_type(value)}"
183
+ }.join(', ')
184
+ end
185
+ end
186
+
187
+ extend Generator
188
+ end
189
+
190
+ if __FILE__ == $0
191
+ if !$stdin.tty?
192
+ data = JSON.parse $stdin.read
193
+ require 'pp'
194
+ pp data
195
+ else
196
+ require 'test/unit'
197
+ require 'date'
198
+ class ParserTest < Test::Unit::TestCase
199
+ PARSED = JSON.parse DATA.read
200
+ def parsed() PARSED end
201
+ def parse_string(str) JSON.parse(%(["#{str}"]).gsub('\\\\', '\\')).first end
202
+ def test_string
203
+ assert_equal "Pagination library for \"Rails 3\", Sinatra, Merb, DataMapper, and more",
204
+ parsed['head']['repository']['description']
205
+ end
206
+ def test_string_specials
207
+ assert_equal "\r\n\t\f\b", parse_string('\r\n\t\f\b')
208
+ assert_equal "aA", parse_string('\u0061\u0041')
209
+ assert_equal "\e", parse_string('\u001B')
210
+ assert_equal "xyz", parse_string('\x\y\z')
211
+ assert_equal '"\\/', parse_string('\"\\\\\\/')
212
+ assert_equal 'no #{interpolation}', parse_string('no #{interpolation}')
213
+ end
214
+ def test_hash
215
+ assert_equal %w[label ref repository sha user], parsed['head'].keys.sort
216
+ end
217
+ def test_number
218
+ assert_equal 124.3e2, parsed['head']['repository']['size']
219
+ end
220
+ def test_bool
221
+ assert_equal true, parsed['head']['repository']['fork']
222
+ assert_equal false, parsed['head']['repository']['private']
223
+ end
224
+ def test_nil
225
+ assert_nil parsed['head']['user']['company']
226
+ end
227
+ def test_array
228
+ assert_equal ["4438f", {"a" => "b"}], parsed['head']['sha']
229
+ end
230
+ def test_invalid
231
+ assert_raises(RuntimeError) { JSON.parse %({) }
232
+ assert_raises(RuntimeError) { JSON.parse %({ "foo": }) }
233
+ assert_raises(RuntimeError) { JSON.parse %([ "foo": "bar" ]) }
234
+ assert_raises(RuntimeError) { JSON.parse %([ ~"foo" ]) }
235
+ assert_raises(RuntimeError) { JSON.parse %([ "foo ]) }
236
+ assert_raises(RuntimeError) { JSON.parse %([ "foo\\" ]) }
237
+ assert_raises(RuntimeError) { JSON.parse %([ "foo\\uabGd" ]) }
238
+ end
239
+ end
240
+
241
+ class GeneratorTest < Test::Unit::TestCase
242
+ def generate(obj) JSON.generate(obj) end
243
+ def test_array
244
+ assert_equal %([1, 2, 3]), generate([1, 2, 3])
245
+ end
246
+ def test_bool
247
+ assert_equal %([true, false]), generate([true, false])
248
+ end
249
+ def test_null
250
+ assert_equal %([null]), generate([nil])
251
+ end
252
+ def test_string
253
+ assert_equal %(["abc\\n123"]), generate(["abc\n123"])
254
+ end
255
+ def test_string_unicode
256
+ assert_equal %(["ć\\"č\\nž\\tš\\\\đ"]), generate(["ć\"č\nž\tš\\đ"])
257
+ end
258
+ def test_time
259
+ time = Time.utc(2012, 04, 19, 1, 2, 3)
260
+ assert_equal %(["2012-04-19 01:02:03 UTC"]), generate([time])
261
+ end
262
+ def test_date
263
+ time = Date.new(2012, 04, 19)
264
+ assert_equal %(["2012-04-19"]), generate([time])
265
+ end
266
+ def test_symbol
267
+ assert_equal %(["abc"]), generate([:abc])
268
+ end
269
+ def test_hash
270
+ json = generate(:abc => 123, 123 => 'abc')
271
+ assert_match /^\{/, json
272
+ assert_match /\}$/, json
273
+ assert_equal [%("123": "abc"), %("abc": 123)], json[1...-1].split(', ').sort
274
+ end
275
+ def test_nested_structure
276
+ json = generate(:hash => {1=>2}, :array => [1,2])
277
+ assert json.include?(%("hash": {"1": 2}))
278
+ assert json.include?(%("array": [1, 2]))
279
+ end
280
+ def test_invalid_json
281
+ assert_raises(ArgumentError) { generate("abc") }
282
+ end
283
+ def test_invalid_object
284
+ err = assert_raises(ArgumentError) { generate("a" => Object.new) }
285
+ assert_equal "can't serialize Object", err.message
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ end # module Utils
292
+ end # module PhusionPassenger
293
+
294
+ __END__
295
+ {
296
+ "head": {
297
+ "ref": "master",
298
+ "repository": {
299
+ "forks": 0,
300
+ "integrate_branch": "rails3",
301
+ "watchers": 1,
302
+ "language": "Ruby",
303
+ "description": "Pagination library for \"Rails 3\", Sinatra, Merb, DataMapper, and more",
304
+ "has_downloads": true,
305
+ "fork": true,
306
+ "created_at": "2011/10/24 03:20:48 -0700",
307
+ "homepage": "http://github.com/mislav/will_paginate/wikis",
308
+ "size": 124.3e2,
309
+ "private": false,
310
+ "has_wiki": true,
311
+ "name": "will_paginate",
312
+ "owner": "dbackeus",
313
+ "url": "https://github.com/dbackeus/will_paginate",
314
+ "has_issues": false,
315
+ "open_issues": 0,
316
+ "pushed_at": "2011/10/25 05:44:05 -0700"
317
+ },
318
+ "label": "dbackeus:master",
319
+ "sha": ["4438f", { "a" : "b" }],
320
+ "user": {
321
+ "name": "David Backeus",
322
+ "company": null,
323
+ "gravatar_id": "ebe96524f5db9e92188f0542dc9d1d1a",
324
+ "location": "Stockholm (Sweden)",
325
+ "type": "User",
326
+ "login": "dbackeus"
327
+ }
328
+ }
329
+ }