Mercurial > bitten > bitten-test
annotate bitten/master.py @ 135:d2b833187429 release-0.3
Bump up version number.
author | cmlenz |
---|---|
date | Sat, 13 Aug 2005 10:59:42 +0000 |
parents | 091ead7d2876 |
children | 395b67aa072e |
rev | line source |
---|---|
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
1 # -*- coding: iso8859-1 -*- |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
2 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
3 # Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de> |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
4 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
5 # Bitten is free software; you can redistribute it and/or |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
6 # modify it under the terms of the GNU General Public License as |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
7 # published by the Free Software Foundation; either version 2 of the |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
8 # License, or (at your option) any later version. |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
9 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
10 # Trac is distributed in the hope that it will be useful, |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
13 # General Public License for more details. |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
14 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
15 # You should have received a copy of the GNU General Public License |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
16 # along with this program; if not, write to the Free Software |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
18 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
19 # Author: Christopher Lenz <cmlenz@gmx.de> |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
20 |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
21 from datetime import datetime, timedelta |
82
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
22 from itertools import ifilter |
15
06207499c58c
* Use logging in the BEEP core as well as in the master and slave scripts. Closes #4.
cmlenz
parents:
14
diff
changeset
|
23 import logging |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
24 import os.path |
76
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
25 import re |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
26 try: |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
27 set |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
28 except NameError: |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
29 from sets import Set as set |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
30 import time |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
31 |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
32 from trac.env import Environment |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
33 from bitten.model import BuildConfig, TargetPlatform, Build, BuildStep, BuildLog |
116 | 34 from bitten.store import ReportStore |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
35 from bitten.util import archive, beep, xmlio |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
36 |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
37 log = logging.getLogger('bitten.master') |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
38 |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
39 DEFAULT_CHECK_INTERVAL = 120 # 2 minutes |
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
40 |
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
41 |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
42 class Master(beep.Listener): |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
43 |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
44 def __init__(self, env_path, ip, port, adjust_timestamps=False, |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
45 check_interval=DEFAULT_CHECK_INTERVAL): |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
46 beep.Listener.__init__(self, ip, port) |
24
cad6d28b8975
* Proper separation between {{{beep.ProfileHandler}}} instances between different channels.
cmlenz
parents:
19
diff
changeset
|
47 self.profiles[OrchestrationProfileHandler.URI] = OrchestrationProfileHandler |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
48 self.env = Environment(env_path) |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
49 self.adjust_timestamps = adjust_timestamps |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
50 self.check_interval = check_interval |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
51 |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
52 self.slaves = {} |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
53 |
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
54 # path to generated snapshot archives, key is (config name, revision) |
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
55 self.snapshots = {} |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
56 for config in BuildConfig.select(self.env): |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
57 snapshots = archive.index(self.env, prefix=config.name) |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
58 for rev, format, path in snapshots: |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
59 self.snapshots[(config.name, rev, format)] = path |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
60 |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
61 self._cleanup_orphaned_builds() |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
62 self.schedule(self.check_interval, self._check_build_triggers) |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
63 |
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
64 def close(self): |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
65 self._cleanup_orphaned_builds() |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
66 beep.Listener.close(self) |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
67 |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
68 def _check_build_triggers(self, when): |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
69 self.schedule(self.check_interval, self._check_build_triggers) |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
70 |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
71 repos = self.env.get_repository() |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
72 try: |
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
73 repos.sync() |
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
74 |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
75 db = self.env.get_db_cnx() |
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
76 for config in BuildConfig.select(self.env, db=db): |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
77 log.debug('Checking for changes to "%s" at %s', config.label, |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
78 config.path) |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
79 node = repos.get_node(config.path) |
56 | 80 for path, rev, chg in node.get_history(): |
76
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
81 enqueued = False |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
82 for platform in TargetPlatform.select(self.env, |
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
83 config.name, db=db): |
76
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
84 # Check whether the latest revision of the configuration |
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
85 # has already been built on this platform |
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
86 builds = Build.select(self.env, config.name, rev, |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
87 platform.id, db=db) |
76
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
88 if not list(builds): |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
89 log.info('Enqueuing build of configuration "%s" at ' |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
90 'revision [%s] on %s', config.name, rev, |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
91 platform.name) |
76
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
92 build = Build(self.env) |
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
93 build.config = config.name |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
94 build.rev = str(rev) |
76
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
95 build.rev_time = repos.get_changeset(rev).date |
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
96 build.platform = platform.id |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
97 build.insert(db) |
76
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
98 enqueued = True |
ffa1ffd8c7db
* Implement basic slave selection based on configured target platforms. Closes #15.
cmlenz
parents:
73
diff
changeset
|
99 if enqueued: |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
100 db.commit() |
56 | 101 break |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
102 finally: |
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
103 repos.close() |
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
104 |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
105 self.schedule(self.check_interval * 0.2, self._check_build_queue) |
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
106 self.schedule(self.check_interval * 1.8, self._cleanup_snapshots) |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
107 |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
108 def _check_build_queue(self, when): |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
109 if not self.slaves: |
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
110 return |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
111 log.debug('Checking for pending builds...') |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
112 for build in Build.select(self.env, status=Build.PENDING): |
86
110bfa3cbc32
Slaves were getting associated with the wrong target platform.
cmlenz
parents:
85
diff
changeset
|
113 for slave in self.slaves.get(build.platform, []): |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
114 active_builds = Build.select(self.env, slave=slave.name, |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
115 status=Build.IN_PROGRESS) |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
116 if not list(active_builds): |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
117 slave.send_initiation(build) |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
118 return |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
119 |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
120 def _cleanup_orphaned_builds(self): |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
121 # Remove all pending or in-progress builds |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
122 db = self.env.get_db_cnx() |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
123 for build in Build.select(self.env, status=Build.IN_PROGRESS, db=db): |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
124 build.status = Build.PENDING |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
125 build.update(db=db) |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
126 for build in Build.select(self.env, status=Build.PENDING, db=db): |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
127 build.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
|
128 db.commit() |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
129 |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
130 def _cleanup_snapshots(self, when): |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
131 log.debug('Checking for unused snapshot archives...') |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
132 for (config, rev, format), path in self.snapshots.items(): |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
133 keep = False |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
134 for build in Build.select(self.env, config=config, rev=rev): |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
135 if build.status not in (Build.SUCCESS, Build.FAILURE): |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
136 keep = True |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
137 break |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
138 if not keep: |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
139 log.info('Removing unused snapshot %s', path) |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
140 os.unlink(path) |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
141 del self.snapshots[(config, rev, format)] |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
142 |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
143 def get_snapshot(self, build, format): |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
144 snapshot = self.snapshots.get((build.config, build.rev, format)) |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
145 if not snapshot: |
96 | 146 config = BuildConfig.fetch(self.env, build.config) |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
147 snapshot = archive.pack(self.env, path=config.path, rev=build.rev, |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
148 prefix=config.name, format=format) |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
149 log.info('Prepared snapshot archive at %s' % snapshot) |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
150 self.snapshots[(build.config, build.rev, format)] = snapshot |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
151 return snapshot |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
152 |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
153 def register(self, handler): |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
154 any_match = False |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
155 for config in BuildConfig.select(self.env): |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
156 for platform in TargetPlatform.select(self.env, config=config.name): |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
157 if not platform.id in self.slaves: |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
158 self.slaves[platform.id] = set() |
85
acb7b67b8152
Fix matching of slave properties against target platform rules.
cmlenz
parents:
84
diff
changeset
|
159 match = True |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
160 for property, pattern in ifilter(None, platform.rules): |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
161 try: |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
162 if not re.match(pattern, handler.info.get(property)): |
86
110bfa3cbc32
Slaves were getting associated with the wrong target platform.
cmlenz
parents:
85
diff
changeset
|
163 match = False |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
164 break |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
165 except re.error, e: |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
166 log.error('Invalid platform matching pattern "%s"', |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
167 pattern, exc_info=True) |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
168 match = False |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
169 break |
84 | 170 if match: |
96 | 171 log.debug('Slave %s matched target platform %s', |
172 handler.name, platform.name) | |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
173 self.slaves[platform.id].add(handler) |
86
110bfa3cbc32
Slaves were getting associated with the wrong target platform.
cmlenz
parents:
85
diff
changeset
|
174 any_match = True |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
175 |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
176 if not any_match: |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
177 log.warning('Slave %s does not match any of the configured target ' |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
178 'platforms', handler.name) |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
179 return False |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
180 |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
181 self.schedule(self.check_interval * 0.2, self._check_build_queue) |
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
182 |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
183 log.info('Registered slave "%s"', handler.name) |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
184 return True |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
185 |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
186 def unregister(self, handler): |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
187 for slaves in self.slaves.values(): |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
188 slaves.discard(handler) |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
189 |
117 | 190 db = self.env.get_db_cnx() |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
191 for build in Build.select(self.env, slave=handler.name, |
117 | 192 status=Build.IN_PROGRESS, db=db): |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
193 log.info('Build [%s] of "%s" by %s cancelled', build.rev, |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
194 build.config, handler.name) |
117 | 195 for step in BuildStep.select(self.env, build=build.id): |
196 step.delete(db=db) | |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
197 build.slave = None |
117 | 198 build.slave_info = {} |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
199 build.status = Build.PENDING |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
200 build.started = 0 |
117 | 201 build.update(db=db) |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
202 break |
117 | 203 db.commit() |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
204 log.info('Unregistered slave "%s"', handler.name) |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
205 |
56 | 206 |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
207 class OrchestrationProfileHandler(beep.ProfileHandler): |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
208 """Handler for communication on the Bitten build orchestration profile from |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
209 the perspective of the build master. |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
210 """ |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
211 URI = 'http://bitten.cmlenz.net/beep/orchestration' |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
212 |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
213 def handle_connect(self): |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
214 self.master = self.session.listener |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
215 assert self.master |
69 | 216 self.env = self.master.env |
217 assert self.env | |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
218 self.name = None |
82
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
219 self.info = {} |
24
cad6d28b8975
* Proper separation between {{{beep.ProfileHandler}}} instances between different channels.
cmlenz
parents:
19
diff
changeset
|
220 |
cad6d28b8975
* Proper separation between {{{beep.ProfileHandler}}} instances between different channels.
cmlenz
parents:
19
diff
changeset
|
221 def handle_disconnect(self): |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
222 self.master.unregister(self) |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
223 |
88 | 224 def handle_msg(self, msgno, payload): |
225 assert payload.content_type == beep.BEEP_XML | |
226 elem = xmlio.parse(payload.body) | |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
227 |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
228 if elem.name == 'register': |
69 | 229 self.name = elem.attr['name'] |
127
a9443f673344
Add option for specifying a [wiki:SlaveConfiguration configuration file] for the build slave. Closes #29.
cmlenz
parents:
119
diff
changeset
|
230 self.info[Build.IP_ADDRESS] = self.session.addr[0] |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
231 for child in elem.children(): |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
232 if child.name == 'platform': |
82
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
233 self.info[Build.MACHINE] = child.gettext() |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
234 self.info[Build.PROCESSOR] = child.attr.get('processor') |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
235 elif child.name == 'os': |
82
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
236 self.info[Build.OS_NAME] = child.gettext() |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
237 self.info[Build.OS_FAMILY] = child.attr.get('family') |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
238 self.info[Build.OS_VERSION] = child.attr.get('version') |
127
a9443f673344
Add option for specifying a [wiki:SlaveConfiguration configuration file] for the build slave. Closes #29.
cmlenz
parents:
119
diff
changeset
|
239 elif child.name == 'package': |
a9443f673344
Add option for specifying a [wiki:SlaveConfiguration configuration file] for the build slave. Closes #29.
cmlenz
parents:
119
diff
changeset
|
240 for name, value in child.attr.items(): |
a9443f673344
Add option for specifying a [wiki:SlaveConfiguration configuration file] for the build slave. Closes #29.
cmlenz
parents:
119
diff
changeset
|
241 if name == 'name': |
a9443f673344
Add option for specifying a [wiki:SlaveConfiguration configuration file] for the build slave. Closes #29.
cmlenz
parents:
119
diff
changeset
|
242 continue |
a9443f673344
Add option for specifying a [wiki:SlaveConfiguration configuration file] for the build slave. Closes #29.
cmlenz
parents:
119
diff
changeset
|
243 self.info[child.attr['name'] + '.' + name] = value |
14
1733c601d2f8
Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents:
13
diff
changeset
|
244 |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
245 if not self.master.register(self): |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
246 xml = xmlio.Element('error', code=550)[ |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
247 'Nothing for you to build here, please move along' |
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
248 ] |
88 | 249 self.channel.send_err(msgno, beep.Payload(xml)) |
83
42970c14524a
Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents:
82
diff
changeset
|
250 return |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
251 |
29 | 252 xml = xmlio.Element('ok') |
88 | 253 self.channel.send_rpy(msgno, beep.Payload(xml)) |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
254 |
56 | 255 def send_initiation(self, build): |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
256 log.info('Initiating build of "%s" on slave %s', build.config, |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
257 self.name) |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
258 |
88 | 259 def handle_reply(cmd, msgno, ansno, payload): |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
260 if cmd == 'ERR': |
88 | 261 if payload.content_type == beep.BEEP_XML: |
262 elem = xmlio.parse(payload.body) | |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
263 if elem.name == 'error': |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
264 log.warning('Slave %s refused build request: %s (%d)', |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
265 self.name, elem.gettext(), |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
266 int(elem.attr['code'])) |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
267 return |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
268 |
88 | 269 elem = xmlio.parse(payload.body) |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
270 assert elem.name == 'proceed' |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
271 type = encoding = None |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
272 for child in elem.children('accept'): |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
273 type, encoding = child.attr['type'], child.attr.get('encoding') |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
274 if (type, encoding) in (('application/tar', 'gzip'), |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
275 ('application/tar', 'bzip2'), |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
276 ('application/tar', None), |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
277 ('application/zip', None)): |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
278 break |
56 | 279 type = None |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
280 if not type: |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
281 xml = xmlio.Element('error', code=550)[ |
63
2332aedba328
* Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents:
61
diff
changeset
|
282 'None of the accepted archive formats supported' |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
283 ] |
88 | 284 self.channel.send_err(beep.Payload(xml)) |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
285 return |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
286 self.send_snapshot(build, type, encoding) |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
287 |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
288 xml = xmlio.Element('build', recipe='recipe.xml') |
88 | 289 self.channel.send_msg(beep.Payload(xml), handle_reply=handle_reply) |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
290 |
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
291 def send_snapshot(self, build, type, encoding): |
63
2332aedba328
* Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents:
61
diff
changeset
|
292 |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
293 timestamp_delta = 0 |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
294 if self.master.adjust_timestamps: |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
295 d = datetime.now() - timedelta(seconds=self.master.check_interval) \ |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
296 - datetime.fromtimestamp(build.rev_time) |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
297 log.info('Warping timestamps by %s' % d) |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
298 timestamp_delta = d.days * 86400 + d.seconds |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
299 |
88 | 300 def handle_reply(cmd, msgno, ansno, payload): |
51
5caccd7b247e
Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents:
49
diff
changeset
|
301 if cmd == 'ERR': |
88 | 302 assert payload.content_type == beep.BEEP_XML |
303 elem = xmlio.parse(payload.body) | |
63
2332aedba328
* Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents:
61
diff
changeset
|
304 if elem.name == 'error': |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
305 log.warning('Slave %s did not accept archive: %s (%d)', |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
306 self.name, elem.gettext(), |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
307 int(elem.attr['code'])) |
80
dc1c7fc9b915
Record the output of build steps in the database. See #12. Still need to get better granularity in transmitting the log output from slave to master before #12 can be closed.
cmlenz
parents:
76
diff
changeset
|
308 |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
309 elif cmd == 'ANS': |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
310 assert payload.content_type == beep.BEEP_XML |
94 | 311 db = self.env.get_db_cnx() |
88 | 312 elem = xmlio.parse(payload.body) |
63
2332aedba328
* Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents:
61
diff
changeset
|
313 if elem.name == 'started': |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
314 self._build_started(db, build, elem, timestamp_delta) |
63
2332aedba328
* Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents:
61
diff
changeset
|
315 elif elem.name == 'step': |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
316 self._build_step_completed(db, build, elem, timestamp_delta) |
82
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
317 elif elem.name == 'completed': |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
318 self._build_completed(db, build, elem, timestamp_delta) |
70 | 319 elif elem.name == 'aborted': |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
320 self._build_aborted(db, build, elem, timestamp_delta) |
63
2332aedba328
* Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents:
61
diff
changeset
|
321 elif elem.name == 'error': |
2332aedba328
* Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents:
61
diff
changeset
|
322 build.status = Build.FAILURE |
94 | 323 build.update(db=db) |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
324 db.commit() |
80
dc1c7fc9b915
Record the output of build steps in the database. See #12. Still need to get better granularity in transmitting the log output from slave to master before #12 can be closed.
cmlenz
parents:
76
diff
changeset
|
325 |
92
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
326 snapshot_format = { |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
327 ('application/tar', 'bzip2'): 'bzip2', |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
328 ('application/tar', 'gzip'): 'gzip', |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
329 ('application/tar', None): 'tar', |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
330 ('application/zip', None): 'zip', |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
331 }[(type, encoding)] |
2e090827c63a
Delete snapshots for builds that have been completed by all configured target platforms, and are thus no longer needed. Closes #20.
cmlenz
parents:
90
diff
changeset
|
332 snapshot_path = self.master.get_snapshot(build, snapshot_format) |
47
083e848088ee
* Improvements to the model classes, and a couple of unit tests.
cmlenz
parents:
45
diff
changeset
|
333 snapshot_name = os.path.basename(snapshot_path) |
90
2c4e104afef8
The build master now transmits snapshot archives without blocking while reading the file and sending the BEEP frames. Closes #17.
cmlenz
parents:
88
diff
changeset
|
334 message = beep.Payload(file(snapshot_path), content_type=type, |
88 | 335 content_disposition=snapshot_name, |
90
2c4e104afef8
The build master now transmits snapshot archives without blocking while reading the file and sending the BEEP frames. Closes #17.
cmlenz
parents:
88
diff
changeset
|
336 content_encoding=encoding) |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
337 self.channel.send_msg(message, handle_reply=handle_reply) |
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
338 |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
339 def _build_started(self, db, build, elem, timestamp_delta=None): |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
340 build.slave = self.name |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
341 build.slave_info.update(self.info) |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
342 build.started = int(_parse_iso_datetime(elem.attr['time'])) |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
343 if timestamp_delta: |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
344 build.started -= timestamp_delta |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
345 build.status = Build.IN_PROGRESS |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
346 log.info('Slave %s started build %d ("%s" as of [%s])', |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
347 self.name, build.id, build.config, build.rev) |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
348 |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
349 def _build_step_completed(self, db, build, elem, timestamp_delta=None): |
119
430c518ebb14
* More logging in master and slave about the build status.
cmlenz
parents:
117
diff
changeset
|
350 log.debug('Slave completed step "%s" with status %s', elem.attr['id'], |
430c518ebb14
* More logging in master and slave about the build status.
cmlenz
parents:
117
diff
changeset
|
351 elem.attr['result']) |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
352 step = BuildStep(self.env, build=build.id, name=elem.attr['id'], |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
353 description=elem.attr.get('description')) |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
354 step.started = int(_parse_iso_datetime(elem.attr['time'])) |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
355 step.stopped = step.started + int(elem.attr['duration']) |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
356 if timestamp_delta: |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
357 step.started -= timestamp_delta |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
358 step.stopped -= timestamp_delta |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
359 if elem.attr['result'] == 'failure': |
135 | 360 log.warning('Step failed') |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
361 step.status = BuildStep.FAILURE |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
362 else: |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
363 step.status = BuildStep.SUCCESS |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
364 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
|
365 |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
366 level_map = {'debug': BuildLog.DEBUG, 'info': BuildLog.INFO, |
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
367 'warning': BuildLog.WARNING, 'error': BuildLog.ERROR} |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
368 for log_elem in elem.children('log'): |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
369 build_log = BuildLog(self.env, build=build.id, step=step.name, |
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
370 type=log_elem.attr.get('type')) |
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
|
371 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
|
372 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
|
373 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
|
374 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
|
375 |
116 | 376 store = ReportStore(self.env) |
377 for report in elem.children('report'): | |
378 store.store_report(build, step, report) | |
379 | |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
380 def _build_completed(self, db, build, elem, timestamp_delta=None): |
119
430c518ebb14
* More logging in master and slave about the build status.
cmlenz
parents:
117
diff
changeset
|
381 log.info('Slave %s completed build %d ("%s" as of [%s]) with status %s', |
430c518ebb14
* More logging in master and slave about the build status.
cmlenz
parents:
117
diff
changeset
|
382 self.name, build.id, build.config, build.rev, |
430c518ebb14
* More logging in master and slave about the build status.
cmlenz
parents:
117
diff
changeset
|
383 elem.attr['result']) |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
384 build.stopped = int(_parse_iso_datetime(elem.attr['time'])) |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
385 if timestamp_delta: |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
386 build.stopped -= timestamp_delta |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
387 if elem.attr['result'] == 'failure': |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
388 build.status = Build.FAILURE |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
389 else: |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
390 build.status = Build.SUCCESS |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
391 |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
392 def _build_aborted(self, db, build, elem, timestamp_delta=None): |
109
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
393 log.info('Slave "%s" aborted build %d ("%s" as of [%s])', |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
394 self.name, build.id, build.config, build.rev) |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
395 build.slave = None |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
396 build.started = 0 |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
397 build.status = Build.PENDING |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
398 build.slave_info = {} |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
399 for step in BuildStep.select(self.env, build=build.id, db=db): |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
400 step.delete(db=db) |
5bf22bb87915
Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents:
96
diff
changeset
|
401 |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
402 |
82
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
403 def _parse_iso_datetime(string): |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
404 """Minimal parser for ISO date-time strings. |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
405 |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
406 Return the time as floating point number. Only handles UTC timestamps |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
407 without time zone information.""" |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
408 try: |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
409 string = string.split('.', 1)[0] # strip out microseconds |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
410 secs = time.mktime(time.strptime(string, '%Y-%m-%dT%H:%M:%S')) |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
411 tzoffset = time.timezone |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
412 if time.daylight: |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
413 tzoffset = time.altzone |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
414 return secs - tzoffset |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
415 except ValueError, e: |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
416 raise ValueError, 'Invalid ISO date/time %s (%s)' % (string, e) |
01200c88ddb0
Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents:
80
diff
changeset
|
417 |
31 | 418 def main(): |
56 | 419 from bitten import __version__ as VERSION |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
420 from optparse import OptionParser |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
421 |
112
a38eabd4b6e1
* Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents:
110
diff
changeset
|
422 # Parse command-line arguments |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
423 parser = OptionParser(usage='usage: %prog [options] env-path', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
424 version='%%prog %s' % VERSION) |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
425 parser.add_option('-p', '--port', action='store', type='int', dest='port', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
426 help='port number to use') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
427 parser.add_option('-H', '--host', action='store', dest='host', |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
428 metavar='HOSTNAME', |
33
d8d44216258a
Exit the slave script when the master disconnects; and other minor fixes.
cmlenz
parents:
31
diff
changeset
|
429 help='the host name or IP address to bind to') |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
430 parser.add_option('-l', '--log', dest='logfile', metavar='FILENAME', |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
431 help='write log messages to FILENAME') |
95
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
432 parser.add_option('-i', '--interval', dest='interval', metavar='SECONDS', |
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
433 default=DEFAULT_CHECK_INTERVAL, type='int', |
1984b2e01998
Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents:
94
diff
changeset
|
434 help='poll interval for changeset detection') |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
435 parser.add_option('--timewarp', action='store_const', dest='timewarp', |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
436 const=True, |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
437 help='adjust timestamps of builds to be neat the ' |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
438 'timestamps of the corresponding changesets') |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
439 parser.add_option('--debug', action='store_const', dest='loglevel', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
440 const=logging.DEBUG, help='enable debugging output') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
441 parser.add_option('-v', '--verbose', action='store_const', dest='loglevel', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
442 const=logging.INFO, help='print as much as possible') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
443 parser.add_option('-q', '--quiet', action='store_const', dest='loglevel', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
444 const=logging.ERROR, help='print as little as possible') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
445 parser.set_defaults(port=7633, loglevel=logging.WARNING) |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
446 options, args = parser.parse_args() |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
447 |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
448 if len(args) < 1: |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
449 parser.error('incorrect number of arguments') |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
450 env_path = args[0] |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
451 |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
452 # Configure logging |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
453 log = logging.getLogger('bitten') |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
454 log.setLevel(options.loglevel) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
455 handler = logging.StreamHandler() |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
456 if options.logfile: |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
457 handler.setLevel(logging.WARNING) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
458 else: |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
459 handler.setLevel(options.loglevel) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
460 formatter = logging.Formatter('%(message)s') |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
461 handler.setFormatter(formatter) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
462 log.addHandler(handler) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
463 if options.logfile: |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
464 handler = logging.FileHandler(options.logfile) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
465 handler.setLevel(options.loglevel) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
466 formatter = logging.Formatter('%(asctime)s [%(name)s] %(levelname)s: ' |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
467 '%(message)s') |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
468 handler.setFormatter(formatter) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
469 log.addHandler(handler) |
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
470 |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
471 port = options.port |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
472 if not (1 <= port <= 65535): |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
473 parser.error('port must be an integer in the range 1-65535') |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
474 |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
475 host = options.host |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
476 if not host: |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
477 import socket |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
478 ip = socket.gethostbyname(socket.gethostname()) |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
479 try: |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
480 host = socket.gethostbyaddr(ip)[0] |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
481 except socket.error, e: |
93
b289e572bc7e
Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents:
92
diff
changeset
|
482 log.warning('Reverse host name lookup failed (%s)', e) |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
483 host = ip |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
484 |
130
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
485 master = Master(env_path, host, port, adjust_timestamps=options.timewarp, |
091ead7d2876
Add a {{{--timewarp}}} option to the build master. If provided, the build master will adjust the timestamps of all builds to shortly after the time of the corresponding changeset. This is mostly for building the history of a project while keeping a chronological association between changeset and build.
cmlenz
parents:
127
diff
changeset
|
486 check_interval=options.interval) |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
487 try: |
42
efa525876b1e
Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents:
34
diff
changeset
|
488 master.run(timeout=5.0) |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
489 except KeyboardInterrupt: |
34
6da9468a6879
The build master now gracefully exits by first terminating all active sessions. Fixes #7.
cmlenz
parents:
33
diff
changeset
|
490 master.quit() |
31 | 491 |
492 if __name__ == '__main__': | |
33
d8d44216258a
Exit the slave script when the master disconnects; and other minor fixes.
cmlenz
parents:
31
diff
changeset
|
493 main() |