annotate bitten/master.py @ 284:ddc93fe34cad

Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
author cmlenz
date Fri, 14 Oct 2005 21:12:45 +0000
parents 33625fa61d6c
children 6abd43d0cd8a
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>
163
634be6cbb808 Flip the switch: Bitten is now BSD-licensed.
cmlenz
parents: 157
diff changeset
4 # All rights reserved.
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff changeset
5 #
163
634be6cbb808 Flip the switch: Bitten is now BSD-licensed.
cmlenz
parents: 157
diff changeset
6 # This software is licensed as described in the file COPYING, which
634be6cbb808 Flip the switch: Bitten is now BSD-licensed.
cmlenz
parents: 157
diff changeset
7 # you should have received as part of this distribution. The terms
634be6cbb808 Flip the switch: Bitten is now BSD-licensed.
cmlenz
parents: 157
diff changeset
8 # are also available at http://bitten.cmlenz.net/wiki/License.
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff changeset
9
95
1984b2e01998 Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents: 94
diff changeset
10 from datetime import datetime, timedelta
15
06207499c58c * Use logging in the BEEP core as well as in the master and slave scripts. Closes #4.
cmlenz
parents: 14
diff changeset
11 import logging
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
12 import os
83
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
13 try:
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
14 set
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
15 except NameError:
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
16 from sets import Set as set
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
17 import sys
47
083e848088ee * Improvements to the model classes, and a couple of unit tests.
cmlenz
parents: 45
diff changeset
18 import time
18
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
19
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
20 from trac.env import Environment
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
21 from bitten.model import BuildConfig, Build, BuildStep, BuildLog, Report
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
22 from bitten.queue import BuildQueue
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
23 from bitten.trac_ext.main import BuildSystem
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
24 from bitten.util import beep, xmlio
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff changeset
25
93
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
26 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
27
95
1984b2e01998 Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents: 94
diff changeset
28 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
29
1984b2e01998 Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents: 94
diff changeset
30
18
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
31 class Master(beep.Listener):
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
32
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
33 def __init__(self, envs, 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
34 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
35 beep.Listener.__init__(self, ip, port)
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
36 self.profiles[OrchestrationProfileHandler.URI] = \
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
37 OrchestrationProfileHandler
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
38 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
39 self.check_interval = check_interval
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
40 self.handlers = {} # Map of connected slaves keyed by name
47
083e848088ee * Improvements to the model classes, and a couple of unit tests.
cmlenz
parents: 45
diff changeset
41
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
42 self.queues = []
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
43 for env in envs:
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
44 self.queues.append(BuildQueue(env))
47
083e848088ee * Improvements to the model classes, and a couple of unit tests.
cmlenz
parents: 45
diff changeset
45
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
46 self.schedule(self.check_interval, self._enqueue_builds)
47
083e848088ee * Improvements to the model classes, and a couple of unit tests.
cmlenz
parents: 45
diff changeset
47
083e848088ee * Improvements to the model classes, and a couple of unit tests.
cmlenz
parents: 45
diff changeset
48 def close(self):
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
49 for queue in self.queues:
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
50 queue.reset_orphaned_builds()
47
083e848088ee * Improvements to the model classes, and a couple of unit tests.
cmlenz
parents: 45
diff changeset
51 beep.Listener.close(self)
18
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
52
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
53 def _enqueue_builds(self):
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
54 self.schedule(self.check_interval, self._enqueue_builds)
18
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
55
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
56 for queue in self.queues:
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
57 queue.populate()
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
58
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
59 self.schedule(self.check_interval * 0.2, self._initiate_builds)
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
60
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
61 def _initiate_builds(self):
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
62 available_slaves = set([name for name in self.handlers
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
63 if not self.handlers[name].building])
228
a8c9dd7e3f71 * Cleanup and documentation for the `BuildQueue` class added in [236].
cmlenz
parents: 227
diff changeset
64 for idx, queue in enumerate(self.queues[:]):
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
65 build, slave = queue.get_next_pending_build(available_slaves)
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
66 if build:
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
67 self.handlers[slave].send_initiation(queue, build)
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
68 available_slaves.discard(slave)
228
a8c9dd7e3f71 * Cleanup and documentation for the `BuildQueue` class added in [236].
cmlenz
parents: 227
diff changeset
69 self.queues.append(self.queues.pop(idx)) # Round robin
18
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
70
83
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
71 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
72 any_match = False
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
73 for queue in self.queues:
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
74 if queue.register_slave(handler.name, handler.info):
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
75 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
76
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
77 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
78 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
79 '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
80 return False
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
81
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
82 self.handlers[handler.name] = handler
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
83 self.schedule(self.check_interval * 0.2, self._initiate_builds)
95
1984b2e01998 Make the repository poll interval configurable. It now defaults to 2 minutes instead of 10 seconds.
cmlenz
parents: 94
diff changeset
84
93
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
85 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
86 return True
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
87
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
88 def unregister(self, handler):
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
89 if handler.name not in self.handlers:
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
90 return
83
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
91
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
92 for queue in self.queues:
253
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
93 if queue.unregister_slave(handler.name):
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
94 for build in list(Build.select(queue.env, slave=handler.name,
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
95 status=Build.IN_PROGRESS)):
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
96 handler._build_aborted(queue, build)
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
97
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
98 del self.handlers[handler.name]
184
fbf949f4c706 Allow invalidation of builds from the web interface. This results in the build being reset to ''PENDING'' status, and all build logs, slave information and reports deleted. Basically initiates a rebuild for a specific revision and target platform.
cmlenz
parents: 163
diff changeset
99
93
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
100 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
101
56
033366d81def Build slave now executes the build. Closes #10.
cmlenz
parents: 51
diff changeset
102
19
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
103 class OrchestrationProfileHandler(beep.ProfileHandler):
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
104 """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
105 the perspective of the build master.
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
106 """
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
107 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
108
51
5caccd7b247e Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents: 49
diff changeset
109 def handle_connect(self):
18
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
110 self.master = self.session.listener
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
111 assert self.master
47
083e848088ee * Improvements to the model classes, and a couple of unit tests.
cmlenz
parents: 45
diff changeset
112 self.name = None
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
113 self.building = False
82
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
114 self.info = {}
24
cad6d28b8975 * Proper separation between {{{beep.ProfileHandler}}} instances between different channels.
cmlenz
parents: 19
diff changeset
115
cad6d28b8975 * Proper separation between {{{beep.ProfileHandler}}} instances between different channels.
cmlenz
parents: 19
diff changeset
116 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
117 self.master.unregister(self)
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff changeset
118
88
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
119 def handle_msg(self, msgno, payload):
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
120 assert payload.content_type == beep.BEEP_XML
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
121 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
122
51
5caccd7b247e Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents: 49
diff changeset
123 if elem.name == 'register':
69
b92d7c7d70fd Record build slave properties in database.
cmlenz
parents: 66
diff changeset
124 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
125 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
126 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
127 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
128 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
129 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
130 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
131 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
132 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
133 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
134 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
135 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
136 if name == 'name':
a9443f673344 Add option for specifying a [wiki:SlaveConfiguration configuration file] for the build slave. Closes #29.
cmlenz
parents: 119
diff changeset
137 continue
a9443f673344 Add option for specifying a [wiki:SlaveConfiguration configuration file] for the build slave. Closes #29.
cmlenz
parents: 119
diff changeset
138 self.info[child.attr['name'] + '.' + name] = value
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
139
83
42970c14524a Perform slave/platform matching at slave registration. Use builtin {{{set}}} type on Python >= 2.4.
cmlenz
parents: 82
diff changeset
140 if not self.master.register(self):
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
141 raise beep.ProtocolError(550, 'Nothing for you to build here, '
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
142 'please move along')
18
591a5a836ecc * {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents: 15
diff changeset
143
29
2adc3480e4aa Some cleanup and additional docstrings.
cmlenz
parents: 24
diff changeset
144 xml = xmlio.Element('ok')
88
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
145 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
146
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
147 def send_initiation(self, queue, build):
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
148 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
149 self.name)
284
ddc93fe34cad Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
cmlenz
parents: 281
diff changeset
150
ddc93fe34cad Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
cmlenz
parents: 281
diff changeset
151 build.slave = self.name
ddc93fe34cad Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
cmlenz
parents: 281
diff changeset
152 build.slave_info.update(self.info)
ddc93fe34cad Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
cmlenz
parents: 281
diff changeset
153 build.status = Build.IN_PROGRESS
ddc93fe34cad Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
cmlenz
parents: 281
diff changeset
154 build.update()
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
155 self.building = True
284
ddc93fe34cad Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
cmlenz
parents: 281
diff changeset
156
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
157 config = BuildConfig.fetch(queue.env, build.config)
42
efa525876b1e Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents: 34
diff changeset
158
88
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
159 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
160 if cmd == 'ERR':
88
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
161 if payload.content_type == beep.BEEP_XML:
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
162 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
163 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
164 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
165 self.name, elem.gettext(),
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
166 int(elem.attr['code']))
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
167 self.building = False
284
ddc93fe34cad Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
cmlenz
parents: 281
diff changeset
168 self._build_aborted(queue, build)
51
5caccd7b247e Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents: 49
diff changeset
169 return
5caccd7b247e Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents: 49
diff changeset
170
88
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
171 elem = xmlio.parse(payload.body)
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
172 if elem.name != 'proceed':
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
173 raise beep.ProtocolError(500)
51
5caccd7b247e Proper archive format negotiation; improved representation of parsed XML content in {{{bitten.util.xmlio}}}.
cmlenz
parents: 49
diff changeset
174
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
175 snapshots = queue.snapshots[config.name]
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
176 snapshot = snapshots.get(build.rev)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
177 if not snapshot:
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
178 # Request a snapshot for this build, and schedule a poll
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
179 # function that kicks off the snapshot transmission once the
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
180 # archive has been completely built
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
181 worker = snapshots.create(build.rev)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
182 def _check_snapshot():
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
183 worker.join(.5)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
184 if worker.isAlive():
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
185 self.master.schedule(2, _check_snapshot)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
186 else:
281
33625fa61d6c * If a slave disconnects after the master has started to create a snapshot archive for it, just remain calm and keep the archive in place.
cmlenz
parents: 277
diff changeset
187 if self.name not in self.master.handlers:
33625fa61d6c * If a slave disconnects after the master has started to create a snapshot archive for it, just remain calm and keep the archive in place.
cmlenz
parents: 277
diff changeset
188 # The slave disconnected while we were building
33625fa61d6c * If a slave disconnects after the master has started to create a snapshot archive for it, just remain calm and keep the archive in place.
cmlenz
parents: 277
diff changeset
189 # the archive
33625fa61d6c * If a slave disconnects after the master has started to create a snapshot archive for it, just remain calm and keep the archive in place.
cmlenz
parents: 277
diff changeset
190 return
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
191 snapshot = snapshots.get(build.rev)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
192 if snapshot is None:
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
193 log.error('Failed to create snapshot archive for '
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
194 '%s@%s', config.path, build.rev)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
195 return
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
196 self.send_snapshot(queue, build, snapshot)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
197 _check_snapshot()
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
198 else:
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
199 self.send_snapshot(queue, build, snapshot)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
200
147
395b67aa072e Build recipes are now stored in the database with the build configuration. This means that it is no longer necessary to store the recipe in the repository. Closes #41.
cmlenz
parents: 135
diff changeset
201 self.channel.send_msg(beep.Payload(config.recipe),
395b67aa072e Build recipes are now stored in the database with the build configuration. This means that it is no longer necessary to store the recipe in the repository. Closes #41.
cmlenz
parents: 135
diff changeset
202 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
203
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
204 def send_snapshot(self, queue, build, snapshot):
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
205 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
206 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
207 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
208 - datetime.fromtimestamp(build.rev_time)
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
209 log.info('Warping timestamps by %s', d)
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
210 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
211
88
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
212 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
213 if cmd == 'ERR':
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
214 if payload.content_type != beep.BEEP_XML:
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
215 raise beep.ProtocolError(500)
88
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
216 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
217 if elem.name == 'error':
185
2c24d9a950ed Add a `--dry-run` option to the build slave. This will result in the slave being registered and executing builds, but without submitting the progress and results of the build back to the server. Useful for getting the configuration of new slaves right without polluting the database with invalid builds.
cmlenz
parents: 184
diff changeset
218 log.warning('Slave %s refused to start build: %s (%d)',
93
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
219 self.name, elem.gettext(),
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
220 int(elem.attr['code']))
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
221 self.building = False
284
ddc93fe34cad Fix a bug in the build master (introduced in [289]) where multiple slaves matching the same target platform would potentially start the same build. This is done by setting the build to `IN_PROGRESS` as soon as the build initiation is sent, as opposed to when the slave accepts the build request.
cmlenz
parents: 281
diff changeset
222 self._build_aborted(queue, build)
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
223
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
224 elif cmd == 'ANS':
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
225 if payload.content_type != beep.BEEP_XML:
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
226 raise beep.ProtocolError(500)
88
8ae753a22494 Some refactoring of the BEEP implementation:
cmlenz
parents: 86
diff changeset
227 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
228 if elem.name == 'started':
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
229 self._build_started(queue, 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
230 elif elem.name == 'step':
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
231 self._build_step_completed(queue, build, elem,
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
232 timestamp_delta)
82
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
233 elif elem.name == 'completed':
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
234 self._build_completed(queue, build, elem, timestamp_delta)
70
ccd03b6f04ef Updated DTD for orchestration profile.
cmlenz
parents: 69
diff changeset
235 elif elem.name == 'aborted':
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
236 self._build_aborted(queue, build)
63
2332aedba328 * Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents: 61
diff changeset
237 elif elem.name == 'error':
2332aedba328 * Allow specifying a different name for a build slave (default is the host name).
cmlenz
parents: 61
diff changeset
238 build.status = Build.FAILURE
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
239
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
240 elif cmd == 'NUL':
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
241 self.building = False
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
242
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
243 snapshot_name = os.path.basename(snapshot)
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
244 message = beep.Payload(file(snapshot, 'rb'),
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
245 content_type='application/zip',
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
246 content_disposition=snapshot_name)
42
efa525876b1e Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents: 34
diff changeset
247 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
248
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
249 def _build_started(self, queue, 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
250 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
251 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
252 build.started -= timestamp_delta
253
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
253 build.update()
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
254
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
255 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
256 self.name, build.id, build.config, build.rev)
253
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
257 for listener in BuildSystem(queue.env).listeners:
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
258 listener.build_started(build)
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
259
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
260 def _build_step_completed(self, queue, build, elem, timestamp_delta=None):
204
e1a53e70b43f * Make deletion of build steps compatible with PySQLite2: records cannot be deleted inside a `select()` loop.
cmlenz
parents: 203
diff changeset
261 log.debug('Slave %s completed step "%s" with status %s', self.name,
e1a53e70b43f * Make deletion of build steps compatible with PySQLite2: records cannot be deleted inside a `select()` loop.
cmlenz
parents: 203
diff changeset
262 elem.attr['id'], elem.attr['result'])
200
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
263
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
264 db = queue.env.get_db_cnx()
200
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
265
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
266 step = BuildStep(queue.env, build=build.id, name=elem.attr['id'],
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
267 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
268 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
269 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
270 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
271 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
272 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
273 if elem.attr['result'] == 'failure':
135
d2b833187429 Bump up version number.
cmlenz
parents: 130
diff changeset
274 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
275 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
276 else:
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
277 step.status = BuildStep.SUCCESS
277
1141027071b3 Changes to snapshot archive creation/transmission:
cmlenz
parents: 267
diff changeset
278 step.errors += [error.gettext() for error in elem.children('error')]
112
a38eabd4b6e1 * Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents: 110
diff changeset
279 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
280
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
281 for idx, log_elem in enumerate(elem.children('log')):
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
282 build_log = BuildLog(queue.env, build=build.id, step=step.name,
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
283 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
284 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
285 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
286 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
287 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
288 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
289
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
290 for report_elem in elem.children('report'):
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
291 report = Report(queue.env, build=build.id, step=step.name,
213
25f84dd9f159 * Refactoring of build recipes, the file format has changed slightly:
cmlenz
parents: 204
diff changeset
292 category=report_elem.attr.get('category'),
25f84dd9f159 * Refactoring of build recipes, the file format has changed slightly:
cmlenz
parents: 204
diff changeset
293 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
294 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
295 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
296 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
297 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
298 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
299 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
300 report.insert(db=db)
116
86439c2aa6d6 Store report data in BDB XML database. Closes #31.
cmlenz
parents: 115
diff changeset
301
200
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
302 db.commit()
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
303
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
304 def _build_completed(self, queue, 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
305 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
306 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
307 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
308 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
309 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
310 else:
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
311 build.status = Build.SUCCESS
200
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
312 build.update()
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
313
253
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
314 log.info('Slave %s completed build %d ("%s" as of [%s]) with status %s',
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
315 self.name, build.id, build.config, build.rev,
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
316 build.status == Build.FAILURE and 'FAILURE' or 'SUCCESS')
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
317 for listener in BuildSystem(queue.env).listeners:
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
318 listener.build_completed(build)
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
319
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
320 def _build_aborted(self, queue, build):
204
e1a53e70b43f * Make deletion of build steps compatible with PySQLite2: records cannot be deleted inside a `select()` loop.
cmlenz
parents: 203
diff changeset
321 log.info('Slave %s aborted build %d ("%s" as of [%s])',
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
322 self.name, build.id, build.config, build.rev)
253
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
323 for listener in BuildSystem(queue.env).listeners:
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
324 listener.build_aborted(build)
184
fbf949f4c706 Allow invalidation of builds from the web interface. This results in the build being reset to ''PENDING'' status, and all build logs, slave information and reports deleted. Basically initiates a rebuild for a specific revision and target platform.
cmlenz
parents: 163
diff changeset
325
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
326 db = queue.env.get_db_cnx()
200
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
327
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
328 for step in list(BuildStep.select(queue.env, build=build.id, db=db)):
184
fbf949f4c706 Allow invalidation of builds from the web interface. This results in the build being reset to ''PENDING'' status, and all build logs, slave information and reports deleted. Basically initiates a rebuild for a specific revision and target platform.
cmlenz
parents: 163
diff changeset
329 step.delete(db=db)
fbf949f4c706 Allow invalidation of builds from the web interface. This results in the build being reset to ''PENDING'' status, and all build logs, slave information and reports deleted. Basically initiates a rebuild for a specific revision and target platform.
cmlenz
parents: 163
diff changeset
330
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
331 build.slave = None
253
cda723f3ac31 Provide hooks for build notification. Closes #62.
cmlenz
parents: 245
diff changeset
332 build.slave_info = {}
109
5bf22bb87915 Transmit build log and generated data back to the build master in XML format. Closes #23.
cmlenz
parents: 96
diff changeset
333 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
334 build.status = Build.PENDING
200
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
335 build.update(db=db)
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
336
692924ffed80 Changes to the BDB XML report store to support transactions. Closes #47.
cmlenz
parents: 197
diff changeset
337 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
338
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff changeset
339
82
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
340 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
341 """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
342
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
343 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
344 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
345 try:
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
346 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
347 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
348 tzoffset = time.timezone
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
349 if time.daylight:
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
350 tzoffset = time.altzone
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
351 return secs - tzoffset
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
352 except ValueError, e:
01200c88ddb0 Include timing information in the build messages transmitted from slave to master for better accuracy.
cmlenz
parents: 80
diff changeset
353 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
354
31
0b82d012e42c Add thin script shells around master and slave.
cmlenz
parents: 29
diff changeset
355 def main():
56
033366d81def Build slave now executes the build. Closes #10.
cmlenz
parents: 51
diff changeset
356 from bitten import __version__ as VERSION
19
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
357 from optparse import OptionParser
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
358
112
a38eabd4b6e1 * Store build logs in a structured way, for example to highlight messages on the error stream.
cmlenz
parents: 110
diff changeset
359 # Parse command-line arguments
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
360 parser = OptionParser(usage='usage: %prog [options] ENV_PATHS',
19
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
361 version='%%prog %s' % VERSION)
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
362 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
363 help='port number to use')
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
364 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
365 metavar='HOSTNAME',
33
d8d44216258a Exit the slave script when the master disconnects; and other minor fixes.
cmlenz
parents: 31
diff changeset
366 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
367 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
368 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
369 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
370 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
371 help='poll interval for changeset detection')
242
372d1de2e3ec * Fixes to the `<c:configure>` command added in [247]: Set current directory when invoking the script, and correctly pass `CFLAGS` and `CXXFLAGS`.
cmlenz
parents: 228
diff changeset
372 parser.add_option('--timewarp', action='store_true', dest='timewarp',
267
7429be6b5720 * Fix some typos.
cmlenz
parents: 253
diff changeset
373 help='adjust timestamps of builds to be near the '
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
374 'timestamps of the corresponding changesets')
19
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
375 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
376 const=logging.DEBUG, help='enable debugging output')
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
377 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
378 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
379 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
380 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
381 parser.set_defaults(port=7633, loglevel=logging.WARNING)
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
382 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
383
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff changeset
384 if len(args) < 1:
19
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
385 parser.error('incorrect number of arguments')
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff changeset
386
93
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
387 # Configure logging
157
2efdc69e63c3 Some style/documentation improvements to make Pylint happier.
cmlenz
parents: 152
diff changeset
388 logger = logging.getLogger('bitten')
2efdc69e63c3 Some style/documentation improvements to make Pylint happier.
cmlenz
parents: 152
diff changeset
389 logger.setLevel(options.loglevel)
93
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
390 handler = logging.StreamHandler()
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
391 if options.logfile:
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
392 handler.setLevel(logging.WARNING)
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
393 else:
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
394 handler.setLevel(options.loglevel)
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
395 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
396 handler.setFormatter(formatter)
157
2efdc69e63c3 Some style/documentation improvements to make Pylint happier.
cmlenz
parents: 152
diff changeset
397 logger.addHandler(handler)
93
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
398 if options.logfile:
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
399 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
400 handler.setLevel(options.loglevel)
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
401 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
402 '%(message)s')
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
403 handler.setFormatter(formatter)
157
2efdc69e63c3 Some style/documentation improvements to make Pylint happier.
cmlenz
parents: 152
diff changeset
404 logger.addHandler(handler)
93
b289e572bc7e Improved logging; the build master can now optionally log to a file. Closes #13.
cmlenz
parents: 92
diff changeset
405
19
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
406 port = options.port
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
407 if not (1 <= port <= 65535):
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
408 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
409
19
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
410 host = options.host
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
411 if not host:
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
412 import socket
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
413 ip = socket.gethostbyname(socket.gethostname())
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
414 try:
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
415 host = socket.gethostbyaddr(ip)[0]
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
416 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
417 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
418 host = ip
9db5f8eddb0d Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents: 18
diff changeset
419
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
420 envs = []
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
421 for arg in args:
228
a8c9dd7e3f71 * Cleanup and documentation for the `BuildQueue` class added in [236].
cmlenz
parents: 227
diff changeset
422 if not os.path.isdir(arg):
a8c9dd7e3f71 * Cleanup and documentation for the `BuildQueue` class added in [236].
cmlenz
parents: 227
diff changeset
423 log.warning('Ignoring %s: not a directory', arg)
a8c9dd7e3f71 * Cleanup and documentation for the `BuildQueue` class added in [236].
cmlenz
parents: 227
diff changeset
424 continue
227
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
425 env = Environment(arg)
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
426 if BuildSystem(env):
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
427 if env.needs_upgrade():
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
428 log.warning('Environment at %s needs to be upgraded', env.path)
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
429 continue
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
430 envs.append(env)
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
431 if not envs:
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
432 log.error('None of the specified environments has support for Bitten')
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
433 sys.exit(2)
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
434
014bc6c29dff * Factor build queue logic into a class separate from the build master.
cmlenz
parents: 213
diff changeset
435 master = Master(envs, host, port, adjust_timestamps=options.timewarp,
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
436 check_interval=options.interval)
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff changeset
437 try:
42
efa525876b1e Basic infrastructure for transmission of snapshot archives to build slaves. See #8.
cmlenz
parents: 34
diff changeset
438 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
439 except KeyboardInterrupt:
34
6da9468a6879 The build master now gracefully exits by first terminating all active sessions. Fixes #7.
cmlenz
parents: 33
diff changeset
440 master.quit()
31
0b82d012e42c Add thin script shells around master and slave.
cmlenz
parents: 29
diff changeset
441
0b82d012e42c Add thin script shells around master and slave.
cmlenz
parents: 29
diff changeset
442 if __name__ == '__main__':
33
d8d44216258a Exit the slave script when the master disconnects; and other minor fixes.
cmlenz
parents: 31
diff changeset
443 main()
Copyright (C) 2012-2017 Edgewall Software