1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os, urllib
17 from cPickle import load
18 from twisted.python import log
19 from twisted.persisted import styles
20 from twisted.internet import defer
21 from zope.interface import implements
22 from buildbot import interfaces
23 from buildbot.util import bbcollections
24 from buildbot.util.eventual import eventually
25 from buildbot.changes import changes
26 from buildbot.status import buildset, builder, buildrequest
29 """
30 I represent the status of the buildmaster.
31 """
32 implements(interfaces.IStatus)
33
58
59 @property
62
65
68
69
70
77
80
82 prefix = self.getBuildbotURL()
83 if not prefix:
84 return None
85 if interfaces.IStatus.providedBy(thing):
86 return prefix
87 if interfaces.ISchedulerStatus.providedBy(thing):
88 pass
89 if interfaces.IBuilderStatus.providedBy(thing):
90 bldr = thing
91 return prefix + "builders/%s" % (
92 urllib.quote(bldr.getName(), safe=''),
93 )
94 if interfaces.IBuildStatus.providedBy(thing):
95 build = thing
96 bldr = build.getBuilder()
97 return prefix + "builders/%s/builds/%d" % (
98 urllib.quote(bldr.getName(), safe=''),
99 build.getNumber())
100 if interfaces.IBuildStepStatus.providedBy(thing):
101 step = thing
102 build = step.getBuild()
103 bldr = build.getBuilder()
104 return prefix + "builders/%s/builds/%d/steps/%s" % (
105 urllib.quote(bldr.getName(), safe=''),
106 build.getNumber(),
107 urllib.quote(step.getName(), safe=''))
108
109
110
111
112
113 if interfaces.IStatusEvent.providedBy(thing):
114
115 if isinstance(thing, changes.Change):
116 change = thing
117 return "%schanges/%d" % (prefix, change.number)
118
119 if interfaces.IStatusLog.providedBy(thing):
120 loog = thing
121 step = loog.getStep()
122 build = step.getBuild()
123 bldr = build.getBuilder()
124
125 logs = step.getLogs()
126 for i in range(len(logs)):
127 if loog is logs[i]:
128 break
129 else:
130 return None
131 return prefix + "builders/%s/builds/%d/steps/%s/logs/%s" % (
132 urllib.quote(bldr.getName(), safe=''),
133 build.getNumber(),
134 urllib.quote(step.getName(), safe=''),
135 urllib.quote(loog.getName()))
136
139
147 d.addCallback(chdict2change)
148 return d
149
152
164
166 """
167 @rtype: L{BuilderStatus}
168 """
169 return self.botmaster.builders[name].builder_status
170
173
176
182 d.addCallback(make_status_objects)
183 return d
184
185 - def generateFinishedBuilds(self, builders=[], branches=[],
186 num_builds=None, finished_before=None,
187 max_search=200):
188
189 def want_builder(bn):
190 if builders:
191 return bn in builders
192 return True
193 builder_names = [bn
194 for bn in self.getBuilderNames()
195 if want_builder(bn)]
196
197
198
199
200 sources = []
201 for bn in builder_names:
202 b = self.getBuilder(bn)
203 g = b.generateFinishedBuilds(branches,
204 finished_before=finished_before,
205 max_search=max_search)
206 sources.append(g)
207
208
209 next_build = [None] * len(sources)
210
211 def refill():
212 for i,g in enumerate(sources):
213 if next_build[i]:
214
215 continue
216 if not g:
217
218 continue
219 try:
220 next_build[i] = g.next()
221 except StopIteration:
222 next_build[i] = None
223 sources[i] = None
224
225 got = 0
226 while True:
227 refill()
228
229 candidates = [(i, b, b.getTimes()[1])
230 for i,b in enumerate(next_build)
231 if b is not None]
232 candidates.sort(lambda x,y: cmp(x[2], y[2]))
233 if not candidates:
234 return
235
236
237 i, build, finshed_time = candidates[-1]
238 next_build[i] = None
239 got += 1
240 yield build
241 if num_builds is not None:
242 if got >= num_builds:
243 return
244
251
252
253
254
259
261 """
262 @rtype: L{BuilderStatus}
263 """
264 filename = os.path.join(self.basedir, basedir, "builder")
265 log.msg("trying to load status pickle from %s" % filename)
266 builder_status = None
267 try:
268 builder_status = load(open(filename, "rb"))
269
270
271
272
273
274
275 versioneds = styles.versionedsToUpgrade
276 styles.doUpgrade()
277 if True in [ hasattr(o, 'wasUpgraded') for o in versioneds.values() ]:
278 log.msg("re-writing upgraded builder pickle")
279 builder_status.saveYourself()
280
281 except IOError:
282 log.msg("no saved status pickle, creating a new one")
283 except:
284 log.msg("error while loading status pickle, creating a new one")
285 log.msg("error follows:")
286 log.err()
287 if not builder_status:
288 builder_status = builder.BuilderStatus(name, category)
289 builder_status.addPointEvent(["builder", "created"])
290 log.msg("added builder %s in category %s" % (name, category))
291
292
293 builder_status.category = category
294 builder_status.basedir = os.path.join(self.basedir, basedir)
295 builder_status.name = name
296 builder_status.status = self
297
298 if not os.path.isdir(builder_status.basedir):
299 os.makedirs(builder_status.basedir)
300 builder_status.determineNextBuildNumber()
301
302 builder_status.setBigState("offline")
303 builder_status.setLogCompressionLimit(self.logCompressionLimit)
304 builder_status.setLogCompressionMethod(self.logCompressionMethod)
305 builder_status.setLogMaxSize(self.logMaxSize)
306 builder_status.setLogMaxTailSize(self.logMaxTailSize)
307
308 for t in self.watchers:
309 self.announceNewBuilder(t, name, builder_status)
310
311 return builder_status
312
317
322
327
332
334 result = {}
335
336 result['title'] = self.getTitle()
337 result['titleURL'] = self.getTitleURL()
338 result['buildbotURL'] = self.getBuildbotURL()
339
340
341 return result
342
344 for r in requests:
345
346
347 pass
348
350 if brid in self._buildreq_observers:
351 for o in self._buildreq_observers[brid]:
352 eventually(o, build_status)
353
355 self._buildreq_observers.add(brid, observer)
356
358 self._buildreq_observers.discard(brid, observer)
359
361 d = defer.Deferred()
362 self._buildset_finished_waiters.add(bsid, d)
363 self._maybeBuildsetFinished(bsid)
364 return d
365
377 d.addCallback(do_notifies)
378 d.addErrback(log.err, 'while notifying for buildset finishes')
379
381
382 self._builder_observers.add(buildername, watcher)
383
385 self._builder_observers.discard(buildername, watcher)
386
395 d.addCallback(do_notifies)
396 d.addErrback(log.err, 'while notifying buildsetSubmitted')
397
399 self._maybeBuildsetFinished(bsid)
400
402 buildername = notif['buildername']
403 if buildername in self._builder_observers:
404 brs = buildrequest.BuildRequestStatus(buildername,
405 notif['brid'], self)
406 for observer in self._builder_observers[buildername]:
407 if hasattr(observer, 'requestSubmitted'):
408 eventually(observer.requestSubmitted, brs)
409