Package buildbot :: Package status :: Package web :: Module slaves
[frames] | no frames]

Source Code for Module buildbot.status.web.slaves

  1   
  2  import time, urllib 
  3  from twisted.python import log 
  4  from twisted.web import html 
  5  from twisted.web.util import Redirect 
  6  from twisted.web.error import NoResource 
  7   
  8  from buildbot.status.web.base import HtmlResource, abbreviate_age, \ 
  9          OneLineMixin, path_to_slave, path_to_build 
 10  from buildbot import version, util 
 11   
 12  # /buildslaves/$slavename 
13 -class OneBuildSlaveResource(HtmlResource, OneLineMixin):
14 addSlash = False
15 - def __init__(self, slavename):
18
19 - def getTitle(self, req):
20 return "Buildbot: %s" % html.escape(self.slavename)
21
22 - def getChild(self, path, req):
23 s = self.getStatus(req) 24 slave = s.getSlave(self.slavename) 25 if path == "shutdown" and self.getControl(req): 26 slave.setGraceful(True) 27 return Redirect(path_to_slave(req, slave))
28
29 - def build_line(self, build, req):
30 buildnum = build.getNumber() 31 buildurl = path_to_build(req, build) 32 data = '<a href="%(builderurl)s">%(builder_name)s</a>' % self.get_line_values(req, build) 33 data += ' <a href="%s">#%d</a> ' % (buildurl, buildnum) 34 35 when = build.getETA() 36 if when is not None: 37 when_time = time.strftime("%H:%M:%S", 38 time.localtime(time.time() + when)) 39 data += "ETA %ds (%s) " % (when, when_time) 40 step = build.getCurrentStep() 41 if step: 42 data += "[%s]" % step.getName() 43 else: 44 data += "[waiting for Lock]" 45 # TODO: is this necessarily the case? 46 47 builder_control = self.getControl(req) 48 if builder_control is not None: 49 stopURL = path_to_build(req, build) + '/stop' 50 data += ''' 51 <form action="%s" class="command stopbuild" style="display:inline" method="post"> 52 <input type="submit" value="Stop Build" /> 53 </form>''' % stopURL 54 return data
55
56 - def body(self, req):
57 s = self.getStatus(req) 58 slave = s.getSlave(self.slavename) 59 my_builders = [] 60 for bname in s.getBuilderNames(): 61 b = s.getBuilder(bname) 62 for bs in b.getSlaves(): 63 slavename = bs.getName() 64 if bs.getName() == self.slavename: 65 my_builders.append(b) 66 67 # Current builds 68 current_builds = [] 69 for b in my_builders: 70 for cb in b.getCurrentBuilds(): 71 if cb.getSlavename() == self.slavename: 72 current_builds.append(cb) 73 74 data = [] 75 76 projectName = s.getProjectName() 77 78 data.append("<a href=\"%s\">%s</a>\n" % (self.path_to_root(req), projectName)) 79 80 data.append("<h1>Build Slave: %s</h1>\n" % html.escape(self.slavename)) 81 82 access_uri = slave.getAccessURI() 83 if access_uri: 84 data.append("<a href=\"%s\">Click to Access Slave</a>" % html.escape(access_uri)) 85 86 shutdown_url = req.childLink("shutdown") 87 88 if not slave.isConnected(): 89 data.append("<h2>NOT CONNECTED</h2>\n") 90 elif self.getControl(req): 91 if not slave.getGraceful(): 92 data.append('''<form method="POST" action="%s"> 93 <input type="submit" value="Gracefully Shutdown"> 94 </form>''' % shutdown_url) 95 else: 96 data.append("Gracefully shutting down...\n") 97 98 if current_builds: 99 data.append("<h2>Currently building:</h2>\n") 100 data.append("<ul>\n") 101 thisURL = "../../../" + path_to_slave(req, slave) 102 for build in current_builds: 103 data.append("<li>%s</li>\n" % self.build_line(build, req)) 104 data.append("</ul>\n") 105 106 else: 107 data.append("<h2>no current builds</h2>\n") 108 109 # Recent builds 110 data.append("<h2>Recent builds:</h2>\n") 111 data.append("<ul>\n") 112 n = 0 113 try: 114 max_builds = int(req.args.get('numbuilds')[0]) 115 except: 116 max_builds = 10 117 for build in s.generateFinishedBuilds(builders=[b.getName() for b in my_builders]): 118 if build.getSlavename() == self.slavename: 119 n += 1 120 data.append("<li>%s</li>\n" % self.make_line(req, build, True)) 121 if n > max_builds: 122 break 123 data.append("</ul>\n") 124 125 data.append(self.footer(s, req)) 126 return "".join(data)
127 128 # /buildslaves
129 -class BuildSlavesResource(HtmlResource):
130 title = "BuildSlaves" 131 addSlash = True 132
133 - def body(self, req):
134 s = self.getStatus(req) 135 data = "" 136 data += "<h1>Build Slaves</h1>\n" 137 138 used_by_builder = {} 139 for bname in s.getBuilderNames(): 140 b = s.getBuilder(bname) 141 for bs in b.getSlaves(): 142 slavename = bs.getName() 143 if slavename not in used_by_builder: 144 used_by_builder[slavename] = [] 145 used_by_builder[slavename].append(bname) 146 147 data += "<ol>\n" 148 for name in util.naturalSort(s.getSlaveNames()): 149 slave = s.getSlave(name) 150 slave_status = s.botmaster.slaves[name].slave_status 151 isBusy = len(slave_status.getRunningBuilds()) 152 data += " <li><a href=\"%s\">%s</a>:\n" % (req.childLink(urllib.quote(name,'')), name) 153 data += " <ul>\n" 154 version = slave.getVersion() 155 data += "<li>Running Buildbot version: %s" % version 156 builder_links = ['<a href="%s">%s</a>' 157 % (req.childLink("../builders/%s" % bname),bname) 158 for bname in used_by_builder.get(name, [])] 159 if builder_links: 160 data += (" <li>Used by Builders: %s</li>\n" % 161 ", ".join(builder_links)) 162 else: 163 data += " <li>Not used by any Builders</li>\n" 164 if slave.isConnected(): 165 data += " <li>Slave is currently connected</li>\n" 166 admin = slave.getAdmin() 167 if admin: 168 # munge it to avoid feeding the spambot harvesters 169 admin = admin.replace("@", " -at- ") 170 data += " <li>Admin: %s</li>\n" % admin 171 last = slave.lastMessageReceived() 172 if last: 173 lt = time.strftime("%Y-%b-%d %H:%M:%S", 174 time.localtime(last)) 175 age = abbreviate_age(time.time() - last) 176 data += " <li>Last heard from: %s " % age 177 data += '<font size="-1">(%s)</font>' % lt 178 data += "</li>\n" 179 if isBusy: 180 data += "<li>Slave is currently building.</li>" 181 else: 182 data += "<li>Slave is idle.</li>" 183 else: 184 data += " <li><b>Slave is NOT currently connected</b></li>\n" 185 186 data += " </ul>\n" 187 data += " </li>\n" 188 data += "\n" 189 190 data += "</ol>\n" 191 192 return data
193
194 - def getChild(self, path, req):
195 try: 196 slave = self.getStatus(req).getSlave(path) 197 return OneBuildSlaveResource(path) 198 except KeyError: 199 return NoResource("No such slave '%s'" % html.escape(path))
200