passenger 5.3.1 → 5.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +19 -0
  3. data/build/cxx_tests.rb +3 -1
  4. data/build/support/cxx_dependency_map.rb +120 -27
  5. data/dev/configkit-schemas/index.json +15 -3
  6. data/src/agent/Core/AdminPanelConnector.h +5 -2
  7. data/src/agent/Core/ApplicationPool/Group/StateInspection.cpp +2 -0
  8. data/src/agent/Core/Config.h +2 -1
  9. data/src/agent/Core/Controller/Config.h +6 -1
  10. data/src/agent/Core/Controller/InitRequest.cpp +6 -1
  11. data/src/agent/Core/CoreMain.cpp +26 -60
  12. data/src/agent/Core/SpawningKit/DirectSpawner.h +18 -6
  13. data/src/agent/Core/SpawningKit/ErrorRenderer.h +8 -8
  14. data/src/agent/Core/SpawningKit/Handshake/Perform.h +217 -61
  15. data/src/agent/Core/SpawningKit/Handshake/Prepare.h +57 -8
  16. data/src/agent/Core/SpawningKit/Handshake/Session.h +34 -1
  17. data/src/agent/Core/SpawningKit/Handshake/WorkDir.h +20 -4
  18. data/src/agent/Core/SpawningKit/SmartSpawner.h +90 -27
  19. data/src/agent/ExecHelper/ExecHelperMain.cpp +3 -0
  20. data/src/agent/Shared/ApiAccountUtils.h +2 -2
  21. data/src/agent/SpawnEnvSetupper/SpawnEnvSetupperMain.cpp +14 -4
  22. data/src/agent/Watchdog/Config.h +2 -1
  23. data/src/agent/Watchdog/WatchdogMain.cpp +38 -0
  24. data/src/apache2_module/Hooks.cpp +1 -0
  25. data/src/cxx_supportlib/ConfigKit/IN_PRACTICE.md +1 -1
  26. data/src/cxx_supportlib/ConfigKit/README.md +1 -1
  27. data/src/cxx_supportlib/Constants.h +6 -1
  28. data/src/cxx_supportlib/FileTools/FileManip.cpp +34 -2
  29. data/src/cxx_supportlib/FileTools/FileManip.h +58 -1
  30. data/src/cxx_supportlib/FileTools/PathManip.cpp +3 -2
  31. data/src/cxx_supportlib/FileTools/PathSecurityCheck.cpp +99 -0
  32. data/src/cxx_supportlib/FileTools/PathSecurityCheck.h +69 -0
  33. data/src/cxx_supportlib/Utils.cpp +37 -6
  34. data/src/cxx_supportlib/Utils.h +6 -0
  35. data/src/cxx_supportlib/Utils/AsyncSignalSafeUtils.h +14 -0
  36. data/src/cxx_supportlib/Utils/IOUtils.cpp +10 -18
  37. data/src/cxx_supportlib/Utils/IOUtils.h +10 -9
  38. data/src/cxx_supportlib/Utils/JsonUtils.h +12 -8
  39. data/src/cxx_supportlib/Utils/SystemMetricsCollector.h +4 -4
  40. data/src/cxx_supportlib/Utils/SystemTime.h +1 -1
  41. data/src/cxx_supportlib/WebSocketCommandReverseServer.h +3 -3
  42. data/src/cxx_supportlib/oxt/system_calls.cpp +25 -1
  43. data/src/cxx_supportlib/oxt/system_calls.hpp +3 -1
  44. data/src/helper-scripts/meteor-loader.rb +115 -28
  45. data/src/helper-scripts/rack-preloader.rb +1 -1
  46. data/src/nginx_module/ConfigGeneral/AutoGeneratedDefinitions.c +4 -4
  47. data/src/nginx_module/ConfigGeneral/AutoGeneratedSetterFuncs.c +4 -4
  48. data/src/nginx_module/LocationConfig/AutoGeneratedCreateFunction.c +0 -10
  49. data/src/nginx_module/LocationConfig/AutoGeneratedHeaderSerialization.c +0 -42
  50. data/src/nginx_module/LocationConfig/AutoGeneratedMergeFunction.c +0 -6
  51. data/src/nginx_module/LocationConfig/AutoGeneratedStruct.h +0 -8
  52. data/src/nginx_module/MainConfig/AutoGeneratedCreateFunction.c +10 -0
  53. data/src/nginx_module/MainConfig/AutoGeneratedManifestGeneration.c +22 -0
  54. data/src/nginx_module/MainConfig/AutoGeneratedStruct.h +8 -0
  55. data/src/nginx_module/ngx_http_passenger_module.c +6 -5
  56. data/src/ruby_supportlib/phusion_passenger.rb +1 -1
  57. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +0 -1
  58. data/src/ruby_supportlib/phusion_passenger/common_library.rb +3 -0
  59. data/src/ruby_supportlib/phusion_passenger/config/installation_utils.rb +3 -3
  60. data/src/ruby_supportlib/phusion_passenger/constants.rb +5 -0
  61. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +4 -2
  62. data/src/ruby_supportlib/phusion_passenger/platform_info.rb +3 -3
  63. data/src/ruby_supportlib/phusion_passenger/request_handler.rb +1 -1
  64. data/src/ruby_supportlib/phusion_passenger/vendor/daemon_controller.rb +1 -1
  65. metadata +4 -2
@@ -31,35 +31,92 @@ require 'logger'
31
31
  module PhusionPassenger
32
32
  module App
33
33
  def self.options
34
+ @@options ||= {}
34
35
  return @@options
35
36
  end
36
37
 
37
- def self.exit_code_for_exception(e)
38
- if e.is_a?(SystemExit)
39
- return e.status
40
- else
41
- return 1
38
+ def self.try_write_file(path, contents)
39
+ begin
40
+ File.open(path, 'wb') do |f|
41
+ f.write(contents)
42
+ end
43
+ rescue SystemCallError => e
44
+ STDERR.puts "Warning: unable to write to #{path}: #{e}"
42
45
  end
43
46
  end
44
47
 
45
- def self.handshake_and_read_startup_request
46
- STDOUT.sync = true
47
- STDERR.sync = true
48
- puts "!> I have control 1.0"
49
- abort "Invalid initialization header" if STDIN.readline != "You have control 1.0\n"
48
+ def self.record_journey_step_begin(step, state, work_dir = nil)
49
+ dir = work_dir || ENV['PASSENGER_SPAWN_WORK_DIR']
50
+ step_dir = "#{dir}/response/steps/#{step.downcase}"
51
+ try_write_file("#{step_dir}/state", state)
52
+ try_write_file("#{step_dir}/begin_time", Time.now.to_f)
53
+ end
50
54
 
51
- @@options = {}
52
- while (line = STDIN.readline) != "\n"
53
- name, value = line.strip.split(/: */, 2)
54
- @@options[name] = value
55
+ def self.record_journey_step_end(step, state, work_dir = nil)
56
+ dir = work_dir || ENV['PASSENGER_SPAWN_WORK_DIR']
57
+ step_dir = "#{dir}/response/steps/#{step.downcase}"
58
+ try_write_file("#{step_dir}/state", state)
59
+ if !File.exist?("#{step_dir}/begin_time") && !File.exist?("#{step_dir}/begin_time_monotonic")
60
+ try_write_file("#{step_dir}/begin_time", Time.now.to_f)
55
61
  end
62
+ try_write_file("#{step_dir}/end_time", Time.now.to_f)
63
+ end
64
+
65
+ def self.init_logging
66
+ logger = Logger.new(STDOUT)
67
+ logger.level = Logger::WARN
68
+ logger.formatter = proc do |severity, datetime, progname, msg|
69
+ "[ pid=#{Process.pid}, time=#{datetime} ]: #{msg.message}"
70
+ end
71
+ end
72
+
73
+ def self.read_startup_arguments
74
+ work_dir = ENV['PASSENGER_SPAWN_WORK_DIR']
75
+ @@options = File.open("#{work_dir}/args.json", 'rb') do |f|
76
+ Utils::JSON.parse(f.read)
77
+ end
78
+ end
79
+
80
+ def self.advertise_port(port)
81
+ work_dir = ENV['PASSENGER_SPAWN_WORK_DIR']
82
+ path = work_dir + '/response/properties.json'
83
+ doc = {
84
+ 'sockets': [{
85
+ 'name': 'main',
86
+ 'address': "tcp://127.0.0.1:#{port}",
87
+ 'protocol': 'http',
88
+ 'concurrency': 0,
89
+ 'accept_http_requests': true
90
+ }]
91
+ }
92
+ File.write(path, Utils::JSON.generate(doc))
93
+ end
94
+
95
+ def self.advertise_readiness
96
+ work_dir = ENV['PASSENGER_SPAWN_WORK_DIR']
97
+ path = work_dir + '/response/finish'
98
+ File.write(path, '1')
56
99
  end
57
100
 
58
101
  def self.init_passenger
59
- require "#{options["ruby_libdir"]}/phusion_passenger"
60
- PhusionPassenger.locate_directories(options["passenger_root"])
61
- PhusionPassenger.require_passenger_lib 'message_channel'
62
- PhusionPassenger.require_passenger_lib 'utils/tmpio'
102
+ STDOUT.sync = true
103
+ STDERR.sync = true
104
+
105
+ work_dir = ENV['PASSENGER_SPAWN_WORK_DIR'].to_s
106
+ if work_dir.empty?
107
+ abort "This program may only be invoked from Passenger (error: $PASSENGER_SPAWN_WORK_DIR not set)."
108
+ end
109
+
110
+ ruby_libdir = File.read("#{work_dir}/args/ruby_libdir").strip
111
+ passenger_root = File.read("#{work_dir}/args/passenger_root").strip
112
+ require "#{ruby_libdir}/phusion_passenger"
113
+ PhusionPassenger.locate_directories(passenger_root)
114
+
115
+ PhusionPassenger.require_passenger_lib 'loader_shared_helpers'
116
+ PhusionPassenger.require_passenger_lib 'preloader_shared_helpers'
117
+ PhusionPassenger.require_passenger_lib 'utils/json'
118
+ require 'socket'
119
+
63
120
  end
64
121
 
65
122
  def self.ping_port(port)
@@ -111,15 +168,15 @@ module PhusionPassenger
111
168
  # Meteor its own process group, and sending signals to the
112
169
  # entire process group.
113
170
  Process.setpgrp
114
-
171
+
115
172
  if options["environment"] == "production"
116
- puts("Warning: meteor running in simulated production mode (--production). For real production use, bundle your app.")
173
+ logger.warn("Warning: meteor running in simulated production mode (--production). For real production use, bundle your app.")
117
174
  end
118
-
175
+
119
176
  if options["meteor_app_settings"]
120
177
  PhusionPassenger.require_passenger_lib 'utils/shellwords'
121
178
  app_settings_file = Shellwords.escape(options["meteor_app_settings"])
122
- puts("Using application settings from file #{app_settings_file}")
179
+ logger.info("Using application settings from file #{app_settings_file}")
123
180
  exec("meteor run -p #{port} --settings #{app_settings_file} #{production}")
124
181
  else
125
182
  exec("meteor run -p #{port} #{production}")
@@ -142,17 +199,47 @@ module PhusionPassenger
142
199
  ################## Main code ##################
143
200
 
144
201
 
145
- handshake_and_read_startup_request
146
202
  init_passenger
203
+ init_logging
204
+
205
+ record_journey_step_end('SUBPROCESS_EXEC_WRAPPER', 'STEP_PERFORMED')
206
+
207
+ record_journey_step_begin('SUBPROCESS_WRAPPER_PREPARATION', 'STEP_IN_PROGRESS')
147
208
  begin
148
- pid, port = load_app
209
+ read_startup_arguments
210
+ rescue Exception
211
+ record_journey_step_end('SUBPROCESS_WRAPPER_PREPARATION', 'STEP_ERRORED')
212
+ raise
213
+ else
214
+ record_journey_step_end('SUBPROCESS_WRAPPER_PREPARATION', 'STEP_PERFORMED')
215
+ end
216
+
217
+ record_journey_step_begin('SUBPROCESS_APP_LOAD_OR_EXEC', 'STEP_IN_PROGRESS')
218
+ begin
219
+ pid, port = load_app
220
+ rescue Exception
221
+ record_journey_step_end('SUBPROCESS_APP_LOAD_OR_EXEC', 'STEP_ERRORED')
222
+ raise
223
+ else
224
+ record_journey_step_end('SUBPROCESS_APP_LOAD_OR_EXEC', 'STEP_PERFORMED')
225
+ end
226
+
227
+ record_journey_step_begin('SUBPROCESS_LISTEN', 'STEP_IN_PROGRESS')
228
+ begin
149
229
  while !ping_port(port)
150
230
  sleep 0.01
151
231
  end
152
- puts "!> Ready"
153
- puts "!> socket: main;tcp://127.0.0.1:#{port};http_session;0"
154
- puts "!> "
155
- wait_for_exit_message
232
+ rescue Exception
233
+ record_journey_step_end('SUBPROCESS_LISTEN', 'STEP_ERRORED')
234
+ raise
235
+ else
236
+ record_journey_step_end('SUBPROCESS_LISTEN', 'STEP_PERFORMED')
237
+ end
238
+
239
+ advertise_port(port)
240
+ advertise_readiness
241
+ begin
242
+ wait_for_exit_message
156
243
  ensure
157
244
  if pid
158
245
  Process.kill('INT', -pid) rescue nil
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: binary
3
3
  # Phusion Passenger - https://www.phusionpassenger.com/
4
- # Copyright (c) 2013-2017 Phusion Holding B.V.
4
+ # Copyright (c) 2013-2018 Phusion Holding B.V.
5
5
  #
6
6
  # "Passenger", "Phusion Passenger" and "Union Station" are registered
7
7
  # trademarks of Phusion Holding B.V.
@@ -226,16 +226,16 @@
226
226
  ngx_string("passenger_app_file_descriptor_ulimit"),
227
227
  NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
228
228
  passenger_conf_set_app_file_descriptor_ulimit,
229
- NGX_HTTP_LOC_CONF_OFFSET,
230
- offsetof(passenger_loc_conf_t, autogenerated.app_file_descriptor_ulimit),
229
+ NGX_HTTP_MAIN_CONF_OFFSET,
230
+ offsetof(passenger_main_conf_t, autogenerated.app_file_descriptor_ulimit),
231
231
  NULL
232
232
  },
233
233
  {
234
234
  ngx_string("passenger_max_instances_per_app"),
235
235
  NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
236
236
  passenger_conf_set_max_instances_per_app,
237
- NGX_HTTP_LOC_CONF_OFFSET,
238
- offsetof(passenger_loc_conf_t, autogenerated.max_instances_per_app),
237
+ NGX_HTTP_MAIN_CONF_OFFSET,
238
+ offsetof(passenger_main_conf_t, autogenerated.max_instances_per_app),
239
239
  NULL
240
240
  },
241
241
  {
@@ -351,10 +351,10 @@ passenger_conf_set_show_version_in_header(ngx_conf_t *cf, ngx_command_t *cmd, vo
351
351
 
352
352
  static char *
353
353
  passenger_conf_set_app_file_descriptor_ulimit(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
354
- passenger_loc_conf_t *passenger_conf = conf;
354
+ passenger_main_conf_t *passenger_conf = conf;
355
355
 
356
356
  passenger_conf->autogenerated.app_file_descriptor_ulimit_explicitly_set = 1;
357
- record_loc_conf_source_location(cf, passenger_conf,
357
+ record_main_conf_source_location(cf,
358
358
  &passenger_conf->autogenerated.app_file_descriptor_ulimit_source_file,
359
359
  &passenger_conf->autogenerated.app_file_descriptor_ulimit_source_line);
360
360
 
@@ -363,10 +363,10 @@ passenger_conf_set_app_file_descriptor_ulimit(ngx_conf_t *cf, ngx_command_t *cmd
363
363
 
364
364
  static char *
365
365
  passenger_conf_set_max_instances_per_app(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
366
- passenger_loc_conf_t *passenger_conf = conf;
366
+ passenger_main_conf_t *passenger_conf = conf;
367
367
 
368
368
  passenger_conf->autogenerated.max_instances_per_app_explicitly_set = 1;
369
- record_loc_conf_source_location(cf, passenger_conf,
369
+ record_main_conf_source_location(cf,
370
370
  &passenger_conf->autogenerated.max_instances_per_app_source_file,
371
371
  &passenger_conf->autogenerated.max_instances_per_app_source_line);
372
372
 
@@ -40,8 +40,6 @@
40
40
 
41
41
  static void
42
42
  passenger_create_autogenerated_loc_conf(passenger_autogenerated_loc_conf_t *conf) {
43
- conf->app_file_descriptor_ulimit = NGX_CONF_UNSET_UINT;
44
- conf->max_instances_per_app = NGX_CONF_UNSET_UINT;
45
43
  conf->ruby.data = NULL;
46
44
  conf->ruby.len = 0;
47
45
  conf->python.data = NULL;
@@ -97,14 +95,6 @@ passenger_create_autogenerated_loc_conf(passenger_autogenerated_loc_conf_t *con
97
95
  conf->app_log_file.data = NULL;
98
96
  conf->app_log_file.len = 0;
99
97
 
100
- conf->app_file_descriptor_ulimit_source_file.data = NULL;
101
- conf->app_file_descriptor_ulimit_source_file.len = 0;
102
- conf->app_file_descriptor_ulimit_source_line = 0;
103
- conf->app_file_descriptor_ulimit_explicitly_set = 0;
104
- conf->max_instances_per_app_source_file.data = NULL;
105
- conf->max_instances_per_app_source_file.len = 0;
106
- conf->max_instances_per_app_source_line = 0;
107
- conf->max_instances_per_app_explicitly_set = 0;
108
98
  conf->ruby_source_file.data = NULL;
109
99
  conf->ruby_source_file.len = 0;
110
100
  conf->ruby_source_line = 0;
@@ -49,26 +49,6 @@ passenger_serialize_autogenerated_loc_conf_to_headers(ngx_conf_t *cf, passenger_
49
49
  * Calculate lengths
50
50
  */
51
51
 
52
- if (conf->autogenerated.app_file_descriptor_ulimit != NGX_CONF_UNSET_UINT) {
53
- end = ngx_snprintf(int_buf,
54
- sizeof(int_buf) - 1,
55
- "%ui",
56
- conf->autogenerated.app_file_descriptor_ulimit);
57
- len += sizeof("!~PASSENGER_APP_FILE_DESCRIPTOR_ULIMIT: ") - 1;
58
- len += end - int_buf;
59
- len += sizeof("\r\n") - 1;
60
- }
61
-
62
- if (conf->autogenerated.max_instances_per_app != NGX_CONF_UNSET_UINT) {
63
- end = ngx_snprintf(int_buf,
64
- sizeof(int_buf) - 1,
65
- "%ui",
66
- conf->autogenerated.max_instances_per_app);
67
- len += sizeof("!~PASSENGER_MAX_PROCESSES: ") - 1;
68
- len += end - int_buf;
69
- len += sizeof("\r\n") - 1;
70
- }
71
-
72
52
  if (conf->autogenerated.ruby.data != NULL) {
73
53
  len += sizeof("!~PASSENGER_RUBY: ") - 1;
74
54
  len += conf->autogenerated.ruby.len;
@@ -277,28 +257,6 @@ passenger_serialize_autogenerated_loc_conf_to_headers(ngx_conf_t *cf, passenger_
277
257
  return 0;
278
258
  }
279
259
 
280
- if (conf->autogenerated.app_file_descriptor_ulimit != NGX_CONF_UNSET_UINT) {
281
- pos = ngx_copy(pos,
282
- "!~PASSENGER_APP_FILE_DESCRIPTOR_ULIMIT: ",
283
- sizeof("!~PASSENGER_APP_FILE_DESCRIPTOR_ULIMIT: ") - 1);
284
- end = ngx_snprintf(int_buf,
285
- sizeof(int_buf) - 1,
286
- "%ui",
287
- conf->autogenerated.app_file_descriptor_ulimit);
288
- pos = ngx_copy(pos, int_buf, end - int_buf);
289
- pos = ngx_copy(pos, (const u_char *) "\r\n", sizeof("\r\n") - 1);
290
- }
291
- if (conf->autogenerated.max_instances_per_app != NGX_CONF_UNSET_UINT) {
292
- pos = ngx_copy(pos,
293
- "!~PASSENGER_MAX_PROCESSES: ",
294
- sizeof("!~PASSENGER_MAX_PROCESSES: ") - 1);
295
- end = ngx_snprintf(int_buf,
296
- sizeof(int_buf) - 1,
297
- "%ui",
298
- conf->autogenerated.max_instances_per_app);
299
- pos = ngx_copy(pos, int_buf, end - int_buf);
300
- pos = ngx_copy(pos, (const u_char *) "\r\n", sizeof("\r\n") - 1);
301
- }
302
260
  if (conf->autogenerated.ruby.data != NULL) {
303
261
  pos = ngx_copy(pos,
304
262
  "!~PASSENGER_RUBY: ",
@@ -43,12 +43,6 @@
43
43
  */
44
44
  static int
45
45
  passenger_merge_autogenerated_loc_conf(passenger_autogenerated_loc_conf_t *conf, passenger_autogenerated_loc_conf_t *prev, ngx_conf_t *cf) {
46
- ngx_conf_merge_uint_value(conf->app_file_descriptor_ulimit,
47
- prev->app_file_descriptor_ulimit,
48
- NGX_CONF_UNSET_UINT);
49
- ngx_conf_merge_uint_value(conf->max_instances_per_app,
50
- prev->max_instances_per_app,
51
- 0);
52
46
  ngx_conf_merge_str_value(conf->ruby,
53
47
  prev->ruby,
54
48
  "ruby");
@@ -40,7 +40,6 @@
40
40
 
41
41
  typedef struct {
42
42
  ngx_flag_t abort_websockets_on_process_shutdown;
43
- ngx_uint_t app_file_descriptor_ulimit;
44
43
  ngx_array_t *base_uris;
45
44
  ngx_flag_t debugger;
46
45
  ngx_flag_t enabled;
@@ -51,7 +50,6 @@ typedef struct {
51
50
  ngx_uint_t headers_hash_max_size;
52
51
  ngx_array_t *headers_source;
53
52
  ngx_flag_t load_shell_envvars;
54
- ngx_uint_t max_instances_per_app;
55
53
  ngx_int_t max_preloader_idle_time;
56
54
  ngx_uint_t max_request_queue_size;
57
55
  ngx_uint_t max_requests;
@@ -80,7 +78,6 @@ typedef struct {
80
78
  ngx_str_t vary_turbocache_by_cookie;
81
79
 
82
80
  ngx_str_t abort_websockets_on_process_shutdown_source_file;
83
- ngx_str_t app_file_descriptor_ulimit_source_file;
84
81
  ngx_str_t app_group_name_source_file;
85
82
  ngx_str_t app_log_file_source_file;
86
83
  ngx_str_t app_rights_source_file;
@@ -99,7 +96,6 @@ typedef struct {
99
96
  ngx_str_t headers_hash_max_size_source_file;
100
97
  ngx_str_t headers_source_source_file;
101
98
  ngx_str_t load_shell_envvars_source_file;
102
- ngx_str_t max_instances_per_app_source_file;
103
99
  ngx_str_t max_preloader_idle_time_source_file;
104
100
  ngx_str_t max_request_queue_size_source_file;
105
101
  ngx_str_t max_requests_source_file;
@@ -129,7 +125,6 @@ typedef struct {
129
125
  ngx_str_t vary_turbocache_by_cookie_source_file;
130
126
 
131
127
  ngx_uint_t abort_websockets_on_process_shutdown_source_line;
132
- ngx_uint_t app_file_descriptor_ulimit_source_line;
133
128
  ngx_uint_t app_group_name_source_line;
134
129
  ngx_uint_t app_log_file_source_line;
135
130
  ngx_uint_t app_rights_source_line;
@@ -148,7 +143,6 @@ typedef struct {
148
143
  ngx_uint_t headers_hash_max_size_source_line;
149
144
  ngx_uint_t headers_source_source_line;
150
145
  ngx_uint_t load_shell_envvars_source_line;
151
- ngx_uint_t max_instances_per_app_source_line;
152
146
  ngx_uint_t max_preloader_idle_time_source_line;
153
147
  ngx_uint_t max_request_queue_size_source_line;
154
148
  ngx_uint_t max_requests_source_line;
@@ -178,7 +172,6 @@ typedef struct {
178
172
  ngx_uint_t vary_turbocache_by_cookie_source_line;
179
173
 
180
174
  ngx_int_t abort_websockets_on_process_shutdown_explicitly_set;
181
- ngx_int_t app_file_descriptor_ulimit_explicitly_set;
182
175
  ngx_int_t app_group_name_explicitly_set;
183
176
  ngx_int_t app_log_file_explicitly_set;
184
177
  ngx_int_t app_rights_explicitly_set;
@@ -197,7 +190,6 @@ typedef struct {
197
190
  ngx_int_t headers_hash_max_size_explicitly_set;
198
191
  ngx_int_t headers_source_explicitly_set;
199
192
  ngx_int_t load_shell_envvars_explicitly_set;
200
- ngx_int_t max_instances_per_app_explicitly_set;
201
193
  ngx_int_t max_preloader_idle_time_explicitly_set;
202
194
  ngx_int_t max_request_queue_size_explicitly_set;
203
195
  ngx_int_t max_requests_explicitly_set;
@@ -72,6 +72,8 @@ passenger_create_autogenerated_main_conf(passenger_autogenerated_main_conf_t *co
72
72
  conf->response_buffer_high_watermark = NGX_CONF_UNSET_UINT;
73
73
  conf->stat_throttle_rate = NGX_CONF_UNSET_UINT;
74
74
  conf->show_version_in_header = NGX_CONF_UNSET;
75
+ conf->app_file_descriptor_ulimit = NGX_CONF_UNSET_UINT;
76
+ conf->max_instances_per_app = NGX_CONF_UNSET_UINT;
75
77
  conf->admin_panel_url.data = NULL;
76
78
  conf->admin_panel_url.len = 0;
77
79
  conf->admin_panel_auth_type.data = NULL;
@@ -173,6 +175,14 @@ passenger_create_autogenerated_main_conf(passenger_autogenerated_main_conf_t *co
173
175
  conf->show_version_in_header_source_file.len = 0;
174
176
  conf->show_version_in_header_source_line = 0;
175
177
  conf->show_version_in_header_explicitly_set = 0;
178
+ conf->app_file_descriptor_ulimit_source_file.data = NULL;
179
+ conf->app_file_descriptor_ulimit_source_file.len = 0;
180
+ conf->app_file_descriptor_ulimit_source_line = 0;
181
+ conf->app_file_descriptor_ulimit_explicitly_set = 0;
182
+ conf->max_instances_per_app_source_file.data = NULL;
183
+ conf->max_instances_per_app_source_file.len = 0;
184
+ conf->max_instances_per_app_source_line = 0;
185
+ conf->max_instances_per_app_explicitly_set = 0;
176
186
  conf->admin_panel_url_source_file.data = NULL;
177
187
  conf->admin_panel_url_source_file.len = 0;
178
188
  conf->admin_panel_url_source_line = 0;
@@ -306,6 +306,28 @@ generate_config_manifest_for_autogenerated_main_conf(manifest_gen_ctx_t *ctx, pa
306
306
  psg_json_value_set_bool(hierarchy_member, "value",
307
307
  conf->autogenerated.show_version_in_header);
308
308
  }
309
+ if (conf->autogenerated.app_file_descriptor_ulimit_explicitly_set) {
310
+ option_container = find_or_create_manifest_option_container(ctx,
311
+ ctx->global_config_container,
312
+ "passenger_app_file_descriptor_ulimit",
313
+ sizeof("passenger_app_file_descriptor_ulimit") - 1);
314
+ hierarchy_member = add_manifest_option_container_hierarchy_member(option_container,
315
+ &conf->autogenerated.app_file_descriptor_ulimit_source_file,
316
+ conf->autogenerated.app_file_descriptor_ulimit_source_line);
317
+ psg_json_value_set_uint(hierarchy_member, "value",
318
+ conf->autogenerated.app_file_descriptor_ulimit);
319
+ }
320
+ if (conf->autogenerated.max_instances_per_app_explicitly_set) {
321
+ option_container = find_or_create_manifest_option_container(ctx,
322
+ ctx->global_config_container,
323
+ "passenger_max_instances_per_app",
324
+ sizeof("passenger_max_instances_per_app") - 1);
325
+ hierarchy_member = add_manifest_option_container_hierarchy_member(option_container,
326
+ &conf->autogenerated.max_instances_per_app_source_file,
327
+ conf->autogenerated.max_instances_per_app_source_line);
328
+ psg_json_value_set_uint(hierarchy_member, "value",
329
+ conf->autogenerated.max_instances_per_app);
330
+ }
309
331
  if (conf->autogenerated.admin_panel_url_explicitly_set) {
310
332
  option_container = find_or_create_manifest_option_container(ctx,
311
333
  ctx->global_config_container,