1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
from buildbot.process.buildstep import LoggingBuildStep, SUCCESS, FAILURE, EXCEPTION
from buildbot.process.properties import Properties
from buildbot.scheduler import Triggerable
from twisted.internet import defer
class Trigger(LoggingBuildStep):
"""I trigger a scheduler.Triggerable, to use one or more Builders as if
they were a single buildstep (like a subroutine call).
"""
name = "trigger"
flunkOnFailure = True
def __init__(self, schedulerNames=[], updateSourceStamp=True,
waitForFinish=False, set_properties={}, **kwargs):
"""
Trigger the given schedulers when this step is executed.
@param schedulerNames: A list of scheduler names that should be
triggered. Schedulers can be specified using
WithProperties, if desired.
@param updateSourceStamp: If True (the default), I will try to give
the schedulers an absolute SourceStamp for
their builds, so that a HEAD build will use
the same revision even if more changes have
occurred since my build's update step was
run. If False, I will use the original
SourceStamp unmodified.
@param waitForFinish: If False (the default), this step will finish
as soon as I've started the triggered
schedulers. If True, I will wait until all of
the triggered schedulers have finished their
builds.
@param set_properties: A dictionary of properties to set for any
builds resulting from this trigger. To copy
existing properties, use WithProperties. These
properties will override properties set in the
Triggered scheduler's constructor.
"""
assert schedulerNames, "You must specify a scheduler to trigger"
self.schedulerNames = schedulerNames
self.updateSourceStamp = updateSourceStamp
self.waitForFinish = waitForFinish
self.set_properties = set_properties
self.running = False
LoggingBuildStep.__init__(self, **kwargs)
self.addFactoryArguments(schedulerNames=schedulerNames,
updateSourceStamp=updateSourceStamp,
waitForFinish=waitForFinish,
set_properties=set_properties)
def interrupt(self, reason):
# TODO: this doesn't actually do anything.
if self.running:
self.step_status.setText(["interrupted"])
def start(self):
properties = self.build.getProperties()
# make a new properties object from a dict rendered by the old
# properties object
props_to_set = Properties()
props_to_set.update(properties.render(self.set_properties), "Trigger")
self.running = True
ss = self.build.getSourceStamp()
if self.updateSourceStamp:
got = properties.getProperty('got_revision')
if got:
ss = ss.getAbsoluteSourceStamp(got)
# (is there an easier way to find the BuildMaster?)
all_schedulers = self.build.builder.botmaster.parent.allSchedulers()
all_schedulers = dict([(sch.name, sch) for sch in all_schedulers])
unknown_schedulers = []
triggered_schedulers = []
# TODO: don't fire any schedulers if we discover an unknown one
dl = []
for scheduler in self.schedulerNames:
scheduler = properties.render(scheduler)
if all_schedulers.has_key(scheduler):
sch = all_schedulers[scheduler]
if isinstance(sch, Triggerable):
dl.append(sch.trigger(ss, set_props=props_to_set))
triggered_schedulers.append(scheduler)
else:
unknown_schedulers.append(scheduler)
else:
unknown_schedulers.append(scheduler)
if unknown_schedulers:
self.step_status.setText(['no scheduler:'] + unknown_schedulers)
rc = FAILURE
else:
rc = SUCCESS
self.step_status.setText(['triggered'] + triggered_schedulers)
if self.waitForFinish:
d = defer.DeferredList(dl, consumeErrors=1)
else:
d = defer.succeed([])
def cb(rclist):
rc = SUCCESS # (this rc is not the same variable as that above)
for was_cb, buildsetstatus in rclist:
# TODO: make this algo more configurable
if not was_cb:
rc = EXCEPTION
break
if buildsetstatus.getResults() == FAILURE:
rc = FAILURE
return self.finished(rc)
def eb(why):
return self.finished(FAILURE)
d.addCallbacks(cb, eb)
|