[Buildbot-commits] buildbot/buildbot buildslave.py,1.7,1.8

Brian Warner warner at users.sourceforge.net
Sat Sep 29 01:07:58 UTC 2007


Update of /cvsroot/buildbot/buildbot/buildbot
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv25039/buildbot

Modified Files:
	buildslave.py 
Log Message:
[project @ add arg to send email when buildslaves go missing. Closes #64.]

Original author: warner at lothar.com
Date: 2007-09-29 01:06:11+00:00

Index: buildslave.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/buildslave.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- buildslave.py	12 Aug 2007 23:17:12 -0000	1.7
+++ buildslave.py	29 Sep 2007 01:07:49 -0000	1.8
@@ -1,5 +1,7 @@
 
 import time
+from email.Message import Message
+from email.Utils import formatdate
 from zope.interface import implements
 from twisted.python import log
 from twisted.internet import defer, reactor
@@ -7,6 +9,7 @@
 
 from buildbot.pbutil import NewCredPerspective
 from buildbot.status.builder import SlaveStatus
+from buildbot.status.mail import MailNotifier
 from buildbot.interfaces import IBuildSlave
 
 class BuildSlave(NewCredPerspective, service.MultiService):
@@ -14,7 +17,7 @@
     There is exactly one for each slave described in the config file (the
     c['slaves'] list). When buildbots connect in (.attach), they get a
     reference to this instance. The BotMaster object is stashed as the
-    .service attribute.
+    .botmaster attribute. The BotMaster is also our '.parent' Service.
 
     I represent a build slave -- a remote machine capable of
     running builds.  I am instantiated by the configuration file, and can be
@@ -22,7 +25,8 @@
 
     implements(IBuildSlave)
 
-    def __init__(self, name, password, max_builds=None):
+    def __init__(self, name, password, max_builds=None,
+                 notify_on_missing=[], missing_timeout=3600):
         """
         @param name: botname this machine will supply when it connects
         @param password: password this machine will supply when
@@ -41,6 +45,13 @@
         self.slavebuilders = []
         self.max_builds = max_builds
         self.lastMessageReceived = 0
+        if isinstance(notify_on_missing, str):
+            notify_on_missing = [notify_on_missing]
+        self.notify_on_missing = notify_on_missing
+        for i in notify_on_missing:
+            assert isinstance(i, str)
+        self.missing_timeout = missing_timeout
+        self.missing_timer = None
 
     def update(self, new):
         """
@@ -78,6 +89,10 @@
         @return: a Deferred that fires with a suitable pb.IPerspective to
                  give to the slave (i.e. 'self')"""
 
+        if self.missing_timer:
+            self.missing_timer.cancel()
+            self.missing_timer = None
+
         if self.slave:
             # uh-oh, we've got a duplicate slave. The most likely
             # explanation is that the slave is behind a slow link, thinks we
@@ -164,7 +179,52 @@
         self.slave_status.setConnected(False)
         self.botmaster.slaveLost(self)
         log.msg("BuildSlave.detached(%s)" % self.slavename)
+        if self.notify_on_missing and self.parent:
+            self.missing_timer = reactor.callLater(self.missing_timeout,
+                                                   self._missing_timer_fired)
+
+    def _missing_timer_fired(self):
+        self.missing_timer = None
+        # notify people, but only if we're still in the config
+        if not self.parent:
+            return
+
+        # first, see if we have a MailNotifier we can use. This gives us a
+        # fromaddr and a relayhost.
+        buildmaster = self.botmaster.parent
+        status = buildmaster.getStatus()
+        for st in buildmaster.statusTargets:
+            if isinstance(st, MailNotifier):
+                break
+        else:
+            # if not, they get a default MailNotifier, which always uses SMTP
+            # to localhost and uses a dummy fromaddr of "buildbot".
+            log.msg("buildslave-missing msg using default MailNotifier")
+            st = MailNotifier("buildbot")
+        # now construct the mail
+        text = "The Buildbot working for '%s'\n" % status.getProjectName()
+        text += ("has noticed that the buildslave named %s went away\n" %
+                 self.slavename)
+        text += "\n"
+        text += ("It last disconnected at %s (buildmaster-local time)\n" %
+                 time.ctime(time.time() - self.missing_timeout)) # close enough
+        text += "\n"
+        text += "The admin on record (as reported by BUILDSLAVE:info/admin)\n"
+        text += "was '%s'.\n" % self.slave_status.getAdmin()
+        text += "\n"
+        text += "Sincerely,\n"
+        text += " The Buildbot\n"
+        text += " %s\n" % status.getProjectURL()
 
+        m = Message()
+        m.set_payload(text)
+        m['Date'] = formatdate(localtime=True)
+        m['Subject'] = "Buildbot: buildslave %s was lost" % self.slavename
+        m['From'] = st.fromaddr
+        recipients = self.notify_on_missing
+        d = st.sendMessage(m, recipients)
+        # return the Deferred for testing purposes
+        return d
 
     def disconnect(self):
         """Forcibly disconnect the slave.





More information about the Commits mailing list