[Buildbot-commits] buildbot/buildbot buildslave.py, 1.6, 1.7 interfaces.py, 1.62, 1.63 master.py, 1.109, 1.110
Brian Warner
warner at users.sourceforge.net
Sun Aug 12 23:17:14 UTC 2007
Update of /cvsroot/buildbot/buildbot/buildbot
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv27314/buildbot
Modified Files:
buildslave.py interfaces.py master.py
Log Message:
[project @ make BuildSlaves live as Service children of the BotMaster]
Original author: warner at lothar.com
Date: 2007-08-12 23:14:33+00:00
Index: buildslave.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/buildslave.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- buildslave.py 12 Aug 2007 22:22:46 -0000 1.6
+++ buildslave.py 12 Aug 2007 23:17:12 -0000 1.7
@@ -1,12 +1,15 @@
import time
+from zope.interface import implements
from twisted.python import log
from twisted.internet import defer, reactor
+from twisted.application import service
from buildbot.pbutil import NewCredPerspective
from buildbot.status.builder import SlaveStatus
+from buildbot.interfaces import IBuildSlave
-class BuildSlave(NewCredPerspective):
+class BuildSlave(NewCredPerspective, service.MultiService):
"""This is the master-side representative for a remote buildbot slave.
There is exactly one for each slave described in the config file (the
c['slaves'] list). When buildbots connect in (.attach), they get a
@@ -17,6 +20,8 @@
running builds. I am instantiated by the configuration file, and can be
subclassed to add extra functionality."""
+ implements(IBuildSlave)
+
def __init__(self, name, password, max_builds=None):
"""
@param name: botname this machine will supply when it connects
@@ -26,7 +31,7 @@
be run concurrently on this buildslave (the
default is None for no limit)
"""
-
+ service.MultiService.__init__(self)
self.slavename = name
self.password = password
self.botmaster = None # no buildmaster yet
Index: interfaces.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/interfaces.py,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -d -r1.62 -r1.63
--- interfaces.py 12 Aug 2007 22:22:51 -0000 1.62
+++ interfaces.py 12 Aug 2007 23:17:12 -0000 1.63
@@ -1035,3 +1035,6 @@
def logChunk(build, step, log, channel, text):
pass
+class IBuildSlave(Interface):
+ # this is a marker interface for the BuildSlave class
+ pass
Index: master.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/master.py,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -d -r1.109 -r1.110
--- master.py 7 Aug 2007 19:21:39 -0000 1.109
+++ master.py 12 Aug 2007 23:17:12 -0000 1.110
@@ -30,7 +30,7 @@
########################################
-class BotMaster(service.Service):
+class BotMaster(service.MultiService):
"""This is the master-side service which manages remote buildbot slaves.
It provides them with BuildSlaves, and distributes file change
@@ -40,6 +40,7 @@
debug = 0
def __init__(self):
+ service.MultiService.__init__(self)
self.builders = {}
self.builderNames = []
# builders maps Builder names to instances of bb.p.builder.Builder,
@@ -96,14 +97,58 @@
return d
return defer.succeed(None)
+ def loadConfig_Slaves(self, new_slaves):
+ old_slaves = [c for c in list(self)
+ if interfaces.IBuildSlave.providedBy(c)]
- def addSlave(self, slave):
- slave.setBotmaster(self)
- self.slaves[slave.slavename] = slave
+ # identify added/removed slaves. For each slave we construct a tuple
+ # of (name, password, class), and we consider the slave to be already
+ # present if the tuples match. (we include the class to make sure
+ # that BuildSlave(name,pw) is different than
+ # SubclassOfBuildSlave(name,pw) ). If the password or class has
+ # changed, we will remove the old version of the slave and replace it
+ # with a new one. If anything else has changed, we just update the
+ # old BuildSlave instance in place. If the name has changed, of
+ # course, it looks exactly the same as deleting one slave and adding
+ # an unrelated one.
+ old_t = {}
+ for s in old_slaves:
+ old_t[(s.slavename, s.password, s.__class__)] = s
+ new_t = {}
+ for s in new_slaves:
+ new_t[(s.slavename, s.password, s.__class__)] = s
+ removed = [old_t[t]
+ for t in old_t
+ if t not in new_t]
+ added = [new_t[t]
+ for t in new_t
+ if t not in old_t]
+ remaining_t = [t
+ for t in new_t
+ if t in old_t]
+ # removeSlave will hang up on the old bot
+ dl = []
+ for s in removed:
+ dl.append(self.removeSlave(s))
+ d = defer.DeferredList(dl, fireOnOneErrback=True)
+ def _add(res):
+ for s in added:
+ self.addSlave(s)
+ for t in remaining_t:
+ old_t[t].update(new_t[t])
+ d.addCallback(_add)
+ return d
- def removeSlave(self, slavename):
- d = self.slaves[slavename].disconnect()
- del self.slaves[slavename]
+ def addSlave(self, s):
+ s.setServiceParent(self)
+ s.setBotmaster(self)
+ self.slaves[s.slavename] = s
+
+ def removeSlave(self, s):
+ # TODO: technically, disownServiceParent could return a Deferred
+ s.disownServiceParent()
+ d = self.slaves[s.slavename].disconnect()
+ del self.slaves[s.slavename]
return d
def slaveLost(self, bot):
@@ -326,7 +371,6 @@
self.statusTargets = []
- self.slaves = []
# this ChangeMaster is a dummy, only used by tests. In the real
# buildmaster, where the BuildMaster instance is activated
# (startService is called) by twistd, this attribute is overwritten.
@@ -684,43 +728,8 @@
for s in new_slaves:
self.checker.addUser(s.slavename, s.password)
self.checker.addUser("change", "changepw")
-
- # identify new/old slaves. For each slave we construct a tuple of
- # (name, password, class), and we consider the slave to be already
- # present if the tuples match. (we include the class to make sure
- # that BuildSlave(name,pw) is different than
- # SubclassOfBuildSlave(name,pw) ). If the password or class has
- # changed, we will remove the old version of the slave and replace it
- # with a new one. If anything else has changed, we just update the
- # old BuildSlave instance in place. If the name has changed, of
- # course, it looks exactly the same as deleting one slave and adding
- # an unrelated one.
- old_t = {}
- for s in self.slaves:
- old_t[(s.slavename, s.password, s.__class__)] = s
- new_t = {}
- for s in new_slaves:
- new_t[(s.slavename, s.password, s.__class__)] = s
- removed = [old_t[t]
- for t in old_t
- if t not in new_t]
- added = [new_t[t]
- for t in new_t
- if t not in old_t]
- remaining_t = [t
- for t in new_t
- if t in old_t]
- # removeSlave will hang up on the old bot
- dl = [self.botmaster.removeSlave(s.slavename) for s in removed]
- d = defer.DeferredList(dl, fireOnOneErrback=True)
- def _add(res):
- for s in added:
- self.botmaster.addSlave(s)
- for t in remaining_t:
- old_t[t].update(new_t[t])
- self.slaves = new_slaves
- d.addCallback(_add)
- return d
+ # let the BotMaster take care of the rest
+ return self.botmaster.loadConfig_Slaves(new_slaves)
def loadConfig_Sources(self, sources):
if not sources:
More information about the Commits
mailing list