| OLD | NEW |
| (Empty) |
| 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): | |
| 16 HtmlResource.__init__(self) | |
| 17 self.slavename = 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_v
alues(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), project
Name)) | |
| 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.quot
e(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)) | |
| OLD | NEW |