Changelog update.
[debian_buildbot.git] / master / buildbot / schedulers / triggerable.py
blobfeadd905f215ce12a6c69dda5e8f1e544c1b601e
1 # This file is part of Buildbot. Buildbot is free software: you can
2 # redistribute it and/or modify it under the terms of the GNU General Public
3 # License as published by the Free Software Foundation, version 2.
5 # This program is distributed in the hope that it will be useful, but WITHOUT
6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
8 # details.
10 # You should have received a copy of the GNU General Public License along with
11 # this program; if not, write to the Free Software Foundation, Inc., 51
12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14 # Copyright Buildbot Team Members
16 from twisted.internet import reactor, defer
17 from buildbot.schedulers import base
18 from buildbot.process.properties import Properties
20 class Triggerable(base.BaseScheduler):
21 """This scheduler doesn't do anything until it is triggered by a Trigger
22 step in a factory. In general, that step will not complete until all of
23 the builds that I fire have finished.
24 """
26 compare_attrs = ('name', 'builderNames', 'properties')
27 def __init__(self, name, builderNames, properties={}):
28 base.BaseScheduler.__init__(self, name, builderNames, properties)
29 self._waiters = {}
30 self.reason = "Triggerable(%s)" % name
32 def trigger(self, ss, set_props=None):
33 """Trigger this scheduler. Returns a deferred that will fire when the
34 buildset is finished.
35 """
37 # properties for this buildset are composed of our own properties,
38 # potentially overridden by anything from the triggering build
39 props = Properties()
40 props.updateFromProperties(self.properties)
41 if set_props:
42 props.updateFromProperties(set_props)
44 d = self.parent.db.runInteraction(self._trigger, ss, props)
45 # this returns a Deferred that fires when the buildset is complete,
46 # with the buildset results (SUCCESS or FAILURE). This Deferred is
47 # not persistent: if the master is bounced, the "upstream" build (the
48 # one which used steps.trigger.Trigger) will disappear anyways.
49 def _done(res):
50 return res[0] # chain the Deferred
51 d.addCallback(_done)
52 return d
54 def _trigger(self, t, ss, props):
55 db = self.parent.db
56 ssid = db.get_sourcestampid(ss, t)
57 bsid = self.create_buildset(ssid, self.reason, t, props)
58 self._waiters[bsid] = d = defer.Deferred()
59 db.scheduler_subscribe_to_buildset(self.schedulerid, bsid, t)
60 reactor.callFromThread(self.parent.master.triggerSlaveManager)
61 return (d,) # apparently you can't return Deferreds from runInteraction
63 def run(self):
64 # this exists just to notify triggerers that the builds they
65 # triggered are now done, i.e. if buildbot.steps.trigger.Trigger is
66 # called with waitForFinish=True.
67 d = self.parent.db.runInteraction(self._run)
68 return d
69 def _run(self, t):
70 db = self.parent.db
71 res = db.scheduler_get_subscribed_buildsets(self.schedulerid, t)
72 # this returns bsid,ssid,results for all of our active subscriptions
73 for (bsid,ssid,complete,results) in res:
74 if complete:
75 d = self._waiters.pop(bsid, None)
76 if d:
77 reactor.callFromThread(d.callback, results)
78 db.scheduler_unsubscribe_buildset(self.schedulerid, bsid, t)
79 return None