Merge ~pappacena/launchpad:gunicorn-experiments into launchpad:master
- Git
- lp:~pappacena/launchpad
- gunicorn-experiments
- Merge into master
Status: | Work in progress |
---|---|
Proposed branch: | ~pappacena/launchpad:gunicorn-experiments |
Merge into: | launchpad:master |
Diff against target: |
770 lines (+109/-272) 21 files modified
configs/development/gunicorn.conf.py (+6/-0) configs/development/launchpad-lazr.conf (+1/-0) configs/development/launchpad.conf (+0/-51) configs/test-playground/launchpad.conf (+0/-41) configs/testrunner-appserver/gunicorn.conf.py (+12/-0) configs/testrunner-appserver/launchpad.conf (+0/-20) configs/testrunner/launchpad.conf (+0/-41) dev/null (+0/-36) lib/lp/scripts/runlaunchpad.py (+21/-1) lib/lp/services/config/__init__.py (+4/-18) lib/lp/services/config/doc/canonical-config.txt (+0/-3) lib/lp/services/config/schema-lazr.conf (+6/-2) lib/lp/services/config/tests/test_config.py (+5/-3) lib/lp/services/webapp/configure.zcml (+0/-7) lib/lp/services/webapp/doc/webapp-publication.txt (+1/-3) lib/lp/services/webapp/publication.py (+2/-2) lib/lp/services/webapp/servers.py (+3/-40) lib/lp/startwsgi.py (+26/-0) lib/lp/testing/layers.py (+18/-0) setup.py (+4/-2) zcml/webapp.zcml (+0/-2) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Launchpad code reviewers | Pending | ||
Review via email: mp+396272@code.launchpad.net |
Commit message
[DONT MERGE] Experiments to use gunicorn instead of Zope Server.
Description of the change
This MP should not be merged. Instead, we will pave a way to migrate to gunicorn slowly to avoid big production disruption. But anyway, the changes here work with most (all?) tests running successfully and the dev server running smoothly (including auto-reload on code changes).
- 5fb6bd9... by Thiago F. Pappacena
-
Fixing port binding for brz acceptance tests
- 7927365... by Thiago F. Pappacena
-
Merge branch 'master' into gunicorn-
experiments - 40cd43d... by Thiago F. Pappacena
-
Pipe
- b7c3579... by Thiago F. Pappacena
-
Merge branch 'master' into gunicorn-
experiments - 03d978a... by Thiago F. Pappacena
-
Avoiding block gunicorn subprocess due to output buffer not beign consumed
- cca3c62... by Thiago F. Pappacena
-
Moving gunicorn config to its own file
- 8c5ac5f... by Thiago F. Pappacena
-
Fixing output buffer consumption on app server layer
- 6aef0db... by Thiago F. Pappacena
-
Merge branch 'master' into gunicorn-
experiments - f066609... by Thiago F. Pappacena
-
Autoreload in dev
- ce702df... by Thiago F. Pappacena
-
Using original HTTPPublication
RequestFactory on startwsgi
Unmerged commits
- ce702df... by Thiago F. Pappacena
-
Using original HTTPPublication
RequestFactory on startwsgi - f066609... by Thiago F. Pappacena
-
Autoreload in dev
- 6aef0db... by Thiago F. Pappacena
-
Merge branch 'master' into gunicorn-
experiments - 8c5ac5f... by Thiago F. Pappacena
-
Fixing output buffer consumption on app server layer
- cca3c62... by Thiago F. Pappacena
-
Moving gunicorn config to its own file
- 03d978a... by Thiago F. Pappacena
-
Avoiding block gunicorn subprocess due to output buffer not beign consumed
- b7c3579... by Thiago F. Pappacena
-
Merge branch 'master' into gunicorn-
experiments - 40cd43d... by Thiago F. Pappacena
-
Pipe
- 7927365... by Thiago F. Pappacena
-
Merge branch 'master' into gunicorn-
experiments - 5fb6bd9... by Thiago F. Pappacena
-
Fixing port binding for brz acceptance tests
Preview Diff
1 | diff --git a/configs/development/gunicorn.conf.py b/configs/development/gunicorn.conf.py |
2 | new file mode 100644 |
3 | index 0000000..b667109 |
4 | --- /dev/null |
5 | +++ b/configs/development/gunicorn.conf.py |
6 | @@ -0,0 +1,6 @@ |
7 | +bind = [":8085", ":8086", ":8087", ":8088", ":8089"] |
8 | +workers = 2 |
9 | +threads = 10 |
10 | +max_requests = 1000 |
11 | +log_level = "DEBUG" |
12 | +reload = True |
13 | diff --git a/configs/development/launchpad-lazr.conf b/configs/development/launchpad-lazr.conf |
14 | index a4956f3..e56bdd8 100644 |
15 | --- a/configs/development/launchpad-lazr.conf |
16 | +++ b/configs/development/launchpad-lazr.conf |
17 | @@ -223,6 +223,7 @@ hostname: xmlrpc.launchpad.test |
18 | |
19 | [vhost.xmlrpc_private] |
20 | hostname: xmlrpc-private.launchpad.test |
21 | +private_port: 8087 |
22 | |
23 | [vhost.feeds] |
24 | hostname: feeds.launchpad.test |
25 | diff --git a/configs/development/launchpad.conf b/configs/development/launchpad.conf |
26 | index fe7e088..8281e09 100644 |
27 | --- a/configs/development/launchpad.conf |
28 | +++ b/configs/development/launchpad.conf |
29 | @@ -5,52 +5,11 @@ site-definition zcml/webapp.zcml |
30 | # Turn on Zope3 developer mode. |
31 | devmode on |
32 | |
33 | -# number of bytecode instructions to execute between checks for |
34 | -# interruptions (SIGINTR, thread switches): |
35 | -interrupt-check-interval 200 |
36 | - |
37 | -<server> |
38 | - type HTTP |
39 | - address 8085 |
40 | -</server> |
41 | - |
42 | -# For debugging purposes, you can use this publisher instead/as well |
43 | -# (obviously if it's as well, use a different port number). If there's |
44 | -# an exception, Zope will drop into pdb at the point of the exception. |
45 | -<server> |
46 | - type PostmortemDebuggingHTTP |
47 | - address 8088 |
48 | -</server> |
49 | - |
50 | -<server> |
51 | - type DebugLayerHTTP |
52 | - address 8086 |
53 | -</server> |
54 | - |
55 | -<server> |
56 | - type PrivateXMLRPC |
57 | - address 8087 |
58 | -</server> |
59 | - |
60 | # non-persistent in-memory storage |
61 | <zodb> |
62 | <mappingstorage/> |
63 | </zodb> |
64 | |
65 | -<accesslog> |
66 | - # This sets up logging to both a file (access.log) and to standard |
67 | - # output (STDOUT). The "path" setting can be a relative or absolute |
68 | - # filesystem path or the tokens STDOUT or STDERR. |
69 | - |
70 | - <logfile> |
71 | - path logs/launchpad-access.log |
72 | - </logfile> |
73 | - |
74 | - <logfile> |
75 | - path STDOUT |
76 | - </logfile> |
77 | -</accesslog> |
78 | - |
79 | <eventlog> |
80 | # This sets up logging to both a file (z3.log) and to standard |
81 | # output (STDOUT). The "path" setting can be a relative or absolute |
82 | @@ -65,13 +24,3 @@ interrupt-check-interval 200 |
83 | </logfile> |
84 | </eventlog> |
85 | |
86 | -<logger> |
87 | - name zc.tracelog |
88 | - propagate false |
89 | - |
90 | - <logfile> |
91 | - format %(message)s |
92 | - path logs/trace.log |
93 | - </logfile> |
94 | - |
95 | -</logger> |
96 | diff --git a/configs/test-playground/launchpad.conf b/configs/test-playground/launchpad.conf |
97 | index ec8095a..0ce913b 100644 |
98 | --- a/configs/test-playground/launchpad.conf |
99 | +++ b/configs/test-playground/launchpad.conf |
100 | @@ -5,52 +5,11 @@ site-definition zcml/webapp.zcml |
101 | # Turn on Zope3 developer mode. |
102 | devmode on |
103 | |
104 | -# number of bytecode instructions to execute between checks for |
105 | -# interruptions (SIGINTR, thread switches): |
106 | -interrupt-check-interval 200 |
107 | - |
108 | -<server> |
109 | - type HTTP |
110 | - address 8085 |
111 | -</server> |
112 | - |
113 | -# For debugging purposes, you can use this publisher instead/as well |
114 | -# (obviously if it's as well, use a different port number). If there's |
115 | -# an exception, Zope will drop into pdb at the point of the exception. |
116 | -<server> |
117 | - type PostmortemDebuggingHTTP |
118 | - address 8089 |
119 | -</server> |
120 | - |
121 | -<server> |
122 | - type DebugLayerHTTP |
123 | - address 8086 |
124 | -</server> |
125 | - |
126 | -<server> |
127 | - type PrivateXMLRPC |
128 | - address 8087 |
129 | -</server> |
130 | - |
131 | # non-persistent in-memory storage |
132 | <zodb> |
133 | <mappingstorage/> |
134 | </zodb> |
135 | |
136 | -<accesslog> |
137 | - # This sets up logging to both a file (access.log) and to standard |
138 | - # output (STDOUT). The "path" setting can be a relative or absolute |
139 | - # filesystem path or the tokens STDOUT or STDERR. |
140 | - |
141 | - <logfile> |
142 | - path logs/launchpad-access.log |
143 | - </logfile> |
144 | - |
145 | - <logfile> |
146 | - path STDOUT |
147 | - </logfile> |
148 | -</accesslog> |
149 | - |
150 | <eventlog> |
151 | # This sets up logging to both a file (z3.log) and to standard |
152 | # output (STDOUT). The "path" setting can be a relative or absolute |
153 | diff --git a/configs/testrunner-appserver/gunicorn.conf.py b/configs/testrunner-appserver/gunicorn.conf.py |
154 | new file mode 100644 |
155 | index 0000000..ba22ec1 |
156 | --- /dev/null |
157 | +++ b/configs/testrunner-appserver/gunicorn.conf.py |
158 | @@ -0,0 +1,12 @@ |
159 | +import os |
160 | +config_dir = os.path.dirname(__file__) |
161 | +log_dir = os.path.join(config_dir, '..', '..', 'logs') |
162 | + |
163 | +bind = [":8085", ":8087"] |
164 | +workers = 1 |
165 | +threads = 10 |
166 | +log_level = "DEBUG" |
167 | + |
168 | +log_file = os.path.join(log_dir, 'gunicorn.log') |
169 | +error_logfile = os.path.join(log_dir, 'gunicorn-error.log') |
170 | +access_logfile = os.path.join(log_dir, 'gunicorn-access.log') |
171 | diff --git a/configs/testrunner-appserver/launchpad.conf b/configs/testrunner-appserver/launchpad.conf |
172 | index 2f9ce03..dde05d8 100644 |
173 | --- a/configs/testrunner-appserver/launchpad.conf |
174 | +++ b/configs/testrunner-appserver/launchpad.conf |
175 | @@ -7,31 +7,11 @@ site-definition zcml/webapp.zcml |
176 | # Make this work a little more like production. |
177 | devmode off |
178 | |
179 | -# number of bytecode instructions to execute between checks for |
180 | -# interruptions (SIGINTR, thread switches): |
181 | -interrupt-check-interval 200 |
182 | - |
183 | -<server> |
184 | - type HTTP |
185 | - address 8085 |
186 | -</server> |
187 | - |
188 | -<server> |
189 | - type PrivateXMLRPC |
190 | - address 8087 |
191 | -</server> |
192 | - |
193 | # non-persistent in-memory storage |
194 | <zodb> |
195 | <mappingstorage/> |
196 | </zodb> |
197 | |
198 | -<accesslog> |
199 | - <logfile> |
200 | - path logs/test-appserver-layer.log |
201 | - </logfile> |
202 | -</accesslog> |
203 | - |
204 | <eventlog> |
205 | <logfile> |
206 | path logs/test-appserver-layer.log |
207 | diff --git a/configs/testrunner/launchpad.conf b/configs/testrunner/launchpad.conf |
208 | index e1aee02..252fd3e 100644 |
209 | --- a/configs/testrunner/launchpad.conf |
210 | +++ b/configs/testrunner/launchpad.conf |
211 | @@ -5,52 +5,11 @@ site-definition zcml/webapp.zcml |
212 | # Turn on Zope3 developer mode. |
213 | devmode on |
214 | |
215 | -# number of bytecode instructions to execute between checks for |
216 | -# interruptions (SIGINTR, thread switches): |
217 | -interrupt-check-interval 200 |
218 | - |
219 | -<server> |
220 | - type HTTP |
221 | - address 8085 |
222 | -</server> |
223 | - |
224 | -# For debugging purposes, you can use this publisher instead/as well |
225 | -# (obviously if it's as well, use a different port number). If there's |
226 | -# an exception, Zope will drop into pdb at the point of the exception. |
227 | -<server> |
228 | - type PostmortemDebuggingHTTP |
229 | - address 8089 |
230 | -</server> |
231 | - |
232 | -<server> |
233 | - type DebugLayerHTTP |
234 | - address 8086 |
235 | -</server> |
236 | - |
237 | -<server> |
238 | - type PrivateXMLRPC |
239 | - address 8087 |
240 | -</server> |
241 | - |
242 | # non-persistent in-memory storage |
243 | <zodb> |
244 | <mappingstorage/> |
245 | </zodb> |
246 | |
247 | -<accesslog> |
248 | - # This sets up logging to both a file (access.log) and to standard |
249 | - # output (STDOUT). The "path" setting can be a relative or absolute |
250 | - # filesystem path or the tokens STDOUT or STDERR. |
251 | - |
252 | - <logfile> |
253 | - path logs/launchpad-access.log |
254 | - </logfile> |
255 | - |
256 | - <logfile> |
257 | - path STDOUT |
258 | - </logfile> |
259 | -</accesslog> |
260 | - |
261 | <eventlog> |
262 | # This sets up logging to both a file (z3.log) and to standard |
263 | # output (STDOUT). The "path" setting can be a relative or absolute |
264 | diff --git a/lib/lp/scripts/runlaunchpad.py b/lib/lp/scripts/runlaunchpad.py |
265 | index 969cfd6..42f2806 100644 |
266 | --- a/lib/lp/scripts/runlaunchpad.py |
267 | +++ b/lib/lp/scripts/runlaunchpad.py |
268 | @@ -6,6 +6,9 @@ from __future__ import absolute_import, print_function, unicode_literals |
269 | __metaclass__ = type |
270 | __all__ = ['start_launchpad'] |
271 | |
272 | +import six |
273 | +from talisker import run_gunicorn |
274 | + |
275 | try: |
276 | from contextlib import ExitStack |
277 | except ImportError: |
278 | @@ -16,10 +19,10 @@ import subprocess |
279 | import sys |
280 | |
281 | import fixtures |
282 | +from gunicorn.app.wsgiapp import WSGIApplication |
283 | from lazr.config import as_host_port |
284 | from rabbitfixture.server import RabbitServerResources |
285 | from testtools.testresult.real import _details_to_str |
286 | -from zope.app.server.main import main |
287 | |
288 | from lp.services.config import config |
289 | from lp.services.daemons import tachandler |
290 | @@ -331,6 +334,23 @@ def start_testapp(argv=list(sys.argv)): |
291 | pass |
292 | |
293 | |
294 | +def main(argv): |
295 | + orig_argv = sys.argv |
296 | + try: |
297 | + # This is a bit hacky, but talisker gets the arguments directly from |
298 | + # sys.argv. There is no way to send it using parameters. We set it |
299 | + # back as soon as run_gunicorn finishes. |
300 | + sys.argv = [ |
301 | + os.path.join(config.root, "bin", "talisker.gunicorn"), |
302 | + "lp.startwsgi", |
303 | + "-c", os.path.join(config.config_dir, "gunicorn.conf.py") |
304 | + ] |
305 | + run_gunicorn() |
306 | + return |
307 | + finally: |
308 | + sys.argv = orig_argv |
309 | + |
310 | + |
311 | def start_launchpad(argv=list(sys.argv), setup=None): |
312 | # We really want to replace this with a generic startup harness. |
313 | # However, this should last us until this is developed |
314 | diff --git a/lib/lp/services/config/__init__.py b/lib/lp/services/config/__init__.py |
315 | index 9d43346..c7828a8 100644 |
316 | --- a/lib/lp/services/config/__init__.py |
317 | +++ b/lib/lp/services/config/__init__.py |
318 | @@ -30,6 +30,7 @@ from six.moves.urllib.parse import ( |
319 | urlunparse, |
320 | ) |
321 | import ZConfig |
322 | +from zope.app.appsetup import appsetup |
323 | |
324 | from lp.services.osutils import open_for_writing |
325 | |
326 | @@ -124,6 +125,7 @@ class LaunchpadConfig: |
327 | else: |
328 | self._process_name = process_name |
329 | self._instance_name = instance_name |
330 | + self._devmode = None |
331 | self.root = TREE_ROOT |
332 | |
333 | def _make_process_name(self): |
334 | @@ -165,7 +167,6 @@ class LaunchpadConfig: |
335 | """Invalidate the config, causing the config to be regenerated.""" |
336 | self._config = None |
337 | self._devmode = None |
338 | - self._servers = None |
339 | |
340 | def reloadConfig(self): |
341 | """Reload the config.""" |
342 | @@ -246,15 +247,6 @@ class LaunchpadConfig: |
343 | """Return the path to the ZConfig file for this instance.""" |
344 | return os.path.join(self.config_dir, 'launchpad.conf') |
345 | |
346 | - def _getZConfig(self): |
347 | - """Modify the config, adding automatically generated settings""" |
348 | - with resources.path('zope.app.server', 'schema.xml') as schemafile: |
349 | - schema = ZConfig.loadSchema(str(schemafile)) |
350 | - root_options, handlers = ZConfig.loadConfig( |
351 | - schema, self.zope_config_file) |
352 | - self._devmode = root_options.devmode |
353 | - self._servers = root_options.servers |
354 | - |
355 | @property |
356 | def devmode(self): |
357 | """Devmode from the zope.app.server.main config. |
358 | @@ -262,20 +254,14 @@ class LaunchpadConfig: |
359 | Copied here for ease of access. |
360 | """ |
361 | if self._devmode is None: |
362 | - self._getZConfig() |
363 | + self._getConfig() |
364 | + self._devmode = self._config.launchpad.devmode |
365 | return self._devmode |
366 | |
367 | @devmode.setter |
368 | def devmode(self, value): |
369 | self._devmode = value |
370 | |
371 | - @property |
372 | - def servers(self): |
373 | - """The defined servers.""" |
374 | - if self._servers is None: |
375 | - self._getZConfig() |
376 | - return self._servers |
377 | - |
378 | def generate_overrides(self): |
379 | """Ensure correct config.zcml overrides will be called. |
380 | |
381 | diff --git a/lib/lp/services/config/doc/canonical-config.txt b/lib/lp/services/config/doc/canonical-config.txt |
382 | index 91f676b..7b70660 100644 |
383 | --- a/lib/lp/services/config/doc/canonical-config.txt |
384 | +++ b/lib/lp/services/config/doc/canonical-config.txt |
385 | @@ -86,9 +86,6 @@ ZConfig. |
386 | >>> config.devmode |
387 | True |
388 | |
389 | - >>> len(config.servers) |
390 | - 4 |
391 | - |
392 | |
393 | Working with test configurations |
394 | -------------------------------- |
395 | diff --git a/lib/lp/services/config/schema-lazr.conf b/lib/lp/services/config/schema-lazr.conf |
396 | index aaa9d30..f4d9193 100644 |
397 | --- a/lib/lp/services/config/schema-lazr.conf |
398 | +++ b/lib/lp/services/config/schema-lazr.conf |
399 | @@ -539,7 +539,6 @@ storm_cache_size: 10000 |
400 | # datatype: existing_directory |
401 | replication_logdir: database/replication |
402 | |
403 | - |
404 | [diff] |
405 | # The maximum size in bytes to read from the librarian to make available in |
406 | # the web UI. 512k == 524288 bytes. |
407 | @@ -841,8 +840,9 @@ dbuser: karma |
408 | # datatype: integer |
409 | max_scaling: 500 |
410 | |
411 | - |
412 | [launchpad] |
413 | +devmode: true |
414 | + |
415 | # A directory of files from which *-lazr.conf will be loaded and |
416 | # overlaid in order on top of the main config. |
417 | # Note that this is relative to the top-level config file, not |
418 | @@ -1640,6 +1640,10 @@ althostnames: none |
419 | # datatype: string |
420 | rooturl: none |
421 | |
422 | +# Is this vhost enabled? |
423 | +# Used to create the correct publishers |
424 | +private_port: None |
425 | + |
426 | [vhost.mainsite] |
427 | # Can the profile page act as a OpenID delegated identity? |
428 | # data-type: boolean |
429 | diff --git a/lib/lp/services/config/tests/test_config.py b/lib/lp/services/config/tests/test_config.py |
430 | index 34921fd..faf37a0 100644 |
431 | --- a/lib/lp/services/config/tests/test_config.py |
432 | +++ b/lib/lp/services/config/tests/test_config.py |
433 | @@ -25,6 +25,7 @@ from lazr.config.interfaces import ConfigErrors |
434 | import scandir |
435 | import testtools |
436 | import ZConfig |
437 | +from zope.app.appsetup import appsetup |
438 | |
439 | import lp.services.config |
440 | from lp.services.config.fixture import ConfigUseFixture |
441 | @@ -33,8 +34,8 @@ from lp.services.config.fixture import ConfigUseFixture |
442 | EXCLUDED_CONFIGS = ['lpnet-template'] |
443 | |
444 | # Calculate some landmark paths. |
445 | -with resources.path('zope.app.server', 'schema.xml') as schema_file: |
446 | - schema = ZConfig.loadSchema(str(schema_file)) |
447 | +schema = os.path.join( |
448 | + os.path.dirname(appsetup.__file__), 'schema', 'schema.xml') |
449 | |
450 | here = os.path.dirname(lp.services.config.__file__) |
451 | lazr_schema_file = os.path.join(here, 'schema-lazr.conf') |
452 | @@ -42,7 +43,8 @@ lazr_schema_file = os.path.join(here, 'schema-lazr.conf') |
453 | |
454 | def make_test(config_file, description): |
455 | def test_function(): |
456 | - root, handlers = ZConfig.loadConfig(schema, config_file) |
457 | + loaded_schema = ZConfig.loadSchema(schema) |
458 | + root, handlers = ZConfig.loadConfig(loaded_schema, config_file) |
459 | # Hack the config file name into test_function's __name__ so that the test |
460 | # -vv output is more informative. Unfortunately, FunctionTestCase's |
461 | # description argument doesn't do what we want. |
462 | diff --git a/lib/lp/services/webapp/configure.zcml b/lib/lp/services/webapp/configure.zcml |
463 | index 95f495d..6642ec3 100644 |
464 | --- a/lib/lp/services/webapp/configure.zcml |
465 | +++ b/lib/lp/services/webapp/configure.zcml |
466 | @@ -8,7 +8,6 @@ |
467 | xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc" |
468 | i18n_domain="launchpad"> |
469 | |
470 | - <include file="servers.zcml" /> |
471 | <include file="errorlog.zcml" /> |
472 | |
473 | <browser:defaultView name="index.html" /> |
474 | @@ -354,12 +353,6 @@ |
475 | handler="lp.services.webapp.sigdumpmem.setup_sigdumpmem" |
476 | /> |
477 | |
478 | - <!-- Confirm that no main thread event handlers use the connection cache --> |
479 | - <subscriber |
480 | - for="zope.processlifetime.IProcessStarting" |
481 | - handler="lp.services.webapp.adapter.break_main_thread_db_access" |
482 | - /> |
483 | - |
484 | <!-- Set the default timeout function. --> |
485 | <subscriber |
486 | for="zope.processlifetime.IProcessStarting" |
487 | diff --git a/lib/lp/services/webapp/doc/webapp-publication.txt b/lib/lp/services/webapp/doc/webapp-publication.txt |
488 | index ffe6a69..9b8b53e 100644 |
489 | --- a/lib/lp/services/webapp/doc/webapp-publication.txt |
490 | +++ b/lib/lp/services/webapp/doc/webapp-publication.txt |
491 | @@ -417,9 +417,7 @@ listens on a particular port. |
492 | |
493 | Find the port the Private XMLRPC service is listening on. |
494 | |
495 | - >>> for server in config.servers: |
496 | - ... if server.type == 'PrivateXMLRPC': |
497 | - ... private_port = server.address[1] |
498 | + >>> private_port = config.vhost.xmlrpc_private.private_port |
499 | |
500 | >>> print_request_and_publication( |
501 | ... 'xmlrpc-private.launchpad.test', method='POST', |
502 | diff --git a/lib/lp/services/webapp/publication.py b/lib/lp/services/webapp/publication.py |
503 | index 7325d9f..6b1beea 100644 |
504 | --- a/lib/lp/services/webapp/publication.py |
505 | +++ b/lib/lp/services/webapp/publication.py |
506 | @@ -28,7 +28,6 @@ from storm.exceptions import ( |
507 | ) |
508 | from storm.zope.interfaces import IZStorm |
509 | import transaction |
510 | -from zc.zservertracelog.interfaces import ITraceLog |
511 | import zope.app.publication.browser |
512 | from zope.authentication.interfaces import IUnauthenticatedPrincipal |
513 | from zope.component import ( |
514 | @@ -871,6 +870,7 @@ def tracelog(request, prefix, msg): |
515 | easier. ``prefix`` should be unique and contain no spaces, and |
516 | preferably a single character to save space. |
517 | """ |
518 | - tracelog = ITraceLog(request, None) |
519 | + #tracelog = ITraceLog(request, None) |
520 | + tracelog = None |
521 | if tracelog is not None: |
522 | tracelog.log('%s %s' % (prefix, six.ensure_str(msg, 'US-ASCII'))) |
523 | diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py |
524 | index d7bcad2..d592c96 100644 |
525 | --- a/lib/lp/services/webapp/servers.py |
526 | +++ b/lib/lp/services/webapp/servers.py |
527 | @@ -23,13 +23,11 @@ from six.moves import xmlrpc_client |
528 | from six.moves.urllib.parse import parse_qs |
529 | import transaction |
530 | from transaction.interfaces import ISynchronizer |
531 | -from zc.zservertracelog.tracelog import Server as ZServerTracelogServer |
532 | from zope.app.publication.httpfactory import HTTPPublicationRequestFactory |
533 | from zope.app.publication.interfaces import IRequestPublicationFactory |
534 | from zope.app.publication.requestpublicationregistry import ( |
535 | factoryRegistry as publisher_factory_registry, |
536 | ) |
537 | -from zope.app.server import wsgi |
538 | from zope.app.wsgi import WSGIPublisherApplication |
539 | from zope.component import getUtility |
540 | from zope.formlib.itemswidgets import MultiDataHelper |
541 | @@ -1111,36 +1109,6 @@ class LaunchpadAccessLogger(CommonAccessLogger): |
542 | ) |
543 | |
544 | |
545 | -http = wsgi.ServerType( |
546 | - ZServerTracelogServer, # subclass of WSGIHTTPServer |
547 | - WSGIPublisherApplication, |
548 | - LaunchpadAccessLogger, |
549 | - 8080, |
550 | - True) |
551 | - |
552 | -pmhttp = wsgi.ServerType( |
553 | - PMDBWSGIHTTPServer, |
554 | - WSGIPublisherApplication, |
555 | - LaunchpadAccessLogger, |
556 | - 8081, |
557 | - True) |
558 | - |
559 | -debughttp = wsgi.ServerType( |
560 | - ZServerTracelogServer, # subclass of WSGIHTTPServer |
561 | - WSGIPublisherApplication, |
562 | - LaunchpadAccessLogger, |
563 | - 8082, |
564 | - True, |
565 | - requestFactory=DebugLayerRequestFactory) |
566 | - |
567 | -privatexmlrpc = wsgi.ServerType( |
568 | - ZServerTracelogServer, # subclass of WSGIHTTPServer |
569 | - WSGIPublisherApplication, |
570 | - LaunchpadAccessLogger, |
571 | - 8080, |
572 | - True) |
573 | - |
574 | - |
575 | # ---- mainsite |
576 | |
577 | class MainLaunchpadPublication(LaunchpadBrowserPublication): |
578 | @@ -1576,16 +1544,11 @@ def register_launchpad_request_publication_factories(): |
579 | TestOpenIDBrowserPublication)) |
580 | |
581 | # We may also have a private XML-RPC server. |
582 | - private_port = None |
583 | - for server in config.servers: |
584 | - if server.type == 'PrivateXMLRPC': |
585 | - ip, private_port = server.address |
586 | - break |
587 | - |
588 | - if private_port is not None: |
589 | + if config.vhost.xmlrpc_private.private_port: |
590 | factories.append(XMLRPCRequestPublicationFactory( |
591 | 'xmlrpc_private', PrivateXMLRPCRequest, |
592 | - PrivateXMLRPCPublication, port=private_port)) |
593 | + PrivateXMLRPCPublication, |
594 | + port=config.vhost.xmlrpc_private.private_port)) |
595 | |
596 | # Register those factories, in priority order corresponding to |
597 | # their order in the list. This means picking a large number for |
598 | diff --git a/lib/lp/services/webapp/servers.zcml b/lib/lp/services/webapp/servers.zcml |
599 | deleted file mode 100644 |
600 | index 0235cd2..0000000 |
601 | --- a/lib/lp/services/webapp/servers.zcml |
602 | +++ /dev/null |
603 | @@ -1,36 +0,0 @@ |
604 | -<!-- Copyright 2009 Canonical Ltd. This software is licensed under the |
605 | - GNU Affero General Public License version 3 (see the file LICENSE). |
606 | ---> |
607 | - |
608 | -<configure xmlns="http://namespaces.zope.org/zope"> |
609 | - <!-- This is the HTTP server, set up to do ZODB-free publication. --> |
610 | - <utility |
611 | - name="HTTP" |
612 | - component="lp.services.webapp.servers.http" |
613 | - provides="zope.app.server.servertype.IServerType" |
614 | - /> |
615 | - |
616 | - <!-- This is the HTTP server, with post-mortem debugging support, |
617 | - set up to do ZODB-free publication. --> |
618 | - <utility |
619 | - name="PostmortemDebuggingHTTP" |
620 | - component="lp.services.webapp.servers.pmhttp" |
621 | - provides="zope.app.server.servertype.IServerType" |
622 | - /> |
623 | - |
624 | - <!-- This is the HTTP server, but making each request have the |
625 | - DebugLayer as the first layer searched. Effectively, this turns |
626 | - on the debug error pages. --> |
627 | - <utility |
628 | - name="DebugLayerHTTP" |
629 | - component="lp.services.webapp.servers.debughttp" |
630 | - provides="zope.app.server.servertype.IServerType" |
631 | - /> |
632 | - |
633 | - <utility |
634 | - name="PrivateXMLRPC" |
635 | - component="lp.services.webapp.servers.privatexmlrpc" |
636 | - provides="zope.app.server.servertype.IServerType" |
637 | - /> |
638 | - |
639 | -</configure> |
640 | diff --git a/lib/lp/startwsgi.py b/lib/lp/startwsgi.py |
641 | new file mode 100644 |
642 | index 0000000..92da007 |
643 | --- /dev/null |
644 | +++ b/lib/lp/startwsgi.py |
645 | @@ -0,0 +1,26 @@ |
646 | +# Copyright 2021 Canonical Ltd. This software is licensed under the |
647 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
648 | + |
649 | +"""WSGI script to start web server.""" |
650 | + |
651 | +from __future__ import absolute_import, print_function, unicode_literals |
652 | + |
653 | +__metaclass__ = type |
654 | +__all__ = [] |
655 | + |
656 | +from zope.app.publication.httpfactory import HTTPPublicationRequestFactory |
657 | +from zope.app.wsgi import ( |
658 | + getWSGIApplication, |
659 | + ) |
660 | +from zope.event import notify |
661 | +import zope.processlifetime |
662 | + |
663 | +from lp.services.config import config |
664 | + |
665 | + |
666 | +application = getWSGIApplication( |
667 | + config.zope_config_file, |
668 | + requestFactory=HTTPPublicationRequestFactory |
669 | +) |
670 | + |
671 | +notify(zope.processlifetime.ProcessStarting()) |
672 | diff --git a/lib/lp/testing/layers.py b/lib/lp/testing/layers.py |
673 | index 9089c60..e0722fd 100644 |
674 | --- a/lib/lp/testing/layers.py |
675 | +++ b/lib/lp/testing/layers.py |
676 | @@ -48,6 +48,7 @@ __all__ = [ |
677 | 'reconnect_stores', |
678 | ] |
679 | |
680 | +import select |
681 | from cProfile import Profile |
682 | import datetime |
683 | import errno |
684 | @@ -80,6 +81,7 @@ from six.moves.urllib.parse import ( |
685 | urlparse, |
686 | ) |
687 | from six.moves.urllib.request import urlopen |
688 | +from six.moves.urllib.error import HTTPError |
689 | import transaction |
690 | from webob.request import environ_from_url as orig_environ_from_url |
691 | import wsgi_intercept |
692 | @@ -1794,6 +1796,14 @@ class LayerProcessController: |
693 | raise LayerIsolationError( |
694 | "App server died in this test (status=%s):\n%s" % ( |
695 | cls.appserver.returncode, cls.appserver.stdout.read())) |
696 | + # Cleanup the app server's output buffer between tests. |
697 | + while True: |
698 | + # Read while we have something available at the stdout. |
699 | + r, w, e = select.select([cls.appserver.stdout], [], [], 0) |
700 | + if cls.appserver.stdout in r: |
701 | + cls.appserver.stdout.readline() |
702 | + else: |
703 | + break |
704 | DatabaseLayer.force_dirty_database() |
705 | |
706 | @classmethod |
707 | @@ -1820,7 +1830,9 @@ class LayerProcessController: |
708 | environ['LPCONFIG'] = _config.instance_name |
709 | cls.appserver = subprocess.Popen( |
710 | cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, |
711 | + stdin=subprocess.PIPE, |
712 | env=environ, cwd=_config.root) |
713 | + cls.appserver.stdin.close() |
714 | |
715 | @classmethod |
716 | def appserver_root_url(cls): |
717 | @@ -1836,6 +1848,12 @@ class LayerProcessController: |
718 | try: |
719 | connection = urlopen(root_url) |
720 | connection.read() |
721 | + except HTTPError as error: |
722 | + if error.code == 503: |
723 | + raise RuntimeError( |
724 | + "App server is returning unknown error code %s. Is " |
725 | + "there another instance running in the same port?" % |
726 | + error.code) |
727 | except URLError as error: |
728 | # We are interested in a wrapped socket.error. |
729 | if not isinstance(error.reason, socket.error): |
730 | diff --git a/setup.py b/setup.py |
731 | index b5696f3..49c56e0 100644 |
732 | --- a/setup.py |
733 | +++ b/setup.py |
734 | @@ -233,6 +233,8 @@ setup( |
735 | 'Sphinx', |
736 | 'statsd', |
737 | 'storm', |
738 | + 'subvertpy', |
739 | + 'talisker[gunicorn]', |
740 | 'tenacity', |
741 | 'testscenarios', |
742 | 'testtools', |
743 | @@ -252,7 +254,6 @@ setup( |
744 | 'zope.app.http', |
745 | 'zope.app.publication', |
746 | 'zope.app.publisher', |
747 | - 'zope.app.server', |
748 | 'zope.app.wsgi[testlayer]', |
749 | 'zope.authentication', |
750 | 'zope.browser', |
751 | @@ -333,6 +334,7 @@ setup( |
752 | 'version-info = lp.scripts.utilities.versioninfo:main', |
753 | 'watch_jsbuild = lp.scripts.utilities.js.watchjsbuild:main', |
754 | 'with-xvfb = lp.scripts.utilities.withxvfb:main', |
755 | - ] |
756 | + ], |
757 | + wsgi=["wsigogogo = lp.startwsgi.gogogo"] |
758 | ), |
759 | ) |
760 | diff --git a/zcml/webapp.zcml b/zcml/webapp.zcml |
761 | index 948c4eb..a574200 100644 |
762 | --- a/zcml/webapp.zcml |
763 | +++ b/zcml/webapp.zcml |
764 | @@ -14,6 +14,4 @@ |
765 | <includeOverrides file="+config-overrides.zcml" /> |
766 | |
767 | <include file="summarizerequests.zcml" /> |
768 | - <include package="zc.zservertracelog" /> |
769 | - |
770 | </configure> |