passenger 5.3.4 → 5.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +13 -0
  3. data/CODE_OF_CONDUCT.md +1 -1
  4. data/build/cxx_tests.rb +12 -1
  5. data/build/misc.rb +2 -1
  6. data/build/packaging.rb +2 -0
  7. data/build/support/cplusplus.rb +2 -2
  8. data/build/support/cxx_dependency_map.rb +653 -383
  9. data/dev/configkit-schemas/index.json +105 -3
  10. data/dev/show-latest-crashlog-dir +27 -0
  11. data/resources/templates/standalone/http.erb +2 -0
  12. data/src/agent/Core/AdminPanelConnector.h +2 -2
  13. data/src/agent/Core/ApplicationPool/Context.h +5 -1
  14. data/src/agent/Core/ApplicationPool/Group.h +2 -0
  15. data/src/agent/Core/ApplicationPool/Group/LifetimeAndBasics.cpp +5 -0
  16. data/src/agent/Core/ApplicationPool/Group/Miscellaneous.cpp +2 -1
  17. data/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp +1 -1
  18. data/src/agent/Core/ApplicationPool/Group/StateInspection.cpp +12 -19
  19. data/src/agent/Core/ApplicationPool/Options.h +35 -31
  20. data/src/agent/Core/ApplicationPool/Pool/GroupUtils.cpp +2 -1
  21. data/src/agent/Core/ApplicationPool/Socket.h +1 -1
  22. data/src/agent/Core/Config.h +38 -7
  23. data/src/agent/Core/ConfigChange.cpp +13 -1
  24. data/src/agent/Core/Controller.h +3 -1
  25. data/src/agent/Core/Controller/Config.h +14 -11
  26. data/src/agent/Core/Controller/InitRequest.cpp +6 -5
  27. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +3 -0
  28. data/src/agent/Core/CoreMain.cpp +149 -34
  29. data/src/agent/Core/OptionParser.h +12 -1
  30. data/src/agent/Core/SpawningKit/Config.h +1 -1
  31. data/src/agent/Core/SpawningKit/Context.h +7 -1
  32. data/src/agent/Core/SpawningKit/Exceptions.h +15 -12
  33. data/src/agent/Core/SpawningKit/README.md +34 -17
  34. data/src/agent/Core/SpawningKit/Spawner.h +5 -3
  35. data/src/agent/Core/SpawningKit/UserSwitchingRules.h +5 -2
  36. data/src/agent/Core/TelemetryCollector.h +674 -0
  37. data/src/agent/Shared/Fundamentals/AbortHandler.cpp +309 -83
  38. data/src/agent/Shared/Fundamentals/AbortHandler.h +18 -3
  39. data/src/agent/Watchdog/Config.h +21 -4
  40. data/src/agent/Watchdog/WatchdogMain.cpp +4 -1
  41. data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp +10 -0
  42. data/src/apache2_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.cpp +5 -0
  43. data/src/apache2_module/ConfigGeneral/AutoGeneratedSetterFuncs.cpp +30 -0
  44. data/src/apache2_module/DirectoryMapper.h +24 -36
  45. data/src/apache2_module/Hooks.cpp +13 -5
  46. data/src/apache2_module/ServerConfig/AutoGeneratedManifestGeneration.cpp +20 -0
  47. data/src/apache2_module/ServerConfig/AutoGeneratedStruct.h +24 -0
  48. data/src/cxx_supportlib/AppTypeDetector/CBindings.cpp +136 -0
  49. data/src/cxx_supportlib/AppTypeDetector/CBindings.h +73 -0
  50. data/src/cxx_supportlib/{AppTypes.h → AppTypeDetector/Detector.h} +59 -132
  51. data/src/cxx_supportlib/ConfigKit/README.md +90 -2
  52. data/src/cxx_supportlib/ConfigKit/Schema.h +58 -13
  53. data/src/cxx_supportlib/ConfigKit/Store.h +128 -4
  54. data/src/cxx_supportlib/Constants.h +1 -1
  55. data/src/cxx_supportlib/ProcessManagement/Ruby.cpp +3 -3
  56. data/src/cxx_supportlib/ProcessManagement/Ruby.h +7 -2
  57. data/src/cxx_supportlib/ProcessManagement/Spawn.cpp +14 -7
  58. data/src/cxx_supportlib/ProcessManagement/Spawn.h +21 -2
  59. data/src/cxx_supportlib/ResourceLocator.h +1 -1
  60. data/src/cxx_supportlib/ServerKit/ClientRef.h +17 -7
  61. data/src/cxx_supportlib/ServerKit/HttpRequestRef.h +17 -7
  62. data/src/cxx_supportlib/Utils/IOUtils.cpp +2 -1
  63. data/src/cxx_supportlib/Utils/ProcessMetricsCollector.h +9 -6
  64. data/src/cxx_supportlib/WrapperRegistry/CBindings.cpp +85 -0
  65. data/src/cxx_supportlib/WrapperRegistry/CBindings.h +56 -0
  66. data/src/cxx_supportlib/WrapperRegistry/Entry.h +112 -0
  67. data/src/cxx_supportlib/WrapperRegistry/README.md +37 -0
  68. data/src/cxx_supportlib/WrapperRegistry/Registry.h +309 -0
  69. data/src/helper-scripts/download_binaries/extconf.rb +6 -2
  70. data/src/nginx_module/ConfigGeneral/AutoGeneratedDefinitions.c +16 -0
  71. data/src/nginx_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.c +6 -0
  72. data/src/nginx_module/ConfigGeneral/AutoGeneratedSetterFuncs.c +24 -0
  73. data/src/nginx_module/ContentHandler.c +34 -13
  74. data/src/nginx_module/ContentHandler.h +3 -3
  75. data/src/nginx_module/MainConfig/AutoGeneratedCreateFunction.c +11 -0
  76. data/src/nginx_module/MainConfig/AutoGeneratedManifestGeneration.c +23 -0
  77. data/src/nginx_module/MainConfig/AutoGeneratedStruct.h +8 -0
  78. data/src/nginx_module/config +2 -1
  79. data/src/nginx_module/ngx_http_passenger_module.c +9 -3
  80. data/src/nginx_module/ngx_http_passenger_module.h +4 -2
  81. data/src/ruby_supportlib/phusion_passenger.rb +2 -1
  82. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +13 -0
  83. data/src/ruby_supportlib/phusion_passenger/common_library.rb +8 -5
  84. data/src/ruby_supportlib/phusion_passenger/config/download_agent_command.rb +6 -2
  85. data/src/ruby_supportlib/phusion_passenger/config/download_nginx_engine_command.rb +6 -2
  86. data/src/ruby_supportlib/phusion_passenger/native_support.rb +7 -3
  87. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +15 -0
  88. data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +11 -1
  89. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +3 -1
  90. metadata +12 -4
  91. data/src/cxx_supportlib/AppTypes.cpp +0 -109
@@ -253,7 +253,7 @@ public:
253
253
  }
254
254
 
255
255
  bool isTotallyBusy() const {
256
- return concurrency != 0 && sessions >= concurrency;
256
+ return concurrency > 0 && sessions >= concurrency;
257
257
  }
258
258
 
259
259
  void recreateStrings(psg_pool_t *newPool) {
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2011-2017 Phusion Holding B.V.
3
+ * Copyright (c) 2011-2018 Phusion Holding B.V.
4
4
  *
5
5
  * "Passenger", "Phusion Passenger" and "Union Station" are registered
6
6
  * trademarks of Phusion Holding B.V.
@@ -41,8 +41,10 @@
41
41
  #include <ConfigKit/PrefixTranslator.h>
42
42
  #include <ServerKit/Context.h>
43
43
  #include <ServerKit/HttpServer.h>
44
+ #include <WrapperRegistry/Registry.h>
44
45
  #include <Core/Controller/Config.h>
45
46
  #include <Core/SecurityUpdateChecker.h>
47
+ #include <Core/TelemetryCollector.h>
46
48
  #include <Core/ApiServer.h>
47
49
  #include <Core/AdminPanelConnector.h>
48
50
  #include <Shared/ApiAccountUtils.h>
@@ -154,13 +156,24 @@ using namespace std;
154
156
  * security_update_checker_interval unsigned integer - default(86400)
155
157
  * security_update_checker_proxy_url string - -
156
158
  * security_update_checker_url string - default("https://securitycheck.phusionpassenger.com/v1/check.json")
157
- * server_software string - default("Phusion_Passenger/5.3.4")
159
+ * server_software string - default("Phusion_Passenger/5.3.5")
158
160
  * show_version_in_header boolean - default(true)
159
161
  * single_app_mode_app_root string - default,read_only
160
162
  * single_app_mode_app_type string - read_only
161
163
  * single_app_mode_startup_file string - read_only
162
164
  * standalone_engine string - default
163
165
  * stat_throttle_rate unsigned integer - default(10)
166
+ * telemetry_collector_ca_certificate_path string - -
167
+ * telemetry_collector_debug_curl boolean - default(false)
168
+ * telemetry_collector_disabled boolean - default(false)
169
+ * telemetry_collector_final_run_timeout unsigned integer - default(5)
170
+ * telemetry_collector_first_interval unsigned integer - default(7200)
171
+ * telemetry_collector_interval unsigned integer - default(21600)
172
+ * telemetry_collector_interval_jitter unsigned integer - default(7200)
173
+ * telemetry_collector_proxy_url string - -
174
+ * telemetry_collector_timeout unsigned integer - default(180)
175
+ * telemetry_collector_url string - default("https://anontelemetry.phusionpassenger.com/v1/collect.json")
176
+ * telemetry_collector_verify_server boolean - default(true)
164
177
  * turbocaching boolean - default(true),read_only
165
178
  * user_switching boolean - default(true)
166
179
  * vary_turbocache_by_cookie string - -
@@ -241,7 +254,9 @@ private:
241
254
  }
242
255
  }
243
256
 
244
- static void validateSingleAppMode(const ConfigKit::Store &config, vector<ConfigKit::Error> &errors) {
257
+ static void validateSingleAppMode(const ConfigKit::Store &config,
258
+ const WrapperRegistry::Registry *wrapperRegistry, vector<ConfigKit::Error> &errors)
259
+ {
245
260
  typedef ConfigKit::Error Error;
246
261
 
247
262
  if (config["multi_app"].asBool()) {
@@ -251,7 +266,8 @@ private:
251
266
  // single_app_mode_app_type and single_app_mode_startup_file are
252
267
  // autodetected in initializeSingleAppMode()
253
268
 
254
- ControllerSingleAppModeSchema::validateAppType("single_app_mode_app_type", config, errors);
269
+ ControllerSingleAppModeSchema::validateAppType("single_app_mode_app_type",
270
+ wrapperRegistry, config, errors);
255
271
  }
256
272
 
257
273
  static void validateControllerSecureHeadersPassword(const ConfigKit::Store &config, vector<ConfigKit::Error> &errors) {
@@ -348,9 +364,13 @@ public:
348
364
  ControllerSchema schema;
349
365
  ConfigKit::TableTranslator translator;
350
366
  } controller;
351
- struct {
367
+ struct ControllerSingleAppModeSubschemaContainer {
352
368
  ControllerSingleAppModeSchema schema;
353
369
  ConfigKit::PrefixTranslator translator;
370
+
371
+ ControllerSingleAppModeSubschemaContainer(const WrapperRegistry::Registry *registry)
372
+ : schema(registry)
373
+ { }
354
374
  } controllerSingleAppMode;
355
375
  struct {
356
376
  ServerKit::Schema schema;
@@ -360,6 +380,10 @@ public:
360
380
  SecurityUpdateChecker::Schema schema;
361
381
  ConfigKit::PrefixTranslator translator;
362
382
  } securityUpdateChecker;
383
+ struct {
384
+ TelemetryCollector::Schema schema;
385
+ ConfigKit::PrefixTranslator translator;
386
+ } telemetryCollector;
363
387
  struct {
364
388
  ApiServer::Schema schema;
365
389
  ConfigKit::TableTranslator translator;
@@ -373,7 +397,9 @@ public:
373
397
  ConfigKit::TableTranslator translator;
374
398
  } adminPanelConnector;
375
399
 
376
- Schema() {
400
+ Schema(const WrapperRegistry::Registry *wrapperRegistry = NULL)
401
+ : controllerSingleAppMode(wrapperRegistry)
402
+ {
377
403
  using namespace ConfigKit;
378
404
 
379
405
  // Add subschema: loggingKit
@@ -410,6 +436,10 @@ public:
410
436
  erase("security_update_checker_server_identifier");
411
437
  erase("security_update_checker_web_server_version");
412
438
 
439
+ // Add subschema: telemetryCollector
440
+ telemetryCollector.translator.setPrefixAndFinalize("telemetry_collector_");
441
+ addSubSchema(telemetryCollector.schema, telemetryCollector.translator);
442
+
413
443
  // Add subschema: apiServer
414
444
  apiServer.translator.add("api_server_authorizations", "authorizations");
415
445
  addSubSchemaPrefixTranslations<ServerKit::HttpServerSchema>(
@@ -453,7 +483,8 @@ public:
453
483
  add("file_descriptor_ulimit", UINT_TYPE, OPTIONAL | READ_ONLY, 0);
454
484
 
455
485
  addValidator(validateMultiAppMode);
456
- addValidator(validateSingleAppMode);
486
+ addValidator(boost::bind(validateSingleAppMode, boost::placeholders::_1,
487
+ wrapperRegistry, boost::placeholders::_2));
457
488
  addValidator(validateControllerSecureHeadersPassword);
458
489
  addValidator(validateApplicationPool);
459
490
  addValidator(validateController);
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2011-2017 Phusion Holding B.V.
3
+ * Copyright (c) 2011-2018 Phusion Holding B.V.
4
4
  *
5
5
  * "Passenger", "Phusion Passenger" and "Union Station" are registered
6
6
  * trademarks of Phusion Holding B.V.
@@ -49,6 +49,7 @@ struct ConfigChangeRequest {
49
49
  boost::scoped_ptr<ConfigKit::Store> config;
50
50
  LoggingKit::ConfigChangeRequest forLoggingKit;
51
51
  SecurityUpdateChecker::ConfigChangeRequest forSecurityUpdateChecker;
52
+ TelemetryCollector::ConfigChangeRequest forTelemetryCollector;
52
53
  vector<ServerKit::ConfigChangeRequest *> forControllerServerKit;
53
54
  vector<Controller::ConfigChangeRequest *> forController;
54
55
  ServerKit::ConfigChangeRequest forApiServerKit;
@@ -188,6 +189,13 @@ asyncPrepareConfigChange(const Json::Value &updates, ConfigChangeRequest *req,
188
189
  coreSchema->securityUpdateChecker.translator,
189
190
  req->config->inspectEffectiveValues(),
190
191
  req->errors, req->forSecurityUpdateChecker);
192
+ if (workingObjects->telemetryCollector != NULL) {
193
+ ConfigKit::prepareConfigChangeForSubComponent(
194
+ *workingObjects->telemetryCollector,
195
+ coreSchema->telemetryCollector.translator,
196
+ req->config->inspectEffectiveValues(),
197
+ req->errors, req->forTelemetryCollector);
198
+ }
191
199
 
192
200
  req->forControllerServerKit.resize(wo->threadWorkingObjects.size(), NULL);
193
201
  req->forController.resize(wo->threadWorkingObjects.size(), NULL);
@@ -287,6 +295,10 @@ asyncCommitConfigChange(ConfigChangeRequest *req, const CommitConfigChangeCallba
287
295
  LoggingKit::context->commitConfigChange(req->forLoggingKit);
288
296
  workingObjects->securityUpdateChecker->commitConfigChange(
289
297
  req->forSecurityUpdateChecker);
298
+ if (workingObjects->telemetryCollector != NULL) {
299
+ workingObjects->telemetryCollector->commitConfigChange(
300
+ req->forTelemetryCollector);
301
+ }
290
302
 
291
303
  wo->appPool->setMax(coreConfig->get("max_pool_size").asInt());
292
304
  wo->appPool->setMaxIdleTime(coreConfig->get("pool_idle_time").asInt() * 1000000ULL);
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2011-2017 Phusion Holding B.V.
3
+ * Copyright (c) 2011-2018 Phusion Holding B.V.
4
4
  *
5
5
  * "Passenger", "Phusion Passenger" and "Union Station" are registered
6
6
  * trademarks of Phusion Holding B.V.
@@ -71,6 +71,7 @@
71
71
  #include <MemoryKit/palloc.h>
72
72
  #include <DataStructures/LString.h>
73
73
  #include <DataStructures/StringKeyTable.h>
74
+ #include <WrapperRegistry/Registry.h>
74
75
  #include <StaticString.h>
75
76
  #include <Utils.h>
76
77
  #include <Utils/StrIntUtils.h>
@@ -365,6 +366,7 @@ public:
365
366
 
366
367
  // Dependencies
367
368
  ResourceLocator *resourceLocator;
369
+ WrapperRegistry::Registry *wrapperRegistry;
368
370
  PoolPtr appPool;
369
371
 
370
372
 
@@ -39,7 +39,7 @@
39
39
  #include <MemoryKit/palloc.h>
40
40
  #include <ServerKit/HttpServer.h>
41
41
  #include <SystemTools/UserDatabase.h>
42
- #include <AppTypes.h>
42
+ #include <WrapperRegistry/Registry.h>
43
43
  #include <Constants.h>
44
44
  #include <Exceptions.h>
45
45
  #include <StaticString.h>
@@ -113,7 +113,7 @@ parseControllerBenchmarkMode(const StaticString &mode) {
113
113
  * multi_app boolean - default(true),read_only
114
114
  * request_freelist_limit unsigned integer - default(1024)
115
115
  * response_buffer_high_watermark unsigned integer - default(134217728)
116
- * server_software string - default("Phusion_Passenger/5.3.4")
116
+ * server_software string - default("Phusion_Passenger/5.3.5")
117
117
  * show_version_in_header boolean - default(true)
118
118
  * start_reading_after_accept boolean - default(true)
119
119
  * stat_throttle_rate unsigned integer - default(10)
@@ -230,7 +230,7 @@ public:
230
230
  * END
231
231
  */
232
232
  struct ControllerSingleAppModeSchema: public ConfigKit::Schema {
233
- ControllerSingleAppModeSchema() {
233
+ ControllerSingleAppModeSchema(const WrapperRegistry::Registry *wrapperRegistry = NULL) {
234
234
  using namespace ConfigKit;
235
235
 
236
236
  addWithDynamicDefault("app_root", STRING_TYPE, OPTIONAL | READ_ONLY | CACHE_DEFAULT_VALUE,
@@ -238,7 +238,7 @@ struct ControllerSingleAppModeSchema: public ConfigKit::Schema {
238
238
  add("app_type", STRING_TYPE, REQUIRED | READ_ONLY);
239
239
  add("startup_file", STRING_TYPE, REQUIRED | READ_ONLY);
240
240
 
241
- addValidator(boost::bind(validateAppType, "app_type",
241
+ addValidator(boost::bind(validateAppType, "app_type", wrapperRegistry,
242
242
  boost::placeholders::_1, boost::placeholders::_2));
243
243
  addNormalizer(normalizeAppRoot);
244
244
  addNormalizer(normalizeStartupFile);
@@ -258,21 +258,24 @@ struct ControllerSingleAppModeSchema: public ConfigKit::Schema {
258
258
  }
259
259
 
260
260
  static void validateAppType(const string &appTypeKey,
261
+ const WrapperRegistry::Registry *wrapperRegistry,
261
262
  const ConfigKit::Store &config, vector<ConfigKit::Error> &errors)
262
263
  {
263
264
  typedef ConfigKit::Error Error;
264
265
 
265
- if (!config[appTypeKey].isNull()) {
266
- PassengerAppType appType = getAppType(config[appTypeKey].asString());
267
- if (appType == PAT_NONE || appType == PAT_ERROR) {
266
+ if (!config[appTypeKey].isNull() && wrapperRegistry != NULL) {
267
+ const WrapperRegistry::Entry &entry =
268
+ wrapperRegistry->lookup(config[appTypeKey].asString());
269
+ if (entry.isNull()) {
268
270
  string message = "'{{" + appTypeKey + "}}' is set to '"
269
271
  + config[appTypeKey].asString() + "', which is not a"
270
272
  " valid application type. Supported app types are:";
271
- const AppTypeDefinition *definition = &appTypeDefinitions[0];
272
- while (definition->type != PAT_NONE) {
273
+ WrapperRegistry::Registry::ConstIterator it(
274
+ wrapperRegistry->getIterator());
275
+ while (*it != NULL) {
273
276
  message.append(1, ' ');
274
- message.append(definition->name);
275
- definition++;
277
+ message.append(it.getValue().language);
278
+ it.next();
276
279
  }
277
280
  errors.push_back(Error(message));
278
281
  }
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2011-2017 Phusion Holding B.V.
3
+ * Copyright (c) 2011-2018 Phusion Holding B.V.
4
4
  *
5
5
  * "Passenger", "Phusion Passenger" and "Union Station" are registered
6
6
  * trademarks of Phusion Holding B.V.
@@ -24,6 +24,7 @@
24
24
  * THE SOFTWARE.
25
25
  */
26
26
  #include <Core/Controller.h>
27
+ #include <AppTypeDetector/Detector.h>
27
28
 
28
29
  /*************************************************************************
29
30
  *
@@ -336,13 +337,13 @@ Controller::createNewPoolOptions(Client *client, Request *req,
336
337
 
337
338
  const LString *appType = secureHeaders.lookup("!~PASSENGER_APP_TYPE");
338
339
  if (appType == NULL || appType->size == 0) {
339
- AppTypeDetector detector;
340
- PassengerAppType type = detector.checkAppRoot(options.appRoot);
341
- if (type == PAT_NONE || type == PAT_ERROR) {
340
+ AppTypeDetector::Detector detector(*wrapperRegistry);
341
+ AppTypeDetector::Detector::Result result = detector.checkAppRoot(options.appRoot);
342
+ if (result.isNull()) {
342
343
  disconnectWithError(&client, "client did not send a recognized !~PASSENGER_APP_TYPE header");
343
344
  return;
344
345
  }
345
- options.appType = getAppTypeName(type);
346
+ options.appType = result.wrapperRegistryEntry->language;
346
347
  } else {
347
348
  fillPoolOption(req, options.appType, "!~PASSENGER_APP_TYPE");
348
349
  }
@@ -94,6 +94,9 @@ Controller::initialize() {
94
94
  if (resourceLocator == NULL) {
95
95
  throw RuntimeException("ResourceLocator not initialized");
96
96
  }
97
+ if (wrapperRegistry == NULL) {
98
+ throw RuntimeException("WrapperRegistry not initialized");
99
+ }
97
100
  if (appPool == NULL) {
98
101
  throw RuntimeException("AppPool not initialized");
99
102
  }
@@ -81,6 +81,7 @@
81
81
  #include <ConfigKit/SubComponentUtils.h>
82
82
  #include <ServerKit/Server.h>
83
83
  #include <ServerKit/AcceptLoadBalancer.h>
84
+ #include <AppTypeDetector/Detector.h>
84
85
  #include <MessageReadersWriters.h>
85
86
  #include <FileDescriptor.h>
86
87
  #include <ResourceLocator.h>
@@ -98,6 +99,7 @@
98
99
  #include <Core/ConfigChange.h>
99
100
  #include <Core/ApplicationPool/Pool.h>
100
101
  #include <Core/SecurityUpdateChecker.h>
102
+ #include <Core/TelemetryCollector.h>
101
103
  #include <Core/AdminPanelConnector.h>
102
104
 
103
105
  using namespace boost;
@@ -165,6 +167,7 @@ namespace Core {
165
167
  oxt::thread *prestarterThread;
166
168
 
167
169
  SecurityUpdateChecker *securityUpdateChecker;
170
+ TelemetryCollector *telemetryCollector;
168
171
  AdminPanelConnector *adminPanelConnector;
169
172
  oxt::thread *adminPanelConnectorThread;
170
173
 
@@ -175,6 +178,7 @@ namespace Core {
175
178
  shutdownCounter(0),
176
179
  prestarterThread(NULL),
177
180
  securityUpdateChecker(NULL),
181
+ telemetryCollector(NULL),
178
182
  adminPanelConnector(NULL),
179
183
  adminPanelConnectorThread(NULL)
180
184
  /*******************/
@@ -190,6 +194,7 @@ namespace Core {
190
194
  delete adminPanelConnectorThread;
191
195
  delete adminPanelConnector;
192
196
  delete securityUpdateChecker;
197
+ delete telemetryCollector;
193
198
 
194
199
  /*******************/
195
200
  /*******************/
@@ -211,6 +216,7 @@ namespace Core {
211
216
 
212
217
  using namespace Passenger::Core;
213
218
 
219
+ static WrapperRegistry::Registry *coreWrapperRegistry;
214
220
  static Schema *coreSchema;
215
221
  static ConfigKit::Store *coreConfig;
216
222
  static WorkingObjects *workingObjects;
@@ -257,9 +263,9 @@ initializeSingleAppMode() {
257
263
 
258
264
  if (coreConfig->get("single_app_mode_app_type").isNull()) {
259
265
  P_DEBUG("Autodetecting application type...");
260
- AppTypeDetector detector(NULL, 0);
261
- PassengerAppType appTypeEnum = detector.checkAppRoot(appRoot);
262
- if (appTypeEnum == PAT_NONE || appTypeEnum == PAT_ERROR) {
266
+ AppTypeDetector::Detector detector(*coreWrapperRegistry, NULL, 0);
267
+ AppTypeDetector::Detector::Result result = detector.checkAppRoot(appRoot);
268
+ if (result.isNull()) {
263
269
  fprintf(stderr, "ERROR: unable to autodetect what kind of application "
264
270
  "lives in %s. Please specify information about the app using "
265
271
  "--app-type and --startup-file, or specify a correct location to "
@@ -269,13 +275,18 @@ initializeSingleAppMode() {
269
275
  exit(1);
270
276
  }
271
277
 
272
- appType = getAppTypeName(appTypeEnum);
278
+ appType = result.wrapperRegistryEntry->language;
273
279
  } else {
274
280
  appType = coreConfig->get("single_app_mode_app_type").asString();
275
281
  }
276
282
 
277
283
  if (coreConfig->get("single_app_mode_startup_file").isNull()) {
278
- startupFile = appRoot + "/" + getAppTypeStartupFile(getAppType(appType));
284
+ const WrapperRegistry::Entry &entry = coreWrapperRegistry->lookup(appType);
285
+ if (entry.defaultStartupFiles.empty()) {
286
+ startupFile = appRoot + "/";
287
+ } else {
288
+ startupFile = appRoot + "/" + entry.defaultStartupFiles[0];
289
+ }
279
290
  } else {
280
291
  startupFile = coreConfig->get("single_app_mode_startup_file").asString();
281
292
  }
@@ -551,39 +562,62 @@ printInfoInThread() {
551
562
  }
552
563
 
553
564
  static void
554
- dumpDiagnosticsOnCrash(void *userData) {
555
- WorkingObjects *wo = workingObjects;
556
- unsigned int i;
557
-
558
- cerr << "### Backtraces\n";
565
+ dumpOxtBacktracesOnCrash(void *userData) {
559
566
  cerr << oxt::thread::all_backtraces();
560
567
  cerr.flush();
568
+ }
569
+
570
+ static void
571
+ dumpControllerStatesOnCrash(void *userData) {
572
+ WorkingObjects *wo = workingObjects;
573
+ unsigned int i;
561
574
 
562
575
  for (i = 0; i < wo->threadWorkingObjects.size(); i++) {
563
576
  ThreadWorkingObjects *two = &wo->threadWorkingObjects[i];
564
- cerr << "### Request handler state (thread " << (i + 1) << ")\n";
577
+ cerr << "####### Controller state (thread " << (i + 1) << ") #######\n";
565
578
  cerr << two->controller->inspectStateAsJson();
566
- cerr << "\n";
579
+ cerr << "\n\n";
567
580
  cerr.flush();
568
581
  }
582
+ }
583
+
584
+ static void
585
+ dumpControllerConfigsOnCrash(void *userData) {
586
+ WorkingObjects *wo = workingObjects;
587
+ unsigned int i;
569
588
 
570
589
  for (i = 0; i < wo->threadWorkingObjects.size(); i++) {
571
590
  ThreadWorkingObjects *two = &wo->threadWorkingObjects[i];
572
- cerr << "### Request handler config (thread " << (i + 1) << ")\n";
591
+ cerr << "####### Controller config (thread " << (i + 1) << ") #######\n";
573
592
  cerr << two->controller->inspectConfig();
574
- cerr << "\n";
593
+ cerr << "\n\n";
575
594
  cerr.flush();
576
595
  }
596
+ }
597
+
598
+ static void
599
+ dumpPoolStateOnCrash(void *userData) {
600
+ WorkingObjects *wo = workingObjects;
577
601
 
578
- cerr << "### Pool state (simple)\n";
602
+ cerr << "####### Pool state (simple) #######\n";
579
603
  // Do not lock, the crash may occur within the pool.
580
604
  Pool::InspectOptions options(Pool::InspectOptions::makeAuthorized());
581
605
  options.verbose = true;
582
606
  cerr << wo->appPool->inspect(options, false);
583
- cerr << "\n";
607
+ cerr << "\n\n";
584
608
  cerr.flush();
585
609
 
586
- cerr << "### mbuf stats\n\n";
610
+ cerr << "####### Pool state (XML) #######\n";
611
+ Pool::ToXmlOptions options2(Pool::ToXmlOptions::makeAuthorized());
612
+ options2.secrets = true;
613
+ cerr << wo->appPool->toXml(options2, false);
614
+ cerr << "\n\n";
615
+ cerr.flush();
616
+ }
617
+
618
+ static void
619
+ dumpMbufStatsOnCrash(void *userData) {
620
+ WorkingObjects *wo = workingObjects;
587
621
  cerr << "nfree_mbuf_blockq : " <<
588
622
  wo->threadWorkingObjects[0].serverKitContext->mbuf_pool.nfree_mbuf_blockq << "\n";
589
623
  cerr << "nactive_mbuf_blockq: " <<
@@ -592,13 +626,6 @@ dumpDiagnosticsOnCrash(void *userData) {
592
626
  wo->threadWorkingObjects[0].serverKitContext->mbuf_pool.mbuf_block_chunk_size << "\n";
593
627
  cerr << "\n";
594
628
  cerr.flush();
595
-
596
- cerr << "### Pool state (XML)\n";
597
- Pool::ToXmlOptions options2(Pool::ToXmlOptions::makeAuthorized());
598
- options2.secrets = true;
599
- cerr << wo->appPool->toXml(options2, false);
600
- cerr << "\n\n";
601
- cerr.flush();
602
629
  }
603
630
 
604
631
  static void
@@ -653,6 +680,7 @@ initializeNonPrivilegedWorkingObjects() {
653
680
  wo->spawningKitContext = boost::make_shared<SpawningKit::Context>(
654
681
  wo->spawningKitContextSchema);
655
682
  wo->spawningKitContext->resourceLocator = &wo->resourceLocator;
683
+ wo->spawningKitContext->wrapperRegistry = coreWrapperRegistry;
656
684
  wo->spawningKitContext->randomGenerator = wo->randomGenerator;
657
685
  wo->spawningKitContext->integrationMode = coreConfig->get("integration_mode").asString();
658
686
  wo->spawningKitContext->instanceDir = coreConfig->get("instance_dir").asString();
@@ -713,6 +741,7 @@ initializeNonPrivilegedWorkingObjects() {
713
741
  &wo->singleAppModeConfig,
714
742
  coreSchema->controllerSingleAppMode.translator);
715
743
  two.controller->resourceLocator = &wo->resourceLocator;
744
+ two.controller->wrapperRegistry = coreWrapperRegistry;
716
745
  two.controller->appPool = wo->appPool;
717
746
  two.controller->shutdownFinishCallback = controllerShutdownFinished;
718
747
  two.controller->initialize();
@@ -821,6 +850,27 @@ initializeSecurityUpdateChecker() {
821
850
  checker->start();
822
851
  }
823
852
 
853
+ static void
854
+ initializeTelemetryCollector() {
855
+ return; // disable for now
856
+ TRACE_POINT();
857
+ WorkingObjects &wo = *workingObjects;
858
+
859
+ Json::Value config = coreConfig->inspectEffectiveValues();
860
+ TelemetryCollector *collector = new TelemetryCollector(
861
+ coreSchema->telemetryCollector.schema,
862
+ coreConfig->inspectEffectiveValues(),
863
+ coreSchema->telemetryCollector.translator);
864
+ wo.telemetryCollector = collector;
865
+ for (unsigned int i = 0; i < wo.threadWorkingObjects.size(); i++) {
866
+ ThreadWorkingObjects *two = &wo.threadWorkingObjects[i];
867
+ collector->controllers.push_back(two->controller);
868
+ }
869
+ collector->initialize();
870
+ collector->start();
871
+ wo.shutdownCounter.fetch_add(1, boost::memory_order_relaxed);
872
+ }
873
+
824
874
  static void
825
875
  runAdminPanelConnector(AdminPanelConnector *connector) {
826
876
  connector->run();
@@ -968,6 +1018,50 @@ reportInitializationInfo() {
968
1018
  }
969
1019
  }
970
1020
 
1021
+ static void
1022
+ initializeAbortHandlerCustomerDiagnostics() {
1023
+ if (!Agent::Fundamentals::abortHandlerInstalled()) {
1024
+ return;
1025
+ }
1026
+
1027
+ Agent::Fundamentals::AbortHandlerConfig::DiagnosticsDumper *diagnosticsDumpers
1028
+ = &Agent::Fundamentals::context->abortHandlerConfig.diagnosticsDumpers[0];
1029
+
1030
+ diagnosticsDumpers[0].name = "OXT backtraces";
1031
+ diagnosticsDumpers[0].logFileName = "backtrace_oxt.log";
1032
+ diagnosticsDumpers[0].func = dumpOxtBacktracesOnCrash;
1033
+
1034
+ diagnosticsDumpers[1].name = "controller states";
1035
+ diagnosticsDumpers[1].logFileName = "controller_states.log";
1036
+ diagnosticsDumpers[1].func = dumpControllerStatesOnCrash;
1037
+
1038
+ diagnosticsDumpers[2].name = "controller configs";
1039
+ diagnosticsDumpers[2].logFileName = "controller_configs.log";
1040
+ diagnosticsDumpers[2].func = dumpControllerConfigsOnCrash;
1041
+
1042
+ diagnosticsDumpers[3].name = "pool state";
1043
+ diagnosticsDumpers[3].logFileName = "pool.log";
1044
+ diagnosticsDumpers[3].func = dumpPoolStateOnCrash;
1045
+
1046
+ diagnosticsDumpers[4].name = "mbuf statistics";
1047
+ diagnosticsDumpers[4].logFileName = "mbufs.log";
1048
+ diagnosticsDumpers[4].func = dumpMbufStatsOnCrash;
1049
+
1050
+ Agent::Fundamentals::abortHandlerConfigChanged();
1051
+ }
1052
+
1053
+ static void
1054
+ uninstallAbortHandlerCustomDiagnostics() {
1055
+ if (!Agent::Fundamentals::abortHandlerInstalled()) {
1056
+ return;
1057
+ }
1058
+
1059
+ for (unsigned int i = 0; i < Agent::Fundamentals::AbortHandlerConfig::MAX_DIAGNOSTICS_DUMPERS; i++) {
1060
+ Agent::Fundamentals::context->abortHandlerConfig.diagnosticsDumpers[i].func = NULL;
1061
+ }
1062
+ Agent::Fundamentals::abortHandlerConfigChanged();
1063
+ }
1064
+
971
1065
  static void
972
1066
  mainLoop() {
973
1067
  TRACE_POINT();
@@ -978,9 +1072,6 @@ mainLoop() {
978
1072
  && maxCpus <= CPU_SETSIZE;
979
1073
  #endif
980
1074
 
981
- Agent::Fundamentals::context->abortHandlerConfig.diagnosticsDumper = dumpDiagnosticsOnCrash;
982
- Agent::Fundamentals::abortHandlerConfigChanged();
983
-
984
1075
  for (unsigned int i = 0; i < wo->threadWorkingObjects.size(); i++) {
985
1076
  ThreadWorkingObjects *two = &wo->threadWorkingObjects[i];
986
1077
  two->bgloop->start("Main event loop: thread " + toString(i + 1), 0);
@@ -1064,6 +1155,20 @@ apiServerShutdownFinished(Core::ApiServer::ApiServer *server) {
1064
1155
  serverShutdownFinished();
1065
1156
  }
1066
1157
 
1158
+ static void
1159
+ telemetryCollectorAsyncShutdownThreadMain() {
1160
+ WorkingObjects *wo = workingObjects;
1161
+ wo->telemetryCollector->stop();
1162
+ serverShutdownFinished();
1163
+ }
1164
+
1165
+ static void
1166
+ asyncShutdownTelemetryCollector() {
1167
+ oxt::thread(telemetryCollectorAsyncShutdownThreadMain,
1168
+ "Telemetry collector shutdown",
1169
+ 512 * 1024);
1170
+ }
1171
+
1067
1172
  /* Wait until the watchdog closes the feedback fd (meaning it
1068
1173
  * was killed) or until we receive an exit message.
1069
1174
  */
@@ -1085,8 +1190,7 @@ waitForExitEvent() {
1085
1190
  TRACE_POINT();
1086
1191
  if (syscalls::select(largestFd + 1, &fds, NULL, NULL, NULL) == -1) {
1087
1192
  int e = errno;
1088
- Agent::Fundamentals::context->abortHandlerConfig.diagnosticsDumper = NULL;
1089
- Agent::Fundamentals::abortHandlerConfigChanged();
1193
+ uninstallAbortHandlerCustomDiagnostics();
1090
1194
  throw SystemException("select() failed", e);
1091
1195
  }
1092
1196
 
@@ -1122,6 +1226,9 @@ waitForExitEvent() {
1122
1226
  if (wo->apiWorkingObjects.apiServer != NULL) {
1123
1227
  wo->apiWorkingObjects.bgloop->safe->runLater(shutdownApiServer);
1124
1228
  }
1229
+ if (wo->telemetryCollector != NULL) {
1230
+ asyncShutdownTelemetryCollector();
1231
+ }
1125
1232
  if (wo->adminPanelConnector != NULL) {
1126
1233
  wo->adminPanelConnector->asyncShutdown();
1127
1234
  }
@@ -1133,8 +1240,7 @@ waitForExitEvent() {
1133
1240
  &fds, NULL, NULL, NULL) == -1)
1134
1241
  {
1135
1242
  int e = errno;
1136
- Agent::Fundamentals::context->abortHandlerConfig.diagnosticsDumper = NULL;
1137
- Agent::Fundamentals::abortHandlerConfigChanged();
1243
+ uninstallAbortHandlerCustomDiagnostics();
1138
1244
  throw SystemException("select() failed", e);
1139
1245
  }
1140
1246
 
@@ -1150,8 +1256,7 @@ cleanup() {
1150
1256
  P_DEBUG("Shutting down " SHORT_PROGRAM_NAME " core...");
1151
1257
  wo->appPool->destroy();
1152
1258
 
1153
- Agent::Fundamentals::context->abortHandlerConfig.diagnosticsDumper = dumpDiagnosticsOnCrash;
1154
- Agent::Fundamentals::abortHandlerConfigChanged();
1259
+ uninstallAbortHandlerCustomDiagnostics();
1155
1260
 
1156
1261
  for (unsigned i = 0; i < wo->threadWorkingObjects.size(); i++) {
1157
1262
  ThreadWorkingObjects *two = &wo->threadWorkingObjects[i];
@@ -1160,6 +1265,11 @@ cleanup() {
1160
1265
  if (wo->apiWorkingObjects.apiServer != NULL) {
1161
1266
  wo->apiWorkingObjects.bgloop->stop();
1162
1267
  }
1268
+ if (wo->telemetryCollector != NULL
1269
+ && !coreConfig->get("telemetry_collector_disabled").asBool())
1270
+ {
1271
+ wo->telemetryCollector->runOneCycle(true);
1272
+ }
1163
1273
  wo->appPool.reset();
1164
1274
  for (unsigned i = 0; i < wo->threadWorkingObjects.size(); i++) {
1165
1275
  ThreadWorkingObjects *two = &wo->threadWorkingObjects[i];
@@ -1210,12 +1320,14 @@ runCore() {
1210
1320
  initializeCurl();
1211
1321
  initializeNonPrivilegedWorkingObjects();
1212
1322
  initializeSecurityUpdateChecker();
1323
+ initializeTelemetryCollector();
1213
1324
  initializeAdminPanelConnector();
1214
1325
  prestartWebApps();
1215
1326
 
1216
1327
  UPDATE_TRACE_POINT();
1217
1328
  warnIfPassengerRootVulnerable();
1218
1329
  reportInitializationInfo();
1330
+ initializeAbortHandlerCustomerDiagnostics();
1219
1331
  mainLoop();
1220
1332
 
1221
1333
  UPDATE_TRACE_POINT();
@@ -1277,7 +1389,9 @@ int
1277
1389
  coreMain(int argc, char *argv[]) {
1278
1390
  int ret;
1279
1391
 
1280
- coreSchema = new Schema();
1392
+ coreWrapperRegistry = new WrapperRegistry::Registry();
1393
+ coreWrapperRegistry->finalize();
1394
+ coreSchema = new Schema(coreWrapperRegistry);
1281
1395
  coreConfig = new ConfigKit::Store(*coreSchema);
1282
1396
  initializeAgent(argc, &argv, SHORT_PROGRAM_NAME " core",
1283
1397
  *coreConfig, coreSchema->loggingKit.translator,
@@ -1289,5 +1403,6 @@ coreMain(int argc, char *argv[]) {
1289
1403
 
1290
1404
  ret = runCore();
1291
1405
  shutdownAgent(coreSchema, coreConfig);
1406
+ delete coreWrapperRegistry;
1292
1407
  return ret;
1293
1408
  }