Mercurial > bitten > bitten-test
annotate bitten/master.py @ 872:f320205ca1f9
Ensure that master only sends utf-8 bodies (especially errors are prone to contain strings of unknown origin, potentially unicode).
author | osimons |
---|---|
date | Tue, 19 Oct 2010 20:55:13 +0000 |
parents | 59acaa8b52c0 |
children |
rev | line source |
---|---|
379 | 1 # -*- coding: utf-8 -*- |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
2 # |
832 | 3 # Copyright (C) 2007-2010 Edgewall Software |
408
933105ab516b
Update file headers and other stuff pointing to the old home.
cmlenz
parents:
402
diff
changeset
|
4 # Copyright (C) 2005-2007 Christopher Lenz <cmlenz@gmx.de> |
163 | 5 # All rights reserved. |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
6 # |
163 | 7 # This software is licensed as described in the file COPYING, which |
8 # you should have received as part of this distribution. The terms | |
408
933105ab516b
Update file headers and other stuff pointing to the old home.
cmlenz
parents:
402
diff
changeset
|
9 # are also available at http://bitten.edgewall.org/wiki/License. |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
10 |
392 | 11 """Build master implementation.""" |
313 | 12 |
312 | 13 import calendar |
392 | 14 import re |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
15 import time |
629
f3bb52da9e3c
0.6dev: Adding support for attachments to configurations and build - full web implementation that mirrors what is available in Ticket and Wiki. Also added a new generic `<attach/>` command that enables attaching files to be part of a recipe and uploaded by slaves as part of build.
osimons
parents:
611
diff
changeset
|
16 from StringIO import StringIO |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
17 |
629
f3bb52da9e3c
0.6dev: Adding support for attachments to configurations and build - full web implementation that mirrors what is available in Ticket and Wiki. Also added a new generic `<attach/>` command that enables attaching files to be part of a recipe and uploaded by slaves as part of build.
osimons
parents:
611
diff
changeset
|
18 from trac.attachment import Attachment |
577
dcee8ff20e82
0.6dev: The `logs_dir` option is not a real `PathOption` as for that it would need to support config-relative path with possibly chained configs following trac:ticket:8358 (for 0.11.5). The fix just makes it a regular `Option` to keep current behaviour for all Trac 0.11+ versions.
osimons
parents:
568
diff
changeset
|
19 from trac.config import BoolOption, IntOption, Option |
392 | 20 from trac.core import * |
629
f3bb52da9e3c
0.6dev: Adding support for attachments to configurations and build - full web implementation that mirrors what is available in Ticket and Wiki. Also added a new generic `<attach/>` command that enables attaching files to be part of a recipe and uploaded by slaves as part of build.
osimons
parents:
611
diff
changeset
|
21 from trac.resource import ResourceNotFound |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
22 from trac.web import IRequestHandler, RequestDone |
392 | 23 |
654
cc1fefd5d814
0.6dev: Moved a constant declaration so that master should still work with Python 2.4. Updated docs with regards to Python requirements + added a changelog message from cmlenz.
osimons
parents:
649
diff
changeset
|
24 from bitten import PROTOCOL_VERSION |
554
2c27f3581100
Supply the target platform as a variable `platform` for build recipes, and adjust test accordingly - fixes #376
dfraser
parents:
542
diff
changeset
|
25 from bitten.model import BuildConfig, Build, BuildStep, BuildLog, Report, \ |
2c27f3581100
Supply the target platform as a variable `platform` for build recipes, and adjust test accordingly - fixes #376
dfraser
parents:
542
diff
changeset
|
26 TargetPlatform |
2c27f3581100
Supply the target platform as a variable `platform` for build recipes, and adjust test accordingly - fixes #376
dfraser
parents:
542
diff
changeset
|
27 |
410
7930cdd83d13
More restructuring: got rid of the `trac_ext` subpackage, which makes no sense now that the master is also coupled to Trac.
cmlenz
parents:
408
diff
changeset
|
28 from bitten.main import BuildSystem |
227
014bc6c29dff
* Factor build queue logic into a class separate from the build master.
cmlenz
parents:
213
diff
changeset
|
29 from bitten.queue import BuildQueue |
392 | 30 from bitten.recipe import Recipe |
31 from bitten.util import xmlio | |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
32 |
411
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
410
diff
changeset
|
33 __all__ = ['BuildMaster'] |
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
410
diff
changeset
|
34 __docformat__ = 'restructuredtext en' |
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
410
diff
changeset
|
35 |
56 | 36 |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
37 HTTP_BAD_REQUEST = 400 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
38 HTTP_FORBIDDEN = 403 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
39 HTTP_NOT_FOUND = 404 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
40 HTTP_METHOD_NOT_ALLOWED = 405 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
41 HTTP_CONFLICT = 409 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
42 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
43 |
392 | 44 class BuildMaster(Component): |
542 | 45 """Trac request handler implementation for the build master.""" |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
46 |
392 | 47 implements(IRequestHandler) |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
48 |
392 | 49 # Configuration options |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
50 |
392 | 51 adjust_timestamps = BoolOption('bitten', 'adjust_timestamps', False, doc= |
432 | 52 """Whether the timestamps of builds should be adjusted to be close |
392 | 53 to the timestamps of the corresponding changesets.""") |
54 | |
55 build_all = BoolOption('bitten', 'build_all', False, doc= | |
56 """Whether to request builds of older revisions even if a younger | |
57 revision has already been built.""") | |
762
5f0cfee44540
Add new last_activity field to build. I considered reusing stopped, but this seemed cleaner and more obvious, which seems like the right way to go.
wbell
parents:
761
diff
changeset
|
58 |
468
44c2b4ac6157
Add stabilization time parameter to build master. Closes #189. Many thanks to Allen Bierbaum for the patch.
cmlenz
parents:
466
diff
changeset
|
59 stabilize_wait = IntOption('bitten', 'stabilize_wait', 0, doc= |
44c2b4ac6157
Add stabilization time parameter to build master. Closes #189. Many thanks to Allen Bierbaum for the patch.
cmlenz
parents:
466
diff
changeset
|
60 """The time in seconds to wait for the repository to stabilize before |
44c2b4ac6157
Add stabilization time parameter to build master. Closes #189. Many thanks to Allen Bierbaum for the patch.
cmlenz
parents:
466
diff
changeset
|
61 queuing up a new build. This allows time for developers to check in |
44c2b4ac6157
Add stabilization time parameter to build master. Closes #189. Many thanks to Allen Bierbaum for the patch.
cmlenz
parents:
466
diff
changeset
|
62 a group of related changes back to back without spawning multiple |
44c2b4ac6157
Add stabilization time parameter to build master. Closes #189. Many thanks to Allen Bierbaum for the patch.
cmlenz
parents:
466
diff
changeset
|
63 builds.""") |
392 | 64 |
65 slave_timeout = IntOption('bitten', 'slave_timeout', 3600, doc= | |
66 """The time in seconds after which a build is cancelled if the slave | |
67 does not report progress.""") | |
68 | |
577
dcee8ff20e82
0.6dev: The `logs_dir` option is not a real `PathOption` as for that it would need to support config-relative path with possibly chained configs following trac:ticket:8358 (for 0.11.5). The fix just makes it a regular `Option` to keep current behaviour for all Trac 0.11+ versions.
osimons
parents:
568
diff
changeset
|
69 logs_dir = Option('bitten', 'logs_dir', "log/bitten", doc= |
516
2f3b7c17d3c3
Switch to storing log messages in files rather than in database rows:
dfraser
parents:
494
diff
changeset
|
70 """The directory on the server in which client log files will be stored.""") |
2f3b7c17d3c3
Switch to storing log messages in files rather than in database rows:
dfraser
parents:
494
diff
changeset
|
71 |
557
b4d3d9cbf200
Alter the appearance of the ''Build Status'' button, to show the current build status [eblot] - fixes #373
dfraser
parents:
554
diff
changeset
|
72 quick_status = BoolOption('bitten', 'quick_status', False, doc= |
806
b62562828364
Improved documentation for the quick-status in navigation. See performance discussion at #536.
osimons
parents:
804
diff
changeset
|
73 """Whether to show the current build status within the Trac main |
b62562828364
Improved documentation for the quick-status in navigation. See performance discussion at #536.
osimons
parents:
804
diff
changeset
|
74 navigation bar. '''Note:''' The feature requires expensive database and |
b62562828364
Improved documentation for the quick-status in navigation. See performance discussion at #536.
osimons
parents:
804
diff
changeset
|
75 repository checks for every page request, and should not be enabled |
b62562828364
Improved documentation for the quick-status in navigation. See performance discussion at #536.
osimons
parents:
804
diff
changeset
|
76 if the project has a large repository or uses a non-Subversion |
b62562828364
Improved documentation for the quick-status in navigation. See performance discussion at #536.
osimons
parents:
804
diff
changeset
|
77 repository such as Mercurial or Git.""") |
557
b4d3d9cbf200
Alter the appearance of the ''Build Status'' button, to show the current build status [eblot] - fixes #373
dfraser
parents:
554
diff
changeset
|
78 |
568 | 79 def __init__(self): |
80 self.env.systeminfo.append(('Bitten', | |
81 __import__('bitten', ['__version__']).__version__)) | |
82 | |
392 | 83 # IRequestHandler methods |
84 | |
85 def match_request(self, req): | |
401
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
86 match = re.match(r'/builds(?:/(\d+)(?:/(\w+)/([^/]+)?)?)?$', |
392 | 87 req.path_info) |
88 if match: | |
89 if match.group(1): | |
90 req.args['id'] = match.group(1) | |
91 req.args['collection'] = match.group(2) | |
92 req.args['member'] = match.group(3) | |
93 return True | |
94 | |
95 def process_request(self, req): | |
96 req.perm.assert_permission('BUILD_EXEC') | |
97 | |
649
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
98 if 'trac_auth' in req.incookie: |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
99 slave_token = req.incookie['trac_auth'].value |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
100 else: |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
101 slave_token = req.session.sid |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
102 |
392 | 103 if 'id' not in req.args: |
104 if req.method != 'POST': | |
715
cd4405466a77
Add a `referer=` argument when logging in, and redirect to a Bitten URL so that slave doesn't need non-build permissions. Closes #459.
osimons
parents:
701
diff
changeset
|
105 self._send_response(req, |
cd4405466a77
Add a `referer=` argument when logging in, and redirect to a Bitten URL so that slave doesn't need non-build permissions. Closes #459.
osimons
parents:
701
diff
changeset
|
106 body='Only POST allowed for build creation.') |
649
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
107 return self._process_build_creation(req, slave_token) |
392 | 108 |
109 build = Build.fetch(self.env, req.args['id']) | |
110 if not build: | |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
111 self._send_error(req, HTTP_NOT_FOUND, |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
112 'No such build (%s)' % req.args['id']) |
649
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
113 |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
114 build_token = build.slave_info.get('token', '') |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
115 if build_token != slave_token: |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
116 self._send_error(req, HTTP_CONFLICT, |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
117 'Token mismatch (wrong slave): slave=%s, build=%s' \ |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
118 % (slave_token, build_token)) |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
119 |
392 | 120 config = BuildConfig.fetch(self.env, build.config) |
121 | |
122 if not req.args['collection']: | |
420
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
123 if req.method == 'DELETE': |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
124 return self._process_build_cancellation(req, config, build) |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
125 else: |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
126 return self._process_build_initiation(req, config, build) |
392 | 127 |
401
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
128 if req.method != 'POST': |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
129 self._send_error(req, HTTP_METHOD_NOT_ALLOWED, |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
130 'Method %s not allowed' % req.method) |
392 | 131 |
132 if req.args['collection'] == 'steps': | |
401
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
133 return self._process_build_step(req, config, build) |
835
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
134 elif req.args['collection'] == 'attach': |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
135 return self._process_attachment(req, config, build) |
785
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
136 elif req.args['collection'] == 'keepalive': |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
137 return self._process_keepalive(req, config, build) |
392 | 138 else: |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
139 self._send_error(req, HTTP_NOT_FOUND, |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
140 "No such collection '%s'" % req.args['collection']) |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
141 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
142 # Internal methods |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
143 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
144 def _send_response(self, req, code=200, body='', headers=None): |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
145 """ Formats and sends the response, raising ``RequestDone``. """ |
872
f320205ca1f9
Ensure that master only sends utf-8 bodies (especially errors are prone to contain strings of unknown origin, potentially unicode).
osimons
parents:
835
diff
changeset
|
146 if isinstance(body, unicode): |
f320205ca1f9
Ensure that master only sends utf-8 bodies (especially errors are prone to contain strings of unknown origin, potentially unicode).
osimons
parents:
835
diff
changeset
|
147 body = body.encode('utf-8') |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
148 req.send_response(code) |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
149 headers = headers or {} |
701
492c18db8f45
Set the `'Content-Length'` header on master-slave communication. Needed to be http/1.1 compatible. Fixes #475.
osimons
parents:
654
diff
changeset
|
150 headers.setdefault('Content-Length', len(body)) |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
151 for header in headers: |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
152 req.send_header(header, headers[header]) |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
153 req.write(body) |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
154 raise RequestDone |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
155 |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
156 def _send_error(self, req, code=500, message=''): |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
157 """ Formats and sends the error, raising ``RequestDone``. """ |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
158 headers = {'Content-Type': 'text/plain', |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
159 'Content-Length': str(len(message))} |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
160 self._send_response(req, code, body=message, headers=headers) |
392 | 161 |
649
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
162 def _process_build_creation(self, req, slave_token): |
762
5f0cfee44540
Add new last_activity field to build. I considered reusing stopped, but this seemed cleaner and more obvious, which seems like the right way to go.
wbell
parents:
761
diff
changeset
|
163 queue = BuildQueue(self.env, build_all=self.build_all, |
468
44c2b4ac6157
Add stabilization time parameter to build master. Closes #189. Many thanks to Allen Bierbaum for the patch.
cmlenz
parents:
466
diff
changeset
|
164 stabilize_wait=self.stabilize_wait, |
419
b72802dc0632
Fix resetting of builds when multiple slaves are building simultaneously, and implement the `slave_timeout` trac.ini option.
cmlenz
parents:
411
diff
changeset
|
165 timeout=self.slave_timeout) |
804
4c73a3cea9f5
Basic Trac 0.12 support, supporting just a `(default)` repository - essentially Trac 0.11 behaviour. Thanks to those that have contributed to #480 to get this working and tested.
osimons
parents:
785
diff
changeset
|
166 try: |
4c73a3cea9f5
Basic Trac 0.12 support, supporting just a `(default)` repository - essentially Trac 0.11 behaviour. Thanks to those that have contributed to #480 to get this working and tested.
osimons
parents:
785
diff
changeset
|
167 queue.populate() |
4c73a3cea9f5
Basic Trac 0.12 support, supporting just a `(default)` repository - essentially Trac 0.11 behaviour. Thanks to those that have contributed to #480 to get this working and tested.
osimons
parents:
785
diff
changeset
|
168 except AssertionError, e: |
4c73a3cea9f5
Basic Trac 0.12 support, supporting just a `(default)` repository - essentially Trac 0.11 behaviour. Thanks to those that have contributed to #480 to get this working and tested.
osimons
parents:
785
diff
changeset
|
169 self.log.error(e.message, exc_info=True) |
4c73a3cea9f5
Basic Trac 0.12 support, supporting just a `(default)` repository - essentially Trac 0.11 behaviour. Thanks to those that have contributed to #480 to get this working and tested.
osimons
parents:
785
diff
changeset
|
170 self._send_error(req, HTTP_BAD_REQUEST, e.message) |
392 | 171 |
172 try: | |
173 elem = xmlio.parse(req.read()) | |
174 except xmlio.ParseError, e: | |
492
56f0ad35c60a
Log errors when build master encounters an XML parse error.
cmlenz
parents:
479
diff
changeset
|
175 self.log.error('Error parsing build initialization request: %s', e, |
56f0ad35c60a
Log errors when build master encounters an XML parse error.
cmlenz
parents:
479
diff
changeset
|
176 exc_info=True) |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
177 self._send_error(req, HTTP_BAD_REQUEST, 'XML parser error') |
392 | 178 |
649
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
179 slave_version = int(elem.attr.get('version', 1)) |
785
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
180 |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
181 # FIXME: Remove version compatibility code. |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
182 # The initial difference between protocol version 3 and 4 is that |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
183 # the master allows keepalive requests-- the master must be |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
184 # at least 4 before slaves supporting version 4 are allowed. When |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
185 # the first force master/slave upgrade requirement comes in |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
186 # (or we bump the) version number again, remove this code. |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
187 if slave_version == 3 and PROTOCOL_VERSION == 4: |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
188 self.log.info('Allowing slave version %d to process build for ' |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
189 'compatibility. Upgrade slave to support build ' |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
190 'keepalives.', slave_version) |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
191 elif slave_version != PROTOCOL_VERSION: |
649
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
192 self._send_error(req, HTTP_BAD_REQUEST, |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
193 "Master-Slave version mismatch: master=%d, slave=%d" % \ |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
194 (PROTOCOL_VERSION, slave_version)) |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
195 |
426 | 196 slavename = elem.attr['name'] |
649
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
197 properties = {'name': slavename, Build.IP_ADDRESS: req.remote_addr, |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
198 Build.TOKEN: slave_token} |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
199 self.log.info('Build slave %r connected from %s with token %s', |
eed0149c302a
0.6dev: Switching to use the new cookie-support, and using trac auth/session ID as unique identification for linking builds with slaves. This overcomes problems with IP address not being unique behind NAT, and also where IP address may change during a build. Closes #421.
osimons
parents:
645
diff
changeset
|
200 slavename, req.remote_addr, slave_token) |
392 | 201 |
202 for child in elem.children(): | |
203 if child.name == 'platform': | |
204 properties[Build.MACHINE] = child.gettext() | |
205 properties[Build.PROCESSOR] = child.attr.get('processor') | |
206 elif child.name == 'os': | |
207 properties[Build.OS_NAME] = child.gettext() | |
208 properties[Build.OS_FAMILY] = child.attr.get('family') | |
209 properties[Build.OS_VERSION] = child.attr.get('version') | |
210 elif child.name == 'package': | |
211 for name, value in child.attr.items(): | |
212 if name == 'name': | |
213 continue | |
214 properties[child.attr['name'] + '.' + name] = value | |
215 | |
444
22d6a7da8777
Another minor improvement to logging in the build master.
cmlenz
parents:
436
diff
changeset
|
216 self.log.debug('Build slave configuration: %r', properties) |
22d6a7da8777
Another minor improvement to logging in the build master.
cmlenz
parents:
436
diff
changeset
|
217 |
426 | 218 build = queue.get_build_for_slave(slavename, properties) |
392 | 219 if not build: |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
220 self._send_response(req, 204, '', {}) |
392 | 221 |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
222 self._send_response(req, 201, 'Build pending', headers={ |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
223 'Content-Type': 'text/plain', |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
224 'Location': req.abs_href.builds(build.id)}) |
392 | 225 |
420
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
226 def _process_build_cancellation(self, req, config, build): |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
227 self.log.info('Build slave %r cancelled build %d', build.slave, |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
228 build.id) |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
229 build.status = Build.PENDING |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
230 build.slave = None |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
231 build.slave_info = {} |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
232 build.started = 0 |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
233 db = self.env.get_db_cnx() |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
234 for step in list(BuildStep.select(self.env, build=build.id, db=db)): |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
235 step.delete(db=db) |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
236 build.update(db=db) |
745
91aabd647610
Delete attachments when builds are cancelled/invalidated.
wbell
parents:
715
diff
changeset
|
237 |
91aabd647610
Delete attachments when builds are cancelled/invalidated.
wbell
parents:
715
diff
changeset
|
238 Attachment.delete_all(self.env, 'build', build.resource.id, db) |
91aabd647610
Delete attachments when builds are cancelled/invalidated.
wbell
parents:
715
diff
changeset
|
239 |
420
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
240 db.commit() |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
241 |
458 | 242 for listener in BuildSystem(self.env).listeners: |
243 listener.build_aborted(build) | |
244 | |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
245 self._send_response(req, 204, '', {}) |
420
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
246 |
392 | 247 def _process_build_initiation(self, req, config, build): |
420
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
248 self.log.info('Build slave %r initiated build %d', build.slave, |
23de253435b8
Slaves now attempt to explicitly cancel builds when they are interrupted.
cmlenz
parents:
419
diff
changeset
|
249 build.id) |
392 | 250 build.started = int(time.time()) |
762
5f0cfee44540
Add new last_activity field to build. I considered reusing stopped, but this seemed cleaner and more obvious, which seems like the right way to go.
wbell
parents:
761
diff
changeset
|
251 build.last_activity = build.started |
392 | 252 build.update() |
277 | 253 |
458 | 254 for listener in BuildSystem(self.env).listeners: |
255 listener.build_started(build) | |
256 | |
287
6abd43d0cd8a
The build slave now stores snapshot archives and the corresponding work directories in project folders of the main work folder, to keep build configurations from different projects that share the same name separate. This also requires transmitting the project name (simply the name of the environment directory) with the build initiation.
cmlenz
parents:
284
diff
changeset
|
257 xml = xmlio.parse(config.recipe) |
392 | 258 xml.attr['path'] = config.path |
259 xml.attr['revision'] = build.rev | |
466
79be3c00ae69
Applied patch to #188 for stable/configurable names of build directories. Thanks to Allen Bierbaum for the patch.
cmlenz
parents:
463
diff
changeset
|
260 xml.attr['config'] = config.name |
79be3c00ae69
Applied patch to #188 for stable/configurable names of build directories. Thanks to Allen Bierbaum for the patch.
cmlenz
parents:
463
diff
changeset
|
261 xml.attr['build'] = str(build.id) |
554
2c27f3581100
Supply the target platform as a variable `platform` for build recipes, and adjust test accordingly - fixes #376
dfraser
parents:
542
diff
changeset
|
262 target_platform = TargetPlatform.fetch(self.env, build.platform) |
2c27f3581100
Supply the target platform as a variable `platform` for build recipes, and adjust test accordingly - fixes #376
dfraser
parents:
542
diff
changeset
|
263 xml.attr['platform'] = target_platform.name |
611
294641e84e89
0.6dev: Adding `${name}` and `${basedir}` (#325) for recipe substitution. Updated docs + new test.
osimons
parents:
577
diff
changeset
|
264 xml.attr['name'] = build.slave |
835
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
265 xml.attr['form_token'] = req.form_token # For posting attachments |
392 | 266 body = str(xml) |
374
446092a2d2fe
Don't accept build results from a slave if the build has been invalidated or it's being built by another slave. Closes #100.
wbell
parents:
373
diff
changeset
|
267 |
473
b1d346c4e539
Only accept build results from the slave that's supposed to be processing this build. Additional logging.
wbell
parents:
468
diff
changeset
|
268 self.log.info('Build slave %r initiated build %d', build.slave, |
b1d346c4e539
Only accept build results from the slave that's supposed to be processing this build. Additional logging.
wbell
parents:
468
diff
changeset
|
269 build.id) |
b1d346c4e539
Only accept build results from the slave that's supposed to be processing this build. Additional logging.
wbell
parents:
468
diff
changeset
|
270 |
761
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
271 # create the first step, mark it as in-progress. |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
272 |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
273 recipe = Recipe(xmlio.parse(config.recipe)) |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
274 stepname = recipe.__iter__().next().id |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
275 |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
276 step = self._start_new_step(build, stepname) |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
277 step.insert() |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
278 |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
279 self._send_response(req, 200, body, headers={ |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
280 'Content-Type': 'application/x-bitten+xml', |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
281 'Content-Length': str(len(body)), |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
282 'Content-Disposition': |
392 | 283 'attachment; filename=recipe_%s_r%s.xml' % |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
284 (config.name, build.rev)}) |
227
014bc6c29dff
* Factor build queue logic into a class separate from the build master.
cmlenz
parents:
213
diff
changeset
|
285 |
401
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
286 def _process_build_step(self, req, config, build): |
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
287 try: |
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
288 elem = xmlio.parse(req.read()) |
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
289 except xmlio.ParseError, e: |
492
56f0ad35c60a
Log errors when build master encounters an XML parse error.
cmlenz
parents:
479
diff
changeset
|
290 self.log.error('Error parsing build step result: %s', e, |
56f0ad35c60a
Log errors when build master encounters an XML parse error.
cmlenz
parents:
479
diff
changeset
|
291 exc_info=True) |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
292 self._send_error(req, HTTP_BAD_REQUEST, 'XML parser error') |
401
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
293 stepname = elem.attr['step'] |
632
01c9848950d5
0.6dev: Cleaning all usage of tabs (replaced with spaces).
osimons
parents:
629
diff
changeset
|
294 |
761
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
295 # we should have created this step previously; if it hasn't, |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
296 # the master and slave are processing steps out of order. |
392 | 297 step = BuildStep.fetch(self.env, build=build.id, name=stepname) |
761
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
298 if not step: |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
299 self._send_error(req, HTTP_CONFLICT, 'Build step has not been created.') |
253 | 300 |
392 | 301 recipe = Recipe(xmlio.parse(config.recipe)) |
302 index = None | |
303 current_step = None | |
304 for num, recipe_step in enumerate(recipe): | |
305 if recipe_step.id == stepname: | |
306 index = num | |
307 current_step = recipe_step | |
308 if index is None: | |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
309 self._send_error(req, HTTP_FORBIDDEN, |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
310 'No such build step' % stepname) |
392 | 311 last_step = index == num |
200
692924ffed80
Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents:
197
diff
changeset
|
312 |
494
9c9bf7a69bf0
Apply patch by Emmanuel Blot to allow a single slave to connect to multiple masters. Closes #271.
cmlenz
parents:
492
diff
changeset
|
313 self.log.debug('Slave %s (build %d) completed step %d (%s) with ' |
9c9bf7a69bf0
Apply patch by Emmanuel Blot to allow a single slave to connect to multiple masters. Closes #271.
cmlenz
parents:
492
diff
changeset
|
314 'status %s', build.slave, build.id, index, stepname, |
9c9bf7a69bf0
Apply patch by Emmanuel Blot to allow a single slave to connect to multiple masters. Closes #271.
cmlenz
parents:
492
diff
changeset
|
315 elem.attr['status']) |
392 | 316 |
317 db = self.env.get_db_cnx() | |
318 | |
761
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
319 step.stopped = int(time.time()) |
758
d11ef8024d7c
Make all times be generated by the server. This eliminates a number of inconsistencies you'll see when the clocks on the slaves are skewed from the master.
wbell
parents:
754
diff
changeset
|
320 |
392 | 321 if elem.attr['status'] == 'failure': |
322 self.log.warning('Build %s step %s failed', build.id, stepname) | |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
323 step.status = BuildStep.FAILURE |
459 | 324 if current_step.onerror == 'fail': |
325 last_step = True | |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
326 else: |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
327 step.status = BuildStep.SUCCESS |
277 | 328 step.errors += [error.gettext() for error in elem.children('error')] |
761
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
329 |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
330 # TODO: step.update(db=db) |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
331 step.delete(db=db) |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
332 step.insert(db=db) |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
333 |
392 | 334 # Collect log messages from the request body |
203
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
335 for idx, log_elem in enumerate(elem.children('log')): |
401
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
336 build_log = BuildLog(self.env, build=build.id, step=stepname, |
203
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
337 generator=log_elem.attr.get('generator'), |
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
338 orderno=idx) |
115
16d69eb6e047
Add support for XML fragments to the {{{xmlio}}} module, so that build output and reports don't need to be nested in a meaningless element (such as {{{<log type="distutils"><messages><message ...>}}}).
cmlenz
parents:
112
diff
changeset
|
339 for message_elem in log_elem.children('message'): |
16d69eb6e047
Add support for XML fragments to the {{{xmlio}}} module, so that build output and reports don't need to be nested in a meaningless element (such as {{{<log type="distutils"><messages><message ...>}}}).
cmlenz
parents:
112
diff
changeset
|
340 build_log.messages.append((message_elem.attr['level'], |
16d69eb6e047
Add support for XML fragments to the {{{xmlio}}} module, so that build output and reports don't need to be nested in a meaningless element (such as {{{<log type="distutils"><messages><message ...>}}}).
cmlenz
parents:
112
diff
changeset
|
341 message_elem.gettext())) |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
342 build_log.insert(db=db) |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
343 |
392 | 344 # Collect report data from the request body |
203
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
345 for report_elem in elem.children('report'): |
401
a10942252ebc
Use POST for submitting step results, instead of PUT.
cmlenz
parents:
392
diff
changeset
|
346 report = Report(self.env, build=build.id, step=stepname, |
213
25f84dd9f159
* Refactoring of build recipes, the file format has changed slightly:
cmlenz
parents:
204
diff
changeset
|
347 category=report_elem.attr.get('category'), |
25f84dd9f159
* Refactoring of build recipes, the file format has changed slightly:
cmlenz
parents:
204
diff
changeset
|
348 generator=report_elem.attr.get('generator')) |
203
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
349 for item_elem in report_elem.children(): |
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
350 item = {'type': item_elem.name} |
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
351 item.update(item_elem.attr) |
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
352 for child_elem in item_elem.children(): |
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
353 item[child_elem.name] = child_elem.gettext() |
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
354 report.items.append(item) |
e6ddca1e5712
Huge refactoring to remove dependency on BDB XML. Report data is now stored in the Trac database (SQLite/PostgreSQL).
cmlenz
parents:
202
diff
changeset
|
355 report.insert(db=db) |
116 | 356 |
392 | 357 # If this was the last step in the recipe we mark the build as |
762
5f0cfee44540
Add new last_activity field to build. I considered reusing stopped, but this seemed cleaner and more obvious, which seems like the right way to go.
wbell
parents:
761
diff
changeset
|
358 # completed otherwise just update last_activity |
459 | 359 if last_step: |
392 | 360 self.log.info('Slave %s completed build %d ("%s" as of [%s])', |
361 build.slave, build.id, build.config, build.rev) | |
362 build.stopped = step.stopped | |
762
5f0cfee44540
Add new last_activity field to build. I considered reusing stopped, but this seemed cleaner and more obvious, which seems like the right way to go.
wbell
parents:
761
diff
changeset
|
363 build.last_activity = build.stopped |
392 | 364 |
365 # Determine overall outcome of the build by checking the outcome | |
366 # of the individual steps against the "onerror" specification of | |
367 # each step in the recipe | |
368 for num, recipe_step in enumerate(recipe): | |
369 step = BuildStep.fetch(self.env, build.id, recipe_step.id) | |
370 if step.status == BuildStep.FAILURE: | |
754
545be0c8f405
Adding the ability to modify the default ''onerror'' property in the ''<build>'' element. If not specified, the behavior is unchanged; by default any step failure will result in the build failing and stopping.
wbell
parents:
748
diff
changeset
|
371 if recipe_step.onerror == 'fail' or \ |
545be0c8f405
Adding the ability to modify the default ''onerror'' property in the ''<build>'' element. If not specified, the behavior is unchanged; by default any step failure will result in the build failing and stopping.
wbell
parents:
748
diff
changeset
|
372 recipe_step.onerror == 'continue': |
392 | 373 build.status = Build.FAILURE |
374 break | |
375 else: | |
376 build.status = Build.SUCCESS | |
377 | |
378 build.update(db=db) | |
761
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
379 else: |
762
5f0cfee44540
Add new last_activity field to build. I considered reusing stopped, but this seemed cleaner and more obvious, which seems like the right way to go.
wbell
parents:
761
diff
changeset
|
380 build.last_activity = step.stopped |
5f0cfee44540
Add new last_activity field to build. I considered reusing stopped, but this seemed cleaner and more obvious, which seems like the right way to go.
wbell
parents:
761
diff
changeset
|
381 build.update(db=db) |
5f0cfee44540
Add new last_activity field to build. I considered reusing stopped, but this seemed cleaner and more obvious, which seems like the right way to go.
wbell
parents:
761
diff
changeset
|
382 |
761
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
383 # start the next step. |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
384 for num, recipe_step in enumerate(recipe): |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
385 if num == index + 1: |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
386 next_step = recipe_step |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
387 if next_step is None: |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
388 self._send_error(req, HTTP_FORBIDDEN, |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
389 'Unable to find step after ' % stepname) |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
390 |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
391 step = self._start_new_step(build, next_step.id) |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
392 step.insert(db=db) |
392 | 393 |
200
692924ffed80
Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents:
197
diff
changeset
|
394 db.commit() |
692924ffed80
Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents:
197
diff
changeset
|
395 |
459 | 396 if last_step: |
392 | 397 for listener in BuildSystem(self.env).listeners: |
398 listener.build_completed(build) | |
253 | 399 |
392 | 400 body = 'Build step processed' |
645
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
401 self._send_response(req, 201, body, { |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
402 'Content-Type': 'text/plain', |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
403 'Content-Length': str(len(body)), |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
404 'Location': req.abs_href.builds( |
8c824b14e1c5
0.6dev: Switching `master.py` to use new `self._send_response()` and `self._send_error() methods. Simplifies code, but most importantly for errors it allows a consistent method for transmitting plain-text error messages to the slave (that the slave will now output as part of debug logging).
osimons
parents:
632
diff
changeset
|
405 build.id, 'steps', stepname)}) |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
406 |
835
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
407 def _process_attachment(self, req, config, build): |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
408 resource_id = req.args['member'] == 'config' \ |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
409 and build.config or build.resource.id |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
410 upload = req.args['file'] |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
411 if not upload.file: |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
412 send_error(req, message="Attachment not received.") |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
413 self.log.debug('Received attachment %s for attaching to build:%s', |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
414 upload.filename, resource_id) |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
415 |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
416 # Determine size of file |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
417 upload.file.seek(0, 2) # to the end |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
418 size = upload.file.tell() |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
419 upload.file.seek(0) # beginning again |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
420 |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
421 # Delete attachment if it already exists |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
422 try: |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
423 old_attach = Attachment(self.env, 'build', |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
424 parent_id=resource_id, filename=upload.filename) |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
425 old_attach.delete() |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
426 except ResourceNotFound: |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
427 pass |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
428 |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
429 # Save new attachment |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
430 attachment = Attachment(self.env, 'build', parent_id=resource_id) |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
431 attachment.description = req.args.get('description', '') |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
432 attachment.author = req.authname |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
433 attachment.insert(upload.filename, upload.file, size) |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
434 |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
435 self._send_response(req, 201, 'Attachment created', headers={ |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
436 'Content-Type': 'text/plain', |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
437 'Content-Length': str(len('Attachment created'))}) |
59acaa8b52c0
Slave attachment support via `<attach />` is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...
osimons
parents:
832
diff
changeset
|
438 |
785
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
439 def _process_keepalive(self, req, config, build): |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
440 build.last_activity = int(time.time()) |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
441 build.update() |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
442 |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
443 self.log.info('Slave %s build %d keepalive ("%s" as of [%s])', |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
444 build.slave, build.id, build.config, build.rev) |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
445 |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
446 body = 'Keepalive processed' |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
447 self._send_response(req, 200, body, { |
8e76b8f6310a
Adding keepalives to the bitten client/server protocol.
wbell
parents:
762
diff
changeset
|
448 'Content-Type': 'text/plain', |
826
77c3de8f5c46
Stop sending the 'Location' header on keepalive responses, which is against the http spec and confuses some proxies.
wbell
parents:
806
diff
changeset
|
449 'Content-Length': str(len(body))}) |
77c3de8f5c46
Stop sending the 'Location' header on keepalive responses, which is against the http spec and confuses some proxies.
wbell
parents:
806
diff
changeset
|
450 |
761
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
451 def _start_new_step(self, build, stepname): |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
452 """Creates the in-memory representation for a newly started |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
453 step, ready to be persisted to the database. |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
454 """ |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
455 step = BuildStep(self.env, build=build.id, name=stepname) |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
456 step.status = BuildStep.IN_PROGRESS |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
457 step.started = int(time.time()) |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
458 step.stopped = 0 |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
459 |
b2272caf5ac4
Master now creates next step as in progress when the previous step is complete. While a build is running, the currently running build step now shows up in the ui as in-progress with an updating duration, which makes it much easier to figure out what's going on or if a build is hanging.
wbell
parents:
758
diff
changeset
|
460 return step |