passenger 5.0.21 → 5.0.22

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 (203) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/CHANGELOG +38 -2
  5. data/CONTRIBUTORS +3 -0
  6. data/README.md +5 -1
  7. data/bin/passenger-status +2 -7
  8. data/build/agent.rb +2 -0
  9. data/build/cxx_dependency_map.rb +1464 -162
  10. data/build/node_tests.rb +1 -1
  11. data/build/packaging.rb +1 -1
  12. data/dev/ci/run_travis.sh +1 -1
  13. data/dev/vagrant/provision.sh +1 -1
  14. data/npm-shrinkwrap.json +635 -125
  15. data/package.json +1 -1
  16. data/resources/templates/standalone/config.erb +33 -161
  17. data/resources/templates/standalone/global.erb +15 -0
  18. data/resources/templates/standalone/http.erb +40 -0
  19. data/resources/templates/standalone/mass_deployment_default_server.erb +11 -0
  20. data/resources/templates/standalone/rails_asset_pipeline.erb +22 -0
  21. data/resources/templates/standalone/server.erb +58 -0
  22. data/src/agent/Core/ApiServer.h +37 -32
  23. data/src/agent/Core/ApplicationPool/BasicGroupInfo.h +1 -1
  24. data/src/agent/Core/ApplicationPool/BasicProcessInfo.h +6 -0
  25. data/src/agent/Core/ApplicationPool/Common.h +1 -1
  26. data/src/agent/Core/ApplicationPool/Group/OutOfBandWork.cpp +1 -1
  27. data/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp +4 -0
  28. data/src/agent/Core/ApplicationPool/Implementation.cpp +2 -2
  29. data/src/agent/Core/ApplicationPool/Options.h +18 -1
  30. data/src/agent/Core/ApplicationPool/Pool.h +1 -1
  31. data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +6 -6
  32. data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +3 -3
  33. data/src/agent/Core/ApplicationPool/Pool/InitializationAndShutdown.cpp +1 -1
  34. data/src/agent/Core/ApplicationPool/Pool/Miscellaneous.cpp +6 -0
  35. data/src/agent/Core/ApplicationPool/Process.h +6 -1
  36. data/src/agent/Core/ApplicationPool/Socket.h +9 -12
  37. data/src/agent/Core/Controller.h +422 -0
  38. data/src/agent/Core/{RequestHandler → Controller}/AppResponse.h +2 -0
  39. data/src/agent/Core/{RequestHandler → Controller}/BufferBody.cpp +27 -5
  40. data/src/agent/Core/{RequestHandler → Controller}/CheckoutSession.cpp +61 -31
  41. data/src/agent/Core/{RequestHandler → Controller}/Client.h +5 -2
  42. data/src/agent/Core/{RequestHandler → Controller}/ForwardResponse.cpp +93 -42
  43. data/src/agent/Core/{RequestHandler → Controller}/Hooks.cpp +107 -60
  44. data/src/agent/Core/Controller/Implementation.cpp +38 -0
  45. data/src/agent/Core/{RequestHandler → Controller}/InitRequest.cpp +134 -80
  46. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +165 -0
  47. data/src/agent/Core/{RequestHandler/Utils.cpp → Controller/InternalUtils.cpp} +49 -32
  48. data/src/agent/Core/Controller/Miscellaneous.cpp +116 -0
  49. data/src/agent/Core/{RequestHandler → Controller}/Request.h +6 -4
  50. data/src/agent/Core/{RequestHandler → Controller}/SendRequest.cpp +205 -130
  51. data/src/agent/Core/Controller/StateInspectionAndConfiguration.cpp +161 -0
  52. data/src/agent/Core/{RequestHandler → Controller}/TurboCaching.h +3 -0
  53. data/src/agent/Core/CoreMain.cpp +62 -51
  54. data/src/agent/Core/OptionParser.h +24 -0
  55. data/src/agent/Core/ResponseCache.h +5 -5
  56. data/src/agent/Core/SpawningKit/Config.h +2 -2
  57. data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -1
  58. data/src/agent/Core/UnionStation/{Core.h → Context.h} +14 -18
  59. data/src/agent/Core/UnionStation/StopwatchLog.h +3 -2
  60. data/src/agent/Core/UnionStation/Transaction.h +7 -7
  61. data/src/agent/Shared/ApiServerUtils.h +9 -1
  62. data/src/agent/UstRouter/ApiServer.h +5 -2
  63. data/src/agent/UstRouter/Controller.h +27 -9
  64. data/src/agent/UstRouter/UstRouterMain.cpp +1 -0
  65. data/src/agent/Watchdog/ApiServer.h +5 -2
  66. data/src/apache2_module/ConfigurationCommands.cpp +7 -0
  67. data/src/apache2_module/ConfigurationFields.hpp +2 -0
  68. data/src/apache2_module/ConfigurationSetters.cpp +24 -0
  69. data/src/apache2_module/CreateDirConfig.cpp +1 -0
  70. data/src/apache2_module/Hooks.cpp +6 -5
  71. data/src/apache2_module/MergeDirConfig.cpp +7 -0
  72. data/src/apache2_module/SetHeaders.cpp +5 -0
  73. data/src/cxx_supportlib/Constants.h +5 -3
  74. data/src/cxx_supportlib/SafeLibev.h +2 -1
  75. data/src/cxx_supportlib/UnionStationFilterSupport.h +2 -1
  76. data/src/cxx_supportlib/Utils/ReleaseableScopedPointer.h +70 -0
  77. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/regex_raw_buffer.cpp +6 -6
  78. data/src/helper-scripts/node-loader.js +59 -0
  79. data/src/nginx_module/CacheLocationConfig.c +48 -0
  80. data/src/nginx_module/ConfigurationCommands.c +20 -0
  81. data/src/nginx_module/ConfigurationFields.h +4 -0
  82. data/src/nginx_module/CreateLocationConfig.c +8 -0
  83. data/src/nginx_module/MergeLocationConfig.c +12 -0
  84. data/src/nodejs_supportlib/phusion_passenger/log_express.js +106 -0
  85. data/src/nodejs_supportlib/phusion_passenger/log_mongodb.js +203 -0
  86. data/src/nodejs_supportlib/phusion_passenger/ustreporter.js +227 -0
  87. data/src/nodejs_supportlib/phusion_passenger/ustrouter_connector.js +446 -0
  88. data/src/nodejs_supportlib/vendor-copy/codify/codify.js +44 -0
  89. data/src/nodejs_supportlib/vendor-copy/codify/package.json +29 -0
  90. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/context.js +200 -0
  91. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/glue.js +488 -0
  92. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/index.js +407 -0
  93. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/node_modules/shimmer/index.js +90 -0
  94. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/node_modules/shimmer/package.json +40 -0
  95. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/package.json +54 -0
  96. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/listener.js +160 -0
  97. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/node_modules/shimmer/index.js +90 -0
  98. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/node_modules/shimmer/package.json +40 -0
  99. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/package.json +46 -0
  100. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/package.json +56 -0
  101. data/src/nodejs_supportlib/vendor-copy/network-byte-order/lib/index.js +102 -0
  102. data/src/nodejs_supportlib/vendor-copy/network-byte-order/package.json +51 -0
  103. data/src/nodejs_supportlib/vendor-copy/winston/LICENSE +19 -0
  104. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston.js +165 -0
  105. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/common.js +483 -0
  106. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config.js +62 -0
  107. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/cli-config.js +35 -0
  108. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/npm-config.js +27 -0
  109. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/syslog-config.js +31 -0
  110. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/container.js +127 -0
  111. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/exception.js +56 -0
  112. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/logger.js +701 -0
  113. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports.js +34 -0
  114. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/console.js +128 -0
  115. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/daily-rotate-file.js +601 -0
  116. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/file.js +675 -0
  117. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/http.js +232 -0
  118. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/memory.js +89 -0
  119. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/transport.js +135 -0
  120. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/webhook.js +146 -0
  121. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/LICENSE +19 -0
  122. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/lib/async.js +1283 -0
  123. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/package.json +66 -0
  124. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/support/sync-package-managers.js +53 -0
  125. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/MIT-LICENSE.txt +23 -0
  126. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/colors.js +176 -0
  127. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/custom/trap.js +45 -0
  128. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/custom/zalgo.js +104 -0
  129. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/extendStringPrototype.js +118 -0
  130. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/index.js +12 -0
  131. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/america.js +12 -0
  132. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/rainbow.js +13 -0
  133. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/random.js +8 -0
  134. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/zebra.js +5 -0
  135. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/styles.js +77 -0
  136. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/system/supports-colors.js +61 -0
  137. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/package.json +35 -0
  138. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/safe.js +9 -0
  139. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/themes/generic-logging.js +12 -0
  140. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/cycle/cycle.js +170 -0
  141. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/cycle/package.json +30 -0
  142. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/LICENSE +20 -0
  143. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/lib/eyes.js +236 -0
  144. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/package.json +42 -0
  145. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/LICENSE.md +11 -0
  146. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/isstream.js +27 -0
  147. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/package.json +42 -0
  148. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/LICENSE +19 -0
  149. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/lib/pkginfo.js +136 -0
  150. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/package.json +56 -0
  151. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/License +19 -0
  152. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/lib/stack-trace.js +111 -0
  153. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/package.json +33 -0
  154. data/src/nodejs_supportlib/vendor-copy/winston/package.json +87 -0
  155. data/src/ruby_supportlib/phusion_passenger.rb +3 -4
  156. data/src/ruby_supportlib/phusion_passenger/admin_tools/instance.rb +19 -2
  157. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +8 -0
  158. data/src/ruby_supportlib/phusion_passenger/config/list_instances_command.rb +2 -6
  159. data/src/ruby_supportlib/phusion_passenger/config/reopen_logs_command.rb +13 -0
  160. data/src/ruby_supportlib/phusion_passenger/config/restart_app_command.rb +3 -0
  161. data/src/ruby_supportlib/phusion_passenger/config/utils.rb +9 -7
  162. data/src/ruby_supportlib/phusion_passenger/config/validate_install_command.rb +8 -1
  163. data/src/ruby_supportlib/phusion_passenger/constants.rb +3 -1
  164. data/src/ruby_supportlib/phusion_passenger/native_support.rb +20 -4
  165. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +8 -0
  166. data/src/ruby_supportlib/phusion_passenger/packaging.rb +1 -0
  167. data/src/ruby_supportlib/phusion_passenger/platform_info/apache_detector.rb +1 -1
  168. data/src/ruby_supportlib/phusion_passenger/platform_info/operating_system.rb +11 -4
  169. data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
  170. data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +647 -0
  171. data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +229 -15
  172. data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +35 -323
  173. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +36 -12
  174. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/nginx_engine.rb +123 -14
  175. data/src/ruby_supportlib/phusion_passenger/standalone/status_command.rb +32 -17
  176. data/src/ruby_supportlib/phusion_passenger/standalone/stop_command.rb +32 -21
  177. data/src/ruby_supportlib/phusion_passenger/standalone/version_command.rb +5 -5
  178. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README.md +2 -2
  179. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Rakefile +5 -1
  180. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +68 -24
  181. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +9 -1
  182. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +9 -7
  183. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +3 -2
  184. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/basics.rb +8 -5
  185. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +395 -0
  186. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +10 -7
  187. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +14 -0
  188. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version_data.rb +2 -2
  189. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml +4 -2
  190. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.example +2 -2
  191. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis +2 -2
  192. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis-with-sudo +16 -0
  193. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile +1 -1
  194. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile.lock +2 -2
  195. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/README.md +1 -1
  196. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails.rb +44 -17
  197. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_support_cache_subscriber.rb +16 -7
  198. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/version_data.rb +2 -2
  199. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/union_station_hooks_rails.gemspec +1 -1
  200. metadata +99 -16
  201. metadata.gz.asc +7 -7
  202. data/resources/oss-binaries.phusionpassenger.com.crt +0 -248
  203. data/src/agent/Core/RequestHandler.h +0 -471
@@ -23,6 +23,7 @@
23
23
  # THE SOFTWARE.
24
24
 
25
25
  PhusionPassenger.require_passenger_lib 'ruby_core_enhancements'
26
+ PhusionPassenger.require_passenger_lib 'standalone/config_options_list'
26
27
 
27
28
  module PhusionPassenger
28
29
  module Standalone
@@ -46,6 +47,23 @@ module PhusionPassenger
46
47
  USER_NAMESPACE_DIRNAME, "standalone", "config.json")
47
48
  end
48
49
 
50
+ def load_local_config_file_from_app_dir_param!(argv)
51
+ if argv.empty?
52
+ app_dir = Dir.logical_pwd
53
+ elsif argv.size == 1
54
+ app_dir = argv[0]
55
+ end
56
+ local_options = {}
57
+ if app_dir
58
+ begin
59
+ ConfigUtils.load_local_config_file!(app_dir, local_options)
60
+ rescue ConfigUtils::ConfigLoadError => e
61
+ abort "*** ERROR: #{e.message}"
62
+ end
63
+ end
64
+ local_options
65
+ end
66
+
49
67
  def load_local_config_file!(app_dir, options)
50
68
  config_file = File.join(app_dir, "Passengerfile.json")
51
69
  if !File.exist?(config_file)
@@ -79,28 +97,224 @@ module PhusionPassenger
79
97
  end
80
98
 
81
99
  result = {}
100
+ config_file_dir = File.dirname(File.absolute_logical_path(filename))
82
101
  config.each_pair do |key, val|
83
- result[key.to_sym] = val
102
+ key = key.to_sym
103
+ spec_item = CONFIG_NAME_INDEX[key]
104
+ if spec_item
105
+ begin
106
+ result[key] = parse_config_value(spec_item, val, config_file_dir)
107
+ rescue ConfigLoadError => e
108
+ raise ConfigLoadError, "cannot parse config file #{filename} " \
109
+ "(error in config option '#{key}': #{e.message})"
110
+ end
111
+ else
112
+ result[key] = val
113
+ end
84
114
  end
85
115
 
86
- resolve_config_file_paths(result, filename)
87
-
88
116
  result
89
117
  end
90
118
 
91
- # Absolutize relative paths. Make them relative to the config file in which
92
- # it's specified.
93
- def resolve_config_file_paths(config_file_options, config_filename)
94
- options = config_file_options
95
- config_file_dir = File.dirname(File.absolute_logical_path(config_filename))
119
+ def load_env_config!
120
+ begin
121
+ load_env_config
122
+ rescue ConfigUtils::ConfigLoadError => e
123
+ abort "*** ERROR: #{e.message}"
124
+ end
125
+ end
126
+
127
+ def load_env_config
128
+ config = {}
129
+ pwd = Dir.logical_pwd
130
+
131
+ ENV.each_pair do |name, value|
132
+ next if name !~ /^PASSENGER_(.+)/
133
+ key = $1.downcase.to_sym
134
+ spec_item = CONFIG_NAME_INDEX[key]
135
+ next if !spec_item
136
+ next if !config_type_supported_in_envvar?(spec_item[:type])
137
+ next if value.empty?
138
+
139
+ begin
140
+ config[key] = parse_config_value(spec_item, value, pwd)
141
+ rescue ConfigLoadError => e
142
+ raise ConfigLoadError, "cannot parse environment variable '#{name}' " \
143
+ "(#{e.message})"
144
+ end
145
+ end
146
+
147
+ config
148
+ end
149
+
150
+ def add_option_parser_options_from_config_spec(parser, spec, options)
151
+ spec.each do |spec_item|
152
+ next if spec_item[:cli].nil?
153
+ args = []
154
+
155
+ if spec_item[:short_cli]
156
+ args << spec_item[:short_cli]
157
+ end
158
+
159
+ args << make_long_cli_switch(spec_item)
160
+
161
+ if type = determine_cli_switch_type(spec_item)
162
+ args << type
163
+ end
164
+
165
+ args << format_cli_switch_description(spec_item)
166
+
167
+ cli_parser = make_cli_switch_parser(parser, spec_item, options)
168
+
169
+ parser.on(*args, &cli_parser)
170
+ end
171
+ end
172
+
173
+ # We want the command line options to override the options in the local
174
+ # config file, but the local config file could only be parsed when the
175
+ # command line options have been parsed. This method remerges all the
176
+ # config options from different sources so that options are overriden
177
+ # according to the following order:
178
+ #
179
+ # - CONFIG_DEFAULTS
180
+ # - global config file
181
+ # - local config file
182
+ # - environment variables
183
+ # - command line options
184
+ def remerge_all_config(global_options, local_options, env_options, parsed_options)
185
+ CONFIG_DEFAULTS.merge(remerge_all_config_without_defaults(
186
+ global_options, local_options, env_options, parsed_options))
187
+ end
188
+
189
+ def remerge_all_config_without_defaults(global_options, local_options, env_options, parsed_options)
190
+ global_options.
191
+ merge(local_options).
192
+ merge(env_options).
193
+ merge(parsed_options)
194
+ end
195
+
196
+ def find_pid_and_log_file(execution_root, options)
197
+ if options[:socket_file]
198
+ pid_basename = 'passenger.pid'
199
+ log_basename = 'passenger.log'
200
+ else
201
+ pid_basename = "passenger.#{options[:port]}.pid"
202
+ log_basename = "passenger.#{options[:port]}.log"
203
+ end
204
+ if File.directory?("#{execution_root}/tmp/pids")
205
+ options[:pid_file] ||= "#{execution_root}/tmp/pids/#{pid_basename}"
206
+ else
207
+ options[:pid_file] ||= "#{execution_root}/#{pid_basename}"
208
+ end
209
+ if File.directory?("#{execution_root}/log")
210
+ options[:log_file] ||= "#{execution_root}/log/#{log_basename}"
211
+ else
212
+ options[:log_file] ||= "#{execution_root}/#{log_basename}"
213
+ end
214
+ end
215
+
216
+ private
217
+ def config_type_supported_in_envvar?(type)
218
+ type == :string || type == :integer || type == :boolean ||
219
+ type == :path
220
+ end
221
+
222
+ def parse_config_value(spec_item, value, base_dir)
223
+ if parser = spec_item[:config_value_parser]
224
+ return parser.call(value, base_dir)
225
+ end
226
+
227
+ case spec_item[:type]
228
+ when :string
229
+ value.to_s
230
+ when :integer
231
+ value = value.to_i
232
+ if spec_item[:min] && value < spec_item[:min]
233
+ raise ConfigLoadError, "value must be greater than or equal to #{spec_item[:min]}"
234
+ else
235
+ value
236
+ end
237
+ when :boolean
238
+ value = value.to_s.downcase
239
+ value == 'true' || value == 'yes' || value == 'on' || value == '1'
240
+ when :path
241
+ File.absolute_logical_path(value.to_s, base_dir)
242
+ when :array
243
+ if value.is_a?(Array)
244
+ value
245
+ else
246
+ raise ConfigLoadError, "array expected"
247
+ end
248
+ when :map
249
+ if value.is_a?(Hash)
250
+ value
251
+ else
252
+ raise ConfigLoadError, "map expected"
253
+ end
254
+ else
255
+ raise ArgumentError, "Unsupported type #{spec_item[:type]}"
256
+ end
257
+ end
258
+
259
+ def make_long_cli_switch(spec_item)
260
+ case spec_item[:type]
261
+ when :string, :integer, :path, :array, :map
262
+ "#{spec_item[:cli]} #{spec_item[:type_desc]}"
263
+ when :boolean
264
+ spec_item[:cli]
265
+ else
266
+ raise ArgumentError,
267
+ "Cannot create long CLI switch for type #{spec_item[:type]}"
268
+ end
269
+ end
270
+
271
+ def determine_cli_switch_type(spec_item)
272
+ case spec_item[:type]
273
+ when :string, :path, :array, :map
274
+ String
275
+ when :integer
276
+ Integer
277
+ when :boolean
278
+ nil
279
+ else
280
+ raise ArgumentError,
281
+ "Cannot determine CLI switch type for #{spec_item[:type]}"
282
+ end
283
+ end
96
284
 
97
- keys = [:socket_file, :ssl_certificate, :ssl_certificate_key, :log_file,
98
- :pid_file, :instance_registry_dir, :data_buffer_dir, :meteor_app_settings,
99
- :rackup, :startup_file, :static_files_dir, :restart_dir,
100
- :nginx_config_template]
101
- keys.each do |key|
102
- if filename = options[key]
103
- options[key] = File.expand_path(filename, config_file_dir)
285
+ def format_cli_switch_description(spec_item)
286
+ desc = spec_item[:desc]
287
+ return '(no description)' if desc.nil?
288
+ result = desc.gsub("\n", "\n" + ' ' * 37)
289
+ result.gsub!('%DEFAULT%', (spec_item[:default] || 'N/A').to_s)
290
+ result
291
+ end
292
+
293
+ def make_cli_switch_parser(parser, spec_item, options)
294
+ if cli_parser = spec_item[:cli_parser]
295
+ lambda do |value|
296
+ cli_parser.call(options, value)
297
+ end
298
+ elsif spec_item[:type] == :integer
299
+ lambda do |value|
300
+ if spec_item[:min] && value < spec_item[:min]
301
+ abort "*** ERROR: you may only specify for #{spec_item[:cli]} " \
302
+ "a number greater than or equal to #{spec_item[:min]}"
303
+ end
304
+ options[spec_item[:name]] = value
305
+ end
306
+ elsif spec_item[:type] == :path
307
+ lambda do |value|
308
+ options[spec_item[:name]] = File.absolute_logical_path(value,
309
+ Dir.logical_pwd)
310
+ end
311
+ elsif spec_item[:type] == :boolean
312
+ lambda do |value|
313
+ options[spec_item[:name]] = true
314
+ end
315
+ else
316
+ lambda do |value|
317
+ options[spec_item[:name]] = value
104
318
  end
105
319
  end
106
320
  end
@@ -39,34 +39,15 @@ PhusionPassenger.require_passenger_lib 'platform_info/ruby'
39
39
  # We lazy load as many libraries as possible not only to improve startup performance,
40
40
  # but also to ensure that we don't require libraries before we've passed the dependency
41
41
  # checking stage of the runtime installer.
42
- #
43
- # ### Path handling
44
- #
45
- # Handle paths as follows so that the behavior complies with the documentation:
46
- # - Immediately absolutize all paths in the option parser, so that relative paths passed
47
- # through the command line are relative to the current working directory.
48
- # - Add the path's option key to ConfigUtils#resolve_config_file_paths so that relative
49
- # paths in Passengerfile.json are absolutized relative to Passengerfile.json.
50
42
 
51
43
  module PhusionPassenger
52
44
  module Standalone
53
45
 
54
46
  class StartCommand < Command
55
- DEFAULT_OPTIONS = {
56
- :environment => ENV['RAILS_ENV'] || ENV['RACK_ENV'] || ENV['NODE_ENV'] ||
57
- ENV['PASSENGER_APP_ENV'] || 'development',
58
- :spawn_method => Kernel.respond_to?(:fork) ? DEFAULT_SPAWN_METHOD : 'direct',
59
- :engine => "nginx",
60
- :nginx_version => PREFERRED_NGINX_VERSION,
61
- :log_level => DEFAULT_LOG_LEVEL,
62
- :auto => !STDIN.tty? || !STDOUT.tty?,
63
- :ctls => [],
64
- :envvars => {}
65
- }.freeze
66
-
67
47
  def run
68
48
  parse_options
69
49
  load_local_config_file
50
+ load_env_config
70
51
  remerge_all_options
71
52
  sanity_check_options_and_set_defaults
72
53
 
@@ -111,9 +92,6 @@ module PhusionPassenger
111
92
  ################# Configuration loading, option parsing and initialization ###################
112
93
 
113
94
  def self.create_option_parser(options)
114
- # Clear @parsed_options so that #remerge_all_options works.
115
- options.clear
116
-
117
95
  logical_pwd = Dir.logical_pwd
118
96
 
119
97
  # If you add or change an option, make sure to update the following places too:
@@ -121,312 +99,63 @@ module PhusionPassenger
121
99
  # function #build_daemon_controller_options
122
100
  # - resources/templates/config/standalone.erb
123
101
  OptionParser.new do |opts|
102
+ defaults = CONFIG_DEFAULTS
124
103
  nl = "\n" + ' ' * 37
125
104
  opts.banner = "Usage: passenger start [DIRECTORY] [OPTIONS]\n"
126
105
  opts.separator "Starts #{PROGRAM_NAME} Standalone and serve one or more web applications."
127
106
  opts.separator ""
128
107
 
129
108
  opts.separator "Server options:"
130
- opts.on("-a", "--address HOST", String, "Bind to the given address.#{nl}" +
131
- "Default: 0.0.0.0") do |value|
132
- options[:address] = value
133
- end
134
- opts.on("-p", "--port NUMBER", Integer,
135
- "Use the given port number. Default: 3000") do |value|
136
- options[:port] = value
137
- end
138
- opts.on("-S", "--socket FILE", String,
139
- "Bind to Unix domain socket instead of TCP#{nl}" +
140
- "socket") do |value|
141
- options[:socket_file] = File.absolute_logical_path(value, logical_pwd)
142
- end
143
- opts.on("--ssl", "Enable SSL support (Nginx#{nl}" +
144
- "engine only)") do
145
- options[:ssl] = true
146
- end
147
- opts.on("--ssl-certificate PATH", String,
148
- "Specify the SSL certificate path#{nl}" +
149
- "(Nginx engine only)") do |value|
150
- options[:ssl_certificate] = File.absolute_logical_path(value, logical_pwd)
151
- end
152
- opts.on("--ssl-certificate-key PATH", String,
153
- "Specify the SSL key path") do |value|
154
- options[:ssl_certificate_key] = File.absolute_logical_path(value, logical_pwd)
155
- end
156
- opts.on("--ssl-port PORT", Integer,
157
- "Listen for SSL on this port, while#{nl}" +
158
- "listening for HTTP on the normal port#{nl}" +
159
- "(Nginx engine only)") do |value|
160
- options[:ssl_port] = value
161
- end
162
- opts.on("-d", "--daemonize", "Daemonize into the background") do
163
- options[:daemonize] = true
164
- end
165
- opts.on("--user USERNAME", String, "User to run as. Ignored unless#{nl}" +
166
- "running as root") do |value|
167
- options[:user] = value
168
- end
169
- opts.on("--log-file FILENAME", String,
170
- "Where to write log messages. Default:#{nl}" +
171
- "console, or /dev/null when daemonized") do |value|
172
- options[:log_file] = File.absolute_logical_path(value, logical_pwd)
173
- end
174
- opts.on("--pid-file FILENAME", String, "Where to store the PID file") do |value|
175
- options[:pid_file] = File.absolute_logical_path(value, logical_pwd)
176
- end
177
- opts.on("--instance-registry-dir PATH", String,
178
- "Use the given instance registry directory") do |value|
179
- options[:instance_registry_dir] = File.absolute_logical_path(value, logical_pwd)
180
- end
181
- opts.on("--data-buffer-dir PATH", String,
182
- "Use the given data buffer directory") do |value|
183
- options[:data_buffer_dir] = File.absolute_logical_path(value, logical_pwd)
184
- end
109
+ ConfigUtils.add_option_parser_options_from_config_spec(opts,
110
+ SERVER_CONFIG_SPEC, options)
185
111
 
186
112
  opts.separator ""
187
113
  opts.separator "Application loading options:"
188
- opts.on("-e", "--environment ENV", String,
189
- "Framework environment.#{nl}" +
190
- "Default: #{DEFAULT_OPTIONS[:environment]}") do |value|
191
- options[:environment] = value
192
- end
193
- opts.on("--ruby FILENAME", String, "Executable to use for Ruby apps#{nl}" +
194
- "Default: " + PlatformInfo.ruby_command + " (current context)") do |value|
195
- options[:ruby] = value
196
- end
197
- opts.on("--nodejs FILENAME", String, "Executable to use for NodeJs apps") do |value|
198
- options[:nodejs] = value
199
- end
200
- opts.on("--python FILENAME", String, "Executable to use for Python apps") do |value|
201
- options[:python] = value
202
- end
203
- opts.on("--meteor-app-settings FILENAME", String,
204
- "Settings file to use for (development mode) Meteor apps") do |value|
205
- options[:meteor_app_settings] = File.absolute_logical_path(value, logical_pwd)
206
- end
207
- opts.on("-R", "--rackup FILE", String,
208
- "Consider application a Ruby app, and use#{nl}" +
209
- "the given rackup file") do |value|
210
- options[:app_type] = "rack"
211
- options[:startup_file] = File.absolute_logical_path(value, logical_pwd)
212
- end
213
- opts.on("--app-type NAME", String,
214
- "Force app to be detected as the given type") do |value|
215
- options[:app_type] = value
216
- end
217
- opts.on("--startup-file FILENAME", String,
218
- "Force given startup file to be used") do |value|
219
- options[:startup_file] = File.absolute_logical_path(value, logical_pwd)
220
- end
221
- opts.on("--spawn-method NAME", String,
222
- "The spawn method to use. Default: #{DEFAULT_OPTIONS[:spawn_method]}") do |value|
223
- options[:spawn_method] = value
224
- end
225
- opts.on("--static-files-dir PATH", String,
226
- "Specify the static files dir (Nginx engine#{nl}" +
227
- "only)") do |value|
228
- options[:static_files_dir] = File.absolute_logical_path(value, logical_pwd)
229
- end
230
- opts.on("--restart-dir PATH", String, "Specify the restart dir") do |value|
231
- options[:restart_dir] = File.absolute_logical_path(value, logical_pwd)
232
- end
233
- opts.on("--friendly-error-pages", "Turn on friendly error pages") do
234
- options[:friendly_error_pages] = true
235
- end
236
- opts.on("--no-friendly-error-pages", "Turn off friendly error pages") do
237
- options[:friendly_error_pages] = false
238
- end
239
- opts.on("--load-shell-envvars",
240
- "Load shell startup files before loading#{nl}" +
241
- "application") do
242
- options[:load_shell_envvars] = true
243
- end
244
- opts.on("--debugger", "Enable debugger support") do
245
- options[:debugger] = true
246
- end
114
+ ConfigUtils.add_option_parser_options_from_config_spec(opts,
115
+ APPLICATION_LOADING_CONFIG_SPECS, options)
247
116
 
248
117
  opts.separator ""
249
118
  opts.separator "Process management options:"
250
- opts.on("--max-pool-size NUMBER", Integer,
251
- "Maximum number of application processes.#{nl}" +
252
- "Default: #{DEFAULT_MAX_POOL_SIZE}") do |value|
253
- if value < 1
254
- abort "*** ERROR: you may only specify for --max-pool-size a number greater than or equal to 1"
255
- end
256
- options[:max_pool_size] = value
257
- end
258
- opts.on("--min-instances NUMBER", Integer,
259
- "Minimum number of processes per#{nl}" +
260
- "application. Default: 1") do |value|
261
- options[:min_instances] = value
262
- end
263
- opts.on("--pool-idle-time SECONDS", Integer,
264
- "Maximum time that processes may be idle.#{nl}" +
265
- "Default: #{DEFAULT_POOL_IDLE_TIME}") do |value|
266
- options[:pool_idle_time] = value
267
- end
268
- opts.on("--max-preloader-idle-time SECONDS", Integer,
269
- "Maximum time that preloader processes may#{nl}" +
270
- "be idle. A value of 0 means that preloader#{nl}" +
271
- "processes never timeout. Default: #{DEFAULT_MAX_PRELOADER_IDLE_TIME}") do |value|
272
- options[:max_preloader_idle_time] = value
273
- end
274
- opts.on("--concurrency-model NAME", String,
275
- "The concurrency model to use, either#{nl}" +
276
- "'process' or 'thread' (Enterprise only).#{nl}" +
277
- "Default: #{DEFAULT_CONCURRENCY_MODEL}") do |value|
278
- options[:concurrency_model] = value
279
- end
280
- opts.on("--thread-count NAME", Integer,
281
- "The number of threads to use when using#{nl}" +
282
- "the 'thread' concurrency model (Enterprise#{nl}" +
283
- "only). Default: #{DEFAULT_APP_THREAD_COUNT}") do |value|
284
- options[:thread_count] = value
285
- end
286
- opts.on("--rolling-restarts", "Enable rolling restarts (Enterprise only)") do
287
- options[:rolling_restarts] = true
288
- end
289
- opts.on("--resist-deployment-errors", "Enable deployment error resistance#{nl}" +
290
- "(Enterprise only)") do
291
- options[:resist_deployment_errors] = true
292
- end
119
+ ConfigUtils.add_option_parser_options_from_config_spec(opts,
120
+ PROCESS_MANAGEMENT_CONFIG_SPECS, options)
293
121
 
294
122
  opts.separator ""
295
123
  opts.separator "Request handling options:"
296
- opts.on("--max-request-time SECONDS", "Abort requests that take too much time#{nl}" +
297
- "(Enterprise only)") do |val|
298
- options[:max_request_time] = val
299
- end
300
- opts.on("--sticky-sessions", "Enable sticky sessions") do
301
- options[:sticky_sessions] = true
302
- end
303
- opts.on("--sticky-sessions-cookie-name NAME", String,
304
- "Cookie name to use for sticky sessions.#{nl}" +
305
- "Default: #{DEFAULT_STICKY_SESSIONS_COOKIE_NAME}") do |value|
306
- options[:sticky_sessions_cookie_name] = value
307
- end
308
- opts.on("--vary-turbocache-by-cookie NAME", String,
309
- "Vary the turbocache by the cookie of the#{nl}" +
310
- "given name") do |value|
311
- options[:vary_turbocache_by_cookie] = value
312
- end
313
- opts.on("--disable-turbocaching", "Disable turbocaching") do
314
- options[:turbocaching] = false
315
- end
124
+ ConfigUtils.add_option_parser_options_from_config_spec(opts,
125
+ REQUEST_HANDLING_CONFIG_SPECS, options)
316
126
 
317
127
  opts.separator ""
318
128
  opts.separator "Union Station options:"
319
- opts.on("--union-station-gateway HOST:PORT", String,
320
- "Specify Union Station Gateway host and port") do |value|
321
- host, port = value.split(":", 2)
322
- port = port.to_i
323
- port = 443 if port == 0
324
- options[:union_station_gateway_address] = host
325
- options[:union_station_gateway_port] = port.to_i
326
- end
327
- opts.on("--union-station-key KEY", String, "Specify Union Station key") do |value|
328
- options[:union_station_key] = value
329
- end
129
+ ConfigUtils.add_option_parser_options_from_config_spec(opts,
130
+ UNION_STATION_CONFIG_SPECS, options)
330
131
 
331
132
  opts.separator ""
332
133
  opts.separator "Nginx engine options:"
333
- opts.on("--nginx-bin FILENAME", String, "Nginx binary to use as core") do |value|
334
- options[:nginx_bin] = File.absolute_logical_path(value, logical_pwd)
335
- end
336
- opts.on("--nginx-version VERSION", String,
337
- "Nginx version to use as core.#{nl}" +
338
- "Default: #{PREFERRED_NGINX_VERSION}") do |value|
339
- options[:nginx_version] = value
340
- end
341
- opts.on("--nginx-tarball FILENAME", String,
342
- "If Nginx needs to be installed, then the#{nl}" +
343
- "given tarball will be used instead of#{nl}" +
344
- "downloading from the Internet") do |value|
345
- options[:nginx_tarball] = File.absolute_logical_path(value, logical_pwd)
346
- end
347
- opts.on("--nginx-config-template FILENAME", String,
348
- "The template to use for generating the#{nl}" +
349
- "Nginx config file") do |value|
350
- options[:nginx_config_template] = File.absolute_logical_path(value, logical_pwd)
351
- end
134
+ ConfigUtils.add_option_parser_options_from_config_spec(opts,
135
+ NGINX_ENGINE_CONFIG_SPECS, options)
352
136
 
353
137
  opts.separator ""
354
138
  opts.separator "Advanced options:"
355
- opts.on("--engine NAME", String,
356
- "Underlying HTTP engine to use. Available#{nl}" +
357
- "options: nginx (default), builtin") do |value|
358
- options[:engine] = value
359
- end
360
- opts.on("--log-level NUMBER", Integer, "Log level to use. Default: #{DEFAULT_LOG_LEVEL}") do |value|
361
- options[:log_level] = value
362
- end
363
- opts.on("--auto", "Run in non-interactive mode. Default when#{nl}" +
364
- "stdin or stdout is not a TTY") do
365
- options[:auto] = true
366
- end
367
- opts.on("--ctl NAME=VALUE", String) do |value|
368
- if value !~ /=.+/
369
- abort "*** ERROR: invalid --ctl format: #{value}"
370
- end
371
- options[:ctls] ||= []
372
- options[:ctls] << value
373
- end
374
- opts.on("--binaries-url-root URL", String,
375
- "If Nginx needs to be installed, then the#{nl}" +
376
- "specified URL will be checked for binaries#{nl}" +
377
- "prior to a local build") do |value|
378
- options[:binaries_url_root] = value
379
- end
380
- opts.on("--no-download-binaries", "Never download binaries") do
381
- options[:download_binaries] = false
382
- end
383
- opts.on("--runtime-check-only",
384
- "Quit after checking whether the#{nl}" +
385
- "#{PROGRAM_NAME} Standalone runtime files#{nl}" +
386
- "are installed") do
387
- options[:runtime_check_only] = true
388
- end
389
- opts.on("--no-install-runtime", "Abort if runtime must be installed") do
390
- options[:dont_install_runtime] = true
391
- end
392
- opts.on("--no-compile-runtime", "Abort if runtime must be compiled") do
393
- options[:dont_compile_runtime] = true
394
- end
139
+ ConfigUtils.add_option_parser_options_from_config_spec(opts,
140
+ ADVANCED_CONFIG_SPECS, options)
395
141
  end
396
142
  end
397
143
 
398
144
  def load_local_config_file
399
- if @argv.empty?
400
- app_dir = Dir.logical_pwd
401
- elsif @argv.size == 1
402
- app_dir = @argv[0]
403
- end
404
- @local_options = {}
405
- if app_dir
406
- begin
407
- ConfigUtils.load_local_config_file!(app_dir, @local_options)
408
- rescue ConfigUtils::ConfigLoadError => e
409
- abort "*** ERROR: #{e.message}"
410
- end
411
- end
145
+ @local_options = ConfigUtils.
146
+ load_local_config_file_from_app_dir_param!(@argv)
147
+ end
148
+
149
+ def load_env_config
150
+ @env_options = ConfigUtils.load_env_config!
412
151
  end
413
152
 
414
- # We want the command line options to override the options in the local config
415
- # file, but the local config file could only be parsed when the command line
416
- # options have been parsed. In this method we remerge all the config options
417
- # from different sources so that options are overriden according to the following
418
- # order:
419
- #
420
- # - DEFAULT_OPTIONS
421
- # - global config file
422
- # - local config file
423
- # - command line options
424
153
  def remerge_all_options
425
- @options = DEFAULT_OPTIONS.
426
- merge(@global_options).
427
- merge(@local_options).
428
- merge(@parsed_options)
429
- @options.delete(:config_filename)
154
+ @options = ConfigUtils.remerge_all_config(@global_options,
155
+ @local_options, @env_options, @parsed_options)
156
+ @options_without_defaults = ConfigUtils.
157
+ remerge_all_config_without_defaults(@global_options,
158
+ @local_options, @env_options, @parsed_options)
430
159
  end
431
160
 
432
161
  def sanity_check_options_and_set_defaults
@@ -437,7 +166,8 @@ module PhusionPassenger
437
166
  end
438
167
  end
439
168
 
440
- if (@options[:address] || @options[:port]) && @options[:socket_file]
169
+ if (@options_without_defaults[:address] || @options_without_defaults[:port]) &&
170
+ @options_without_defaults[:socket_file]
441
171
  abort "You cannot specify both --address/--port and --socket. Please choose either one."
442
172
  end
443
173
  if @options[:ssl] && !@options[:ssl_certificate]
@@ -450,11 +180,6 @@ module PhusionPassenger
450
180
  abort "You've specified an invalid value for --engine. The only values allowed are: builtin, nginx."
451
181
  end
452
182
 
453
- if !@options[:socket_file]
454
- @options[:address] ||= "0.0.0.0"
455
- @options[:port] ||= 3000
456
- end
457
-
458
183
  if @options[:engine] == "builtin"
459
184
  # We explicitly check that some options are set and warn the user about this,
460
185
  # in case they are using the builtin engine. We don't warn about options
@@ -563,24 +288,7 @@ module PhusionPassenger
563
288
  end
564
289
 
565
290
  def find_pid_and_log_file(app_finder, options)
566
- exec_root = app_finder.execution_root
567
- if options[:socket_file]
568
- pid_basename = "passenger.pid"
569
- log_basename = "passenger.log"
570
- else
571
- pid_basename = "passenger.#{options[:port]}.pid"
572
- log_basename = "passenger.#{options[:port]}.log"
573
- end
574
- if File.directory?("#{exec_root}/tmp/pids")
575
- options[:pid_file] ||= "#{exec_root}/tmp/pids/#{pid_basename}"
576
- else
577
- options[:pid_file] ||= "#{exec_root}/#{pid_basename}"
578
- end
579
- if File.directory?("log")
580
- options[:log_file] ||= "#{exec_root}/log/#{log_basename}"
581
- else
582
- options[:log_file] ||= "#{exec_root}/#{log_basename}"
583
- end
291
+ ConfigUtils.find_pid_and_log_file(app_finder.execution_root, options)
584
292
  end
585
293
 
586
294
  def create_working_dir
@@ -716,7 +424,11 @@ module PhusionPassenger
716
424
  backward = 10
717
425
  end
718
426
 
719
- IO.popen("tail -f -n #{backward} \"#{log_file}\"", "rb") do |f|
427
+ if PlatformInfo.os_name != 'solaris'
428
+ backward_arg = "-n #{backward}"
429
+ end
430
+
431
+ IO.popen("tail -f #{backward_arg} \"#{log_file}\"", "rb") do |f|
720
432
  begin
721
433
  while true
722
434
  begin