passenger 5.0.9 → 5.0.10

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 (106) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/CHANGELOG +15 -0
  5. data/CONTRIBUTORS +6 -0
  6. data/README.md +1 -1
  7. data/bin/passenger-install-apache2-module +24 -11
  8. data/bin/passenger-status +29 -14
  9. data/build/agents.rb +12 -10
  10. data/build/cxx_tests.rb +30 -30
  11. data/doc/Design and Architecture.html +1 -10
  12. data/doc/Design and Architecture.txt +1 -6
  13. data/doc/Users guide Apache.html +1 -19
  14. data/doc/Users guide Apache.txt +1 -1
  15. data/doc/Users guide Nginx.html +2 -20
  16. data/doc/Users guide Nginx.txt +2 -2
  17. data/doc/users_guide_snippets/tips.txt +0 -9
  18. data/ext/common/ApplicationPool2/ApiKey.h +158 -0
  19. data/ext/common/ApplicationPool2/BasicGroupInfo.h +81 -0
  20. data/ext/common/ApplicationPool2/BasicProcessInfo.h +106 -0
  21. data/ext/common/ApplicationPool2/Common.h +5 -44
  22. data/ext/common/ApplicationPool2/Context.h +94 -0
  23. data/ext/common/ApplicationPool2/Group.h +130 -1205
  24. data/ext/common/ApplicationPool2/Group/InitializationAndShutdown.cpp +190 -0
  25. data/ext/common/ApplicationPool2/Group/InternalUtils.cpp +329 -0
  26. data/ext/common/ApplicationPool2/Group/LifetimeAndBasics.cpp +103 -0
  27. data/ext/common/ApplicationPool2/{Pool/Debug.h → Group/Miscellaneous.cpp} +40 -38
  28. data/ext/common/ApplicationPool2/Group/OutOfBandWork.cpp +323 -0
  29. data/ext/common/ApplicationPool2/Group/ProcessListManagement.cpp +606 -0
  30. data/ext/common/ApplicationPool2/Group/SessionManagement.cpp +337 -0
  31. data/ext/common/ApplicationPool2/Group/SpawningAndRestarting.cpp +478 -0
  32. data/ext/common/ApplicationPool2/Group/StateInspection.cpp +197 -0
  33. data/ext/common/ApplicationPool2/Group/Verification.cpp +159 -0
  34. data/ext/common/ApplicationPool2/Implementation.cpp +19 -1401
  35. data/ext/common/ApplicationPool2/Options.h +5 -5
  36. data/ext/common/ApplicationPool2/Pool.h +260 -815
  37. data/ext/common/ApplicationPool2/Pool/{AnalyticsCollection.h → AnalyticsCollection.cpp} +55 -56
  38. data/ext/common/ApplicationPool2/Pool/{GarbageCollection.h → GarbageCollection.cpp} +49 -49
  39. data/ext/common/ApplicationPool2/Pool/GeneralUtils.cpp +241 -0
  40. data/ext/common/ApplicationPool2/Pool/GroupUtils.cpp +276 -0
  41. data/ext/common/ApplicationPool2/Pool/InitializationAndShutdown.cpp +145 -0
  42. data/ext/common/ApplicationPool2/Pool/Miscellaneous.cpp +244 -0
  43. data/ext/common/ApplicationPool2/Pool/ProcessUtils.cpp +330 -0
  44. data/ext/common/ApplicationPool2/Pool/StateInspection.cpp +299 -0
  45. data/ext/common/ApplicationPool2/Process.h +399 -205
  46. data/ext/common/ApplicationPool2/Session.h +70 -28
  47. data/ext/common/ApplicationPool2/Socket.h +1 -0
  48. data/ext/common/Constants.h +11 -3
  49. data/ext/common/Exceptions.h +1 -1
  50. data/ext/common/Logging.cpp +9 -4
  51. data/ext/common/Logging.h +6 -0
  52. data/ext/common/ServerKit/HttpServer.h +225 -215
  53. data/ext/common/ServerKit/Server.h +57 -57
  54. data/ext/common/SpawningKit/BackgroundIOCapturer.h +160 -0
  55. data/ext/common/SpawningKit/Config.h +107 -0
  56. data/ext/common/{ApplicationPool2 → SpawningKit}/DirectSpawner.h +17 -16
  57. data/ext/common/{ApplicationPool2 → SpawningKit}/DummySpawner.h +33 -33
  58. data/ext/common/{ApplicationPool2/SpawnerFactory.h → SpawningKit/Factory.h} +17 -17
  59. data/ext/common/{ApplicationPool2/ComponentInfo.h → SpawningKit/Options.h} +8 -21
  60. data/ext/common/SpawningKit/PipeWatcher.h +148 -0
  61. data/ext/common/{ApplicationPool2/PipeWatcher.h → SpawningKit/Result.h} +15 -33
  62. data/ext/common/{ApplicationPool2 → SpawningKit}/SmartSpawner.h +52 -57
  63. data/ext/common/{ApplicationPool2 → SpawningKit}/Spawner.h +83 -371
  64. data/ext/common/SpawningKit/UserSwitchingRules.h +265 -0
  65. data/ext/common/Utils/BufferedIO.h +24 -0
  66. data/ext/common/{ApplicationPool2/SpawnObject.h → Utils/ClassUtils.h} +24 -51
  67. data/ext/common/Utils/IOUtils.cpp +70 -0
  68. data/ext/common/Utils/IOUtils.h +19 -0
  69. data/ext/common/Utils/JsonUtils.h +113 -0
  70. data/ext/common/Utils/StrIntUtils.h +29 -0
  71. data/ext/common/Utils/json.h +1 -1
  72. data/ext/common/agents/ApiServerUtils.h +941 -0
  73. data/ext/common/agents/HelperAgent/{AdminServer.h → ApiServer.h} +163 -365
  74. data/ext/common/agents/HelperAgent/Main.cpp +86 -88
  75. data/ext/common/agents/HelperAgent/OptionParser.h +9 -10
  76. data/ext/common/agents/HelperAgent/RequestHandler/BufferBody.cpp +3 -0
  77. data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +2 -0
  78. data/ext/common/agents/HelperAgent/RequestHandler/Hooks.cpp +1 -1
  79. data/ext/common/agents/HelperAgent/RequestHandler/SendRequest.cpp +2 -2
  80. data/ext/common/agents/LoggingAgent/ApiServer.h +279 -0
  81. data/ext/common/agents/LoggingAgent/Main.cpp +41 -51
  82. data/ext/common/agents/LoggingAgent/OptionParser.h +11 -11
  83. data/ext/common/agents/Watchdog/ApiServer.h +311 -0
  84. data/ext/common/agents/Watchdog/Main.cpp +91 -65
  85. data/helper-scripts/prespawn +2 -0
  86. data/lib/phusion_passenger.rb +1 -1
  87. data/lib/phusion_passenger/admin_tools/instance.rb +1 -1
  88. data/lib/phusion_passenger/common_library.rb +27 -14
  89. data/lib/phusion_passenger/config/{admin_command_command.rb → api_call_command.rb} +19 -16
  90. data/lib/phusion_passenger/config/detach_process_command.rb +6 -3
  91. data/lib/phusion_passenger/config/main.rb +3 -5
  92. data/lib/phusion_passenger/config/reopen_logs_command.rb +29 -7
  93. data/lib/phusion_passenger/config/restart_app_command.rb +13 -4
  94. data/lib/phusion_passenger/config/utils.rb +15 -8
  95. data/lib/phusion_passenger/constants.rb +6 -2
  96. data/lib/phusion_passenger/platform_info/apache.rb +4 -0
  97. data/lib/phusion_passenger/platform_info/apache_detector.rb +18 -3
  98. data/resources/templates/apache2/mpm_unknown.txt.erb +20 -0
  99. metadata +42 -21
  100. metadata.gz.asc +7 -7
  101. data/ext/common/ApplicationPool2/Pool/GeneralUtils.h +0 -127
  102. data/ext/common/ApplicationPool2/Pool/Inspection.h +0 -219
  103. data/ext/common/ApplicationPool2/Pool/ProcessUtils.h +0 -85
  104. data/ext/common/ApplicationPool2/SuperGroup.h +0 -706
  105. data/ext/common/agents/LoggingAgent/AdminServer.h +0 -435
  106. data/ext/common/agents/Watchdog/AdminServer.h +0 -432
@@ -1002,6 +1002,7 @@ keepAliveAppConnection(Client *client, Request *req) {
1002
1002
  void
1003
1003
  storeAppResponseInTurboCache(Client *client, Request *req) {
1004
1004
  if (turboCaching.isEnabled() && !req->cacheKey.empty()) {
1005
+ TRACE_POINT();
1005
1006
  AppResponse *resp = &req->appResponse;
1006
1007
  unsigned int headerSize = 0;
1007
1008
  unsigned int i;
@@ -1013,6 +1014,7 @@ storeAppResponseInTurboCache(Client *client, Request *req) {
1013
1014
  turboCaching.responseCache.store(req, ev_now(getLoop()),
1014
1015
  headerSize, resp->bodyCacheBuffer.size));
1015
1016
  if (entry.valid()) {
1017
+ UPDATE_TRACE_POINT();
1016
1018
  SKC_DEBUG(client, "Storing app response in turbocache");
1017
1019
  SKC_TRACE(client, 2, "Turbocache entries:\n" << turboCaching.responseCache.inspect());
1018
1020
 
@@ -31,7 +31,7 @@ virtual unsigned int getClientName(const Client *client, char *buf, size_t size)
31
31
  char *pos = buf;
32
32
  const char *end = buf + size - 1;
33
33
  // WARNING: If you change the format, be sure to change
34
- // AdminServer::extractThreadNumberFromClientName() too.
34
+ // ApiServer::extractThreadNumberFromClientName() too.
35
35
  pos += uintToString(threadNumber, pos, end - pos);
36
36
  pos = appendData(pos, end, "-", 1);
37
37
  pos += uintToString(client->number, pos, end - pos);
@@ -290,7 +290,7 @@ determineHeaderSizeForSessionProtocol(Request *req,
290
290
  }
291
291
 
292
292
  dataSize += sizeof("PASSENGER_CONNECT_PASSWORD");
293
- dataSize += req->session->getGroupSecret().size() + 1;
293
+ dataSize += ApplicationPool2::ApiKey::SIZE + 1;
294
294
 
295
295
  if (req->https) {
296
296
  dataSize += sizeof("HTTPS");
@@ -404,7 +404,7 @@ constructHeaderForSessionProtocol(Request *req, char * restrict buffer, unsigned
404
404
  }
405
405
 
406
406
  pos = appendData(pos, end, P_STATIC_STRING_WITH_NULL("PASSENGER_CONNECT_PASSWORD"));
407
- pos = appendData(pos, end, req->session->getGroupSecret());
407
+ pos = appendData(pos, end, req->session->getApiKey().toStaticString());
408
408
  pos = appendData(pos, end, "", 1);
409
409
 
410
410
  if (req->https) {
@@ -0,0 +1,279 @@
1
+ /*
2
+ * Phusion Passenger - https://www.phusionpassenger.com/
3
+ * Copyright (c) 2013-2015 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_LOGGING_AGENT_API_SERVER_H_
26
+ #define _PASSENGER_LOGGING_AGENT_API_SERVER_H_
27
+
28
+ #include <sstream>
29
+ #include <string>
30
+
31
+ #include <agents/LoggingAgent/LoggingServer.h>
32
+ #include <agents/ApiServerUtils.h>
33
+ #include <ApplicationPool2/ApiKey.h>
34
+ #include <ServerKit/HttpServer.h>
35
+ #include <DataStructures/LString.h>
36
+ #include <Exceptions.h>
37
+ #include <StaticString.h>
38
+ #include <Utils/StrIntUtils.h>
39
+ #include <Utils/modp_b64.h>
40
+ #include <Utils/json.h>
41
+ #include <Utils/BufferedIO.h>
42
+ #include <Utils/MessageIO.h>
43
+
44
+ namespace Passenger {
45
+ namespace LoggingAgent {
46
+
47
+ using namespace std;
48
+
49
+
50
+ class Request: public ServerKit::BaseHttpRequest {
51
+ public:
52
+ string body;
53
+ Json::Value jsonBody;
54
+
55
+ DEFINE_SERVER_KIT_BASE_HTTP_REQUEST_FOOTER(Request);
56
+ };
57
+
58
+ class ApiServer: public ServerKit::HttpServer<ApiServer, ServerKit::HttpClient<Request> > {
59
+ private:
60
+ typedef ServerKit::HttpServer<ApiServer, ServerKit::HttpClient<Request> > ParentClass;
61
+ typedef ServerKit::HttpClient<Request> Client;
62
+ typedef ServerKit::HeaderTable HeaderTable;
63
+
64
+ void route(Client *client, Request *req, const StaticString &path) {
65
+ if (path == P_STATIC_STRING("/ping.json")) {
66
+ apiServerProcessPing(this, client, req);
67
+ } else if (path == P_STATIC_STRING("/version.json")) {
68
+ apiServerProcessVersion(this, client, req);
69
+ } else if (path == P_STATIC_STRING("/shutdown.json")) {
70
+ apiServerProcessShutdown(this, client, req);
71
+ } else if (path == P_STATIC_STRING("/backtraces.txt")) {
72
+ apiServerProcessBacktraces(this, client, req);
73
+ } else if (path == P_STATIC_STRING("/config.json")) {
74
+ processConfig(client, req);
75
+ } else if (path == P_STATIC_STRING("/reinherit_logs.json")) {
76
+ apiServerProcessReinheritLogs(this, client, req,
77
+ instanceDir, fdPassingPassword);
78
+ } else if (path == P_STATIC_STRING("/reopen_logs.json")) {
79
+ apiServerProcessReopenLogs(this, client, req);
80
+ } else if (path == P_STATIC_STRING("/status.txt")) {
81
+ processStatusTxt(client, req);
82
+ } else {
83
+ apiServerRespondWith404(this, client, req);
84
+ }
85
+ }
86
+
87
+ void processConfig(Client *client, Request *req) {
88
+ if (req->method == HTTP_GET) {
89
+ if (!authorizeStateInspectionOperation(this, client, req)) {
90
+ apiServerRespondWith401(this, client, req);
91
+ }
92
+
93
+ HeaderTable headers;
94
+ Json::Value doc;
95
+ string logFile = getLogFile();
96
+ string fileDescriptorLogFile = getFileDescriptorLogFile();
97
+
98
+ headers.insert(req->pool, "Content-Type", "application/json");
99
+ doc["log_level"] = getLogLevel();
100
+ if (!logFile.empty()) {
101
+ doc["log_file"] = logFile;
102
+ }
103
+ if (!fileDescriptorLogFile.empty()) {
104
+ doc["file_descriptor_log_file"] = fileDescriptorLogFile;
105
+ }
106
+
107
+ writeSimpleResponse(client, 200, &headers, doc.toStyledString());
108
+ if (!req->ended()) {
109
+ endRequest(&client, &req);
110
+ }
111
+ } else if (req->method == HTTP_PUT) {
112
+ if (!authorizeAdminOperation(this, client, req)) {
113
+ apiServerRespondWith401(this, client, req);
114
+ } else if (!req->hasBody()) {
115
+ endAsBadRequest(&client, &req, "Body required");
116
+ }
117
+ // Continue in processConfigBody()
118
+ } else {
119
+ apiServerRespondWith405(this, client, req);
120
+ }
121
+ }
122
+
123
+ void processConfigBody(Client *client, Request *req) {
124
+ HeaderTable headers;
125
+ Json::Value &json = req->jsonBody;
126
+
127
+ headers.insert(req->pool, "Content-Type", "application/json");
128
+
129
+ if (json.isMember("log_level")) {
130
+ setLogLevel(json["log_level"].asInt());
131
+ }
132
+ if (json.isMember("log_file")) {
133
+ string logFile = json["log_file"].asString();
134
+ try {
135
+ logFile = absolutizePath(logFile);
136
+ } catch (const SystemException &e) {
137
+ unsigned int bufsize = 1024;
138
+ char *message = (char *) psg_pnalloc(req->pool, bufsize);
139
+ snprintf(message, bufsize, "{ \"status\": \"error\", "
140
+ "\"message\": \"Cannot absolutize log file filename: %s\" }",
141
+ e.what());
142
+ writeSimpleResponse(client, 500, &headers, message);
143
+ if (!req->ended()) {
144
+ endRequest(&client, &req);
145
+ }
146
+ return;
147
+ }
148
+
149
+ int e;
150
+ if (!setLogFile(logFile, &e)) {
151
+ unsigned int bufsize = 1024;
152
+ char *message = (char *) psg_pnalloc(req->pool, bufsize);
153
+ snprintf(message, bufsize, "{ \"status\": \"error\", "
154
+ "\"message\": \"Cannot open log file: %s (errno=%d)\" }",
155
+ strerror(e), e);
156
+ writeSimpleResponse(client, 500, &headers, message);
157
+ if (!req->ended()) {
158
+ endRequest(&client, &req);
159
+ }
160
+ return;
161
+ }
162
+ P_NOTICE("Log file opened.");
163
+ }
164
+
165
+ writeSimpleResponse(client, 200, &headers, "{ \"status\": \"ok\" }\n");
166
+ if (!req->ended()) {
167
+ endRequest(&client, &req);
168
+ }
169
+ }
170
+
171
+ void processStatusTxt(Client *client, Request *req) {
172
+ if (req->method != HTTP_GET) {
173
+ apiServerRespondWith405(this, client, req);
174
+ } else if (authorizeStateInspectionOperation(this, client, req)) {
175
+ HeaderTable headers;
176
+ headers.insert(req->pool, "Content-Type", "text/plain");
177
+
178
+ stringstream stream;
179
+ loggingServer->dump(stream);
180
+ writeSimpleResponse(client, 200, &headers, stream.str());
181
+ if (!req->ended()) {
182
+ endRequest(&client, &req);
183
+ }
184
+ } else {
185
+ apiServerRespondWith401(this, client, req);
186
+ }
187
+ }
188
+
189
+ protected:
190
+ virtual void onRequestBegin(Client *client, Request *req) {
191
+ const StaticString path(req->path.start->data, req->path.size);
192
+
193
+ P_INFO("API request: " << http_method_str(req->method) <<
194
+ " " << StaticString(req->path.start->data, req->path.size));
195
+
196
+ try {
197
+ route(client, req, path);
198
+ } catch (const oxt::tracable_exception &e) {
199
+ SKC_ERROR(client, "Exception: " << e.what() << "\n" << e.backtrace());
200
+ if (!req->ended()) {
201
+ req->wantKeepAlive = false;
202
+ endRequest(&client, &req);
203
+ }
204
+ }
205
+ }
206
+
207
+ virtual ServerKit::Channel::Result onRequestBody(Client *client, Request *req,
208
+ const MemoryKit::mbuf &buffer, int errcode)
209
+ {
210
+ if (buffer.size() > 0) {
211
+ // Data
212
+ req->body.append(buffer.start, buffer.size());
213
+ } else if (errcode == 0) {
214
+ // EOF
215
+ Json::Reader reader;
216
+ if (reader.parse(req->body, req->jsonBody)) {
217
+ try {
218
+ processConfigBody(client, req);
219
+ } catch (const oxt::tracable_exception &e) {
220
+ SKC_ERROR(client, "Exception: " << e.what() << "\n" << e.backtrace());
221
+ if (!req->ended()) {
222
+ req->wantKeepAlive = false;
223
+ endRequest(&client, &req);
224
+ }
225
+ }
226
+ } else {
227
+ apiServerRespondWith422(this, client, req, reader.getFormattedErrorMessages());
228
+ }
229
+ } else {
230
+ // Error
231
+ disconnect(&client);
232
+ }
233
+ return ServerKit::Channel::Result(buffer.size(), false);
234
+ }
235
+
236
+ virtual void deinitializeRequest(Client *client, Request *req) {
237
+ req->body.clear();
238
+ if (!req->jsonBody.isNull()) {
239
+ req->jsonBody = Json::Value();
240
+ }
241
+ ParentClass::deinitializeRequest(client, req);
242
+ }
243
+
244
+ public:
245
+ LoggingServer *loggingServer;
246
+ ApiAccountDatabase *apiAccountDatabase;
247
+ string instanceDir;
248
+ string fdPassingPassword;
249
+ EventFd *exitEvent;
250
+
251
+ ApiServer(ServerKit::Context *context)
252
+ : ParentClass(context),
253
+ loggingServer(NULL),
254
+ apiAccountDatabase(NULL),
255
+ exitEvent(NULL)
256
+ { }
257
+
258
+ virtual StaticString getServerName() const {
259
+ return P_STATIC_STRING("LoggerApiServer");
260
+ }
261
+
262
+ virtual unsigned int getClientName(const Client *client, char *buf, size_t size) const {
263
+ return ParentClass::getClientName(client, buf, size);
264
+ }
265
+
266
+ bool authorizeByUid(uid_t uid) const {
267
+ return uid == 0 || uid == geteuid();
268
+ }
269
+
270
+ bool authorizeByApiKey(const ApplicationPool2::ApiKey &apiKey) const {
271
+ return apiKey.isSuper();
272
+ }
273
+ };
274
+
275
+
276
+ } // namespace LoggingAgent
277
+ } // namespace Passenger
278
+
279
+ #endif /* _PASSENGER_LOGGING_AGENT_API_SERVER_H_ */
@@ -22,6 +22,9 @@
22
22
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
  * THE SOFTWARE.
24
24
  */
25
+ // Include ev++.h early to avoid macro clash on EV_ERROR.
26
+ #include <ev++.h>
27
+
25
28
  #include <oxt/system_calls.hpp>
26
29
  #include <oxt/backtrace.hpp>
27
30
  #include <oxt/thread.hpp>
@@ -35,13 +38,15 @@
35
38
  #include <cstring>
36
39
  #include <cerrno>
37
40
  #include <algorithm>
41
+ #include <stdexcept>
38
42
  #include <stdlib.h>
39
43
  #include <signal.h>
40
44
 
41
45
  #include <agents/Base.h>
46
+ #include <agents/ApiServerUtils.h>
42
47
  #include <agents/LoggingAgent/OptionParser.h>
43
48
  #include <agents/LoggingAgent/LoggingServer.h>
44
- #include <agents/LoggingAgent/AdminServer.h>
49
+ #include <agents/LoggingAgent/ApiServer.h>
45
50
 
46
51
  #include <AccountsDatabase.h>
47
52
  #include <Account.h>
@@ -68,8 +73,8 @@ namespace LoggingAgent {
68
73
  struct WorkingObjects {
69
74
  string password;
70
75
  FileDescriptor serverSocketFd;
71
- vector<int> adminSockets;
72
- vector<LoggingAgent::AdminServer::Authorization> adminAuthorizations;
76
+ vector<int> apiSockets;
77
+ ApiAccountDatabase apiAccountDatabase;
73
78
 
74
79
  ResourceLocator *resourceLocator;
75
80
  BackgroundEventLoop *bgloop;
@@ -77,7 +82,7 @@ namespace LoggingAgent {
77
82
  AccountsDatabasePtr accountsDatabase;
78
83
  LoggingServer *loggingServer;
79
84
 
80
- LoggingAgent::AdminServer *adminServer;
85
+ LoggingAgent::ApiServer *apiServer;
81
86
  EventFd exitEvent;
82
87
  EventFd allClientsDisconnectedEvent;
83
88
 
@@ -109,7 +114,7 @@ static WorkingObjects *workingObjects;
109
114
 
110
115
  static void printInfo(EV_P_ struct ev_signal *watcher, int revents);
111
116
  static void onTerminationSignal(EV_P_ struct ev_signal *watcher, int revents);
112
- static void adminServerShutdownFinished(LoggingAgent::AdminServer *server);
117
+ static void apiServerShutdownFinished(LoggingAgent::ApiServer *server);
113
118
  static void waitForExitEvent();
114
119
 
115
120
  void
@@ -149,30 +154,6 @@ makeFileWorldReadableAndWritable(const string &path) {
149
154
  } while (ret == -1 && errno == EINTR);
150
155
  }
151
156
 
152
- static void
153
- parseAndAddAdminAuthorization(const string &description) {
154
- TRACE_POINT();
155
- WorkingObjects *wo = workingObjects;
156
- LoggingAgent::AdminServer::Authorization auth;
157
- vector<string> args;
158
-
159
- split(description, ':', args);
160
-
161
- if (args.size() == 2) {
162
- auth.level = LoggingAgent::AdminServer::FULL;
163
- auth.username = args[0];
164
- auth.password = strip(readAll(args[1]));
165
- } else if (args.size() == 3) {
166
- auth.level = LoggingAgent::AdminServer::parseLevel(args[0]);
167
- auth.username = args[1];
168
- auth.password = strip(readAll(args[2]));
169
- } else {
170
- P_BUG("Too many elements in authorization description");
171
- }
172
-
173
- wo->adminAuthorizations.push_back(auth);
174
- }
175
-
176
157
  static void
177
158
  initializePrivilegedWorkingObjects() {
178
159
  TRACE_POINT();
@@ -190,7 +171,11 @@ initializePrivilegedWorkingObjects() {
190
171
 
191
172
  UPDATE_TRACE_POINT();
192
173
  foreach (description, authorizations) {
193
- parseAndAddAdminAuthorization(description);
174
+ try {
175
+ wo->apiAccountDatabase.add(description);
176
+ } catch (const ArgumentException &e) {
177
+ throw std::runtime_error(e.what());
178
+ }
194
179
  }
195
180
 
196
181
  // Initialize ResourceLocator here in case passenger_root's parent
@@ -204,7 +189,7 @@ startListening() {
204
189
  const VariantMap &options = *agentsOptions;
205
190
  WorkingObjects *wo = workingObjects;
206
191
  string address;
207
- vector<string> adminAddresses;
192
+ vector<string> apiAddresses;
208
193
 
209
194
  address = options.get("logging_agent_address");
210
195
  wo->serverSocketFd.assign(createServer(address, 0, true,
@@ -216,13 +201,13 @@ startListening() {
216
201
  }
217
202
 
218
203
  UPDATE_TRACE_POINT();
219
- adminAddresses = options.getStrSet("logging_agent_admin_addresses",
204
+ apiAddresses = options.getStrSet("logging_agent_api_addresses",
220
205
  false);
221
- foreach (address, adminAddresses) {
222
- wo->adminSockets.push_back(createServer(address, 0, true,
206
+ foreach (address, apiAddresses) {
207
+ wo->apiSockets.push_back(createServer(address, 0, true,
223
208
  __FILE__, __LINE__));
224
- P_LOG_FILE_DESCRIPTOR_PURPOSE(wo->adminSockets.back(),
225
- "Server address: " << wo->adminSockets.back());
209
+ P_LOG_FILE_DESCRIPTOR_PURPOSE(wo->apiSockets.back(),
210
+ "Server address: " << wo->apiSockets.back());
226
211
  if (getSocketAddressType(address) == SAT_UNIX) {
227
212
  makeFileWorldReadableAndWritable(parseUnixSocketAddress(address));
228
213
  }
@@ -299,13 +284,15 @@ initializeUnprivilegedWorkingObjects() {
299
284
  wo->serverSocketFd, wo->accountsDatabase, options);
300
285
 
301
286
  UPDATE_TRACE_POINT();
302
- wo->adminServer = new LoggingAgent::AdminServer(wo->serverKitContext);
303
- wo->adminServer->loggingServer = wo->loggingServer;
304
- wo->adminServer->exitEvent = &wo->exitEvent;
305
- wo->adminServer->shutdownFinishCallback = adminServerShutdownFinished;
306
- wo->adminServer->authorizations = wo->adminAuthorizations;
307
- foreach (fd, wo->adminSockets) {
308
- wo->adminServer->listen(fd);
287
+ wo->apiServer = new LoggingAgent::ApiServer(wo->serverKitContext);
288
+ wo->apiServer->loggingServer = wo->loggingServer;
289
+ wo->apiServer->apiAccountDatabase = &wo->apiAccountDatabase;
290
+ wo->apiServer->instanceDir = options.get("instance_dir", false);
291
+ wo->apiServer->fdPassingPassword = options.get("watchdog_fd_passing_password", false);
292
+ wo->apiServer->exitEvent = &wo->exitEvent;
293
+ wo->apiServer->shutdownFinishCallback = apiServerShutdownFinished;
294
+ foreach (fd, wo->apiSockets) {
295
+ wo->apiServer->listen(fd);
309
296
  }
310
297
 
311
298
  UPDATE_TRACE_POINT();
@@ -362,12 +349,12 @@ mainLoop() {
362
349
  }
363
350
 
364
351
  static void
365
- shutdownAdminServer() {
366
- workingObjects->adminServer->shutdown();
352
+ shutdownApiServer() {
353
+ workingObjects->apiServer->shutdown();
367
354
  }
368
355
 
369
356
  static void
370
- adminServerShutdownFinished(LoggingAgent::AdminServer *server) {
357
+ apiServerShutdownFinished(LoggingAgent::ApiServer *server) {
371
358
  workingObjects->allClientsDisconnectedEvent.notify();
372
359
  }
373
360
 
@@ -410,7 +397,7 @@ waitForExitEvent() {
410
397
  /* We received an exit command. */
411
398
  P_NOTICE("Received command to shutdown gracefully. "
412
399
  "Waiting until all clients have disconnected...");
413
- wo->bgloop->safe->runLater(shutdownAdminServer);
400
+ wo->bgloop->safe->runLater(shutdownApiServer);
414
401
 
415
402
  UPDATE_TRACE_POINT();
416
403
  FD_ZERO(&fds);
@@ -433,7 +420,7 @@ cleanup() {
433
420
 
434
421
  P_DEBUG("Shutting down " AGENT_EXE " logger...");
435
422
  wo->bgloop->stop();
436
- delete wo->adminServer;
423
+ delete wo->apiServer;
437
424
  P_NOTICE(AGENT_EXE " logger shutdown finished");
438
425
  }
439
426
 
@@ -458,6 +445,9 @@ runLoggingAgent() {
458
445
  } catch (const tracable_exception &e) {
459
446
  P_ERROR("ERROR: " << e.what() << "\n" << e.backtrace());
460
447
  return 1;
448
+ } catch (const std::runtime_error &e) {
449
+ P_CRITICAL("ERROR: " << e.what());
450
+ return 1;
461
451
  }
462
452
 
463
453
  return 0;
@@ -500,11 +490,11 @@ preinitialize(VariantMap &options) {
500
490
  static void
501
491
  setAgentsOptionsDefaults() {
502
492
  VariantMap &options = *agentsOptions;
503
- set<string> defaultAdminListenAddress;
504
- defaultAdminListenAddress.insert(DEFAULT_LOGGING_AGENT_ADMIN_LISTEN_ADDRESS);
493
+ set<string> defaultApiListenAddress;
494
+ defaultApiListenAddress.insert(DEFAULT_LOGGING_AGENT_API_LISTEN_ADDRESS);
505
495
 
506
496
  options.setDefault("logging_agent_address", DEFAULT_LOGGING_AGENT_LISTEN_ADDRESS);
507
- options.setDefaultStrSet("logging_agent_admin_addresses", defaultAdminListenAddress);
497
+ options.setDefaultStrSet("logging_agent_api_addresses", defaultApiListenAddress);
508
498
  }
509
499
 
510
500
  static void