def content(self, request, ctx): s = self.getStatus(request) slave = s.getSlave(self.slavename) my_builders = [] for bname in s.getBuilderNames(): b = s.getBuilder(bname) for bs in b.getSlaves(): if bs.getName() == self.slavename: my_builders.append(b) # Current builds current_builds = [] for b in my_builders: for cb in b.getCurrentBuilds(): if cb.getSlavename() == self.slavename: current_builds.append(self.get_line_values(request, cb)) # try: # max_builds = int(request.args.get('numbuilds')[0]) # except: # max_builds = 10 max_builds = 10 recent_builds = [] n = 0 for rb in s.generateFinishedBuilds(builders=[b.getName() for b in my_builders]): if rb.getSlavename() == self.slavename: n += 1 recent_builds.append(self.get_line_values(request, rb)) if n > max_builds: break # connects over the last hour slave = s.getSlave(self.slavename) connect_count = slave.getConnectCount() if slave.isPaused(): pause_url = request.childLink("unpause") else: pause_url = request.childLink("pause") ctx.update(dict(slave=slave, slavename=self.slavename, current=current_builds, recent=recent_builds, shutdown_url=request.childLink("shutdown"), pause_url=pause_url, authz=self.getAuthz(request), this_url="../../../" + path_to_slave(request, slave), access_uri=slave.getAccessURI(), admin=slave.getAdmin() or u'', host=slave.getHost() or u'', info=slave.getInfoAsDict(), slave_version=slave.getVersion(), show_builder_column=True, connect_count=connect_count)) template = request.site.buildbot_service.templates.get_template("buildslave.html") data = template.render(**ctx) return data
def content(self, request, ctx): s = self.getStatus(request) slave = s.getSlave(self.slavename) my_builders = [] for bname in s.getBuilderNames(): b = s.getBuilder(bname) for bs in b.getSlaves(): if bs.getName() == self.slavename: my_builders.append(b) # Current builds current_builds = [] for b in my_builders: for cb in b.getCurrentBuilds(): if cb.getSlavename() == self.slavename: current_builds.append(self.get_line_values(request, cb)) try: max_builds = int(request.args.get('numbuilds')[0]) except: max_builds = 10 recent_builds = [] n = 0 for rb in s.generateFinishedBuilds( builders=[b.getName() for b in my_builders]): if rb.getSlavename() == self.slavename: n += 1 recent_builds.append(self.get_line_values(request, rb)) if n > max_builds: break # connects over the last hour slave = s.getSlave(self.slavename) connect_count = slave.getConnectCount() if slave.isPaused(): pause_url = request.childLink("unpause") else: pause_url = request.childLink("pause") ctx.update(dict(slave=slave, slavename=self.slavename, current=current_builds, recent=recent_builds, shutdown_url=request.childLink("shutdown"), pause_url=pause_url, authz=self.getAuthz(request), this_url="../../../" + path_to_slave(request, slave), access_uri=slave.getAccessURI()), admin=unicode(slave.getAdmin() or '', 'utf-8'), host=unicode(slave.getHost() or '', 'utf-8'), slave_version=slave.getVersion(), show_builder_column=True, connect_count=connect_count) template = request.site.buildbot_service.templates.get_template( "buildslave.html") data = template.render(**ctx) return data
def getChild(self, path, req): s = self.getStatus(req) slave = s.getSlave(self.slavename) if path == "shutdown": return ShutdownActionResource(slave) if path == "pause" or path == "unpause": return PauseActionResource(slave, path == "pause") return Redirect(path_to_slave(req, slave))
def getChild(self, path, req): s = self.getStatus(req) slave = s.getSlave(self.slavename) if path == "shutdown": if self.getAuthz(req).actionAllowed("gracefulShutdown", req, slave): slave.setGraceful(True) else: return Redirect(path_to_authfail(req)) return Redirect(path_to_slave(req, slave))
def content(self, req, cxt): b = self.builder_status cxt['name'] = b.getName() slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()] cxt['pending'] = [] for pb in b.getPendingBuilds(): source = pb.getSourceStamp() changes = [] if source.changes: for c in source.changes: changes.append({ 'url' : path_to_change(req, c), 'who' : c.who}) if source.revision: reason = source.revision else: reason = "no changes specified" cxt['pending'].append({ 'when': time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())), 'delay': util.formatInterval(util.now() - pb.getSubmitTime()), 'reason': reason, 'id': pb.brid, 'changes' : changes }) numbuilds = int(req.args.get('numbuilds', ['5'])[0]) recent = cxt['recent'] = [] for build in b.generateFinishedBuilds(num_builds=int(numbuilds)): recent.append(self.get_line_values(req, build, False)) sl = cxt['slaves'] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s['link'] = path_to_slave(req, slave) s['name'] = slave.getName() c = s['connected'] = slave.isConnected() if c: s['admin'] = slave.getAdmin() connected_slaves += 1 cxt['connected_slaves'] = connected_slaves cxt['authz'] = self.getAuthz(req) cxt['builder_url'] = path_to_builder(req, b) template = req.site.buildbot_service.templates.get_template("builder.html") return template.render(**cxt)
def content(self, req, cxt): b = self.builder_status cxt["name"] = b.getName() slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt["current"] = [self.builder(x, req) for x in b.getCurrentBuilds()] cxt["pending"] = [] for pb in b.getPendingBuilds(): changes = [] if pb.source.changes: for c in pb.source.changes: changes.append({"url": path_to_change(req, c), "who": c.who}) if pb.source.revision: reason = pb.source.revision else: reason = "no changes specified" cxt["pending"].append( { "when": time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())), "delay": util.formatInterval(util.now() - pb.getSubmitTime()), "reason": reason, "id": id(pb), "changes": changes, } ) numbuilds = int(req.args.get("numbuilds", ["5"])[0]) recent = cxt["recent"] = [] for build in b.generateFinishedBuilds(num_builds=int(numbuilds)): recent.append(self.get_line_values(req, build, False)) sl = cxt["slaves"] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s["link"] = path_to_slave(req, slave) s["name"] = slave.getName() c = s["connected"] = slave.isConnected() if c: s["admin"] = slave.getAdmin() connected_slaves += 1 cxt["connected_slaves"] = connected_slaves cxt["authz"] = self.getAuthz(req) cxt["builder_url"] = path_to_builder(req, b) template = req.site.buildbot_service.templates.get_template("builder.html") return template.render(**cxt)
def performAction(self, request): res = yield self.getAuthz(request).actionAllowed( self.action, request, self.slave) url = None if res: self.slave.setPaused(self.state) url = path_to_slave(request, self.slave) else: url = path_to_authzfail(request) defer.returnValue(url)
def performAction(self, request): res = yield self.getAuthz(request).actionAllowed(self.action, request, self.slave) url = None if res: self.slave.setGraceful(True) url = path_to_slave(request, self.slave) else: url = path_to_authzfail(request) defer.returnValue(url)
def performAction(self, request): d = self.getAuthz(request).actionAllowed(self.action, request, self.slave) wfd = defer.waitForDeferred(d) yield wfd res = wfd.getResult() url = None if res: self.slave.setGraceful(True) url = path_to_slave(request, self.slave) else: url = path_to_authzfail(request) yield url
def performAction(self, request): authz = self.getAuthz(request) res = yield authz.actionAllowed(self.action, request, self.slave) url = None if res: username = authz.getUsernameFull(request) slave_url = absolute_path_to_slave(self.slave.master.status, self.slave) log.msg("Shutdown %s gracefully requested by %s" % (self.slave.name, username)) self.slave.master.status.slaveShutdownGraceFully(self.slave.name, slave_url, username) self.slave.setGraceful(True) url = path_to_slave(request, self.slave) else: url = path_to_authzfail(request) defer.returnValue(url)
def content(self, request, ctx): s = self.getStatus(request) slave = s.getSlave(self.slavename) my_builders = [] for bname in s.getBuilderNames(): b = s.getBuilder(bname) for bs in b.getSlaves(): if bs.getName() == self.slavename: my_builders.append(b) # Current builds current_builds = [] for b in my_builders: for cb in b.getCurrentBuilds(): if cb.getSlavename() == self.slavename: current_builds.append(self.get_line_values(request, cb)) try: max_builds = int(request.args.get("numbuilds")[0]) except: max_builds = 10 recent_builds = [] n = 0 for rb in s.generateFinishedBuilds(builders=[b.getName() for b in my_builders]): if rb.getSlavename() == self.slavename: n += 1 recent_builds.append(self.get_line_values(request, rb)) if n > max_builds: break ctx.update( dict( slave=s.getSlave(self.slavename), slavename=self.slavename, current=current_builds, recent=recent_builds, shutdown_url=request.childLink("shutdown"), control=self.getControl(request), this_url="../../../" + path_to_slave(request, slave), access_uri=slave.getAccessURI(), ), admin=unicode(slave.getAdmin() or "", "utf-8"), host=unicode(slave.getHost() or "", "utf-8"), ) template = request.site.buildbot_service.templates.get_template("buildslave.html") data = template.render(**ctx) return data
def performAction(self, request): authz = self.getAuthz(request) res = yield authz.actionAllowed(self.action, request, self.slave) url = None if res: username = authz.getUsernameFull(request) slave_url = absolute_path_to_slave(self.slave.master.status, self.slave) if self.slave.isPaused(): self.slave.master.status.slaveUnpaused(self.slave.name, slave_url, username) action = "Unpause" else: self.slave.master.status.slavePaused(self.slave.name, slave_url, username) action = "Pause" log.msg("%s %s requested by %s" % (action, self.slave.name, username)) self.slave.setPaused(self.state) url = path_to_slave(request, self.slave) else: url = path_to_authzfail(request) defer.returnValue(url)
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += "<h1>Builder: %s</h1>\n" % html.escape(b.getName()) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "<ul>\n" numbuilds = req.args.get('numbuilds', ['5'])[0] for i,build in enumerate(b.generateFinishedBuilds(num_builds=int(numbuilds))): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: slaveurl = path_to_slave(req, slave) data += "<li><b><a href=\"%s\">%s</a></b>: " % (html.escape(slaveurl), html.escape(slave.getName())) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = path_to_builder(req, b) + '/force' data += make_force_build_form(forceURL) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = path_to_builder(req, b) + '/ping' data += """ <form action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL data += self.footer(status, req) return data
def content(self, request, ctx): s = self.getStatus(request) slave_status = s.getSlave(self.slavename) try: max_builds = int(request.args.get('numbuilds')[0]) except: max_builds = 15 filters = { "slave": self.slavename } bbURL = s.getBuildbotURL() slave_params = { "build_steps": ["0"], "build_props": ["0"], "builders": ["0"] } slave_json = SlaveJsonResource(s, slave_status) slave_dict = slave_json.asDict(request, params=slave_params) slave_url = bbURL + path_to_json_slaves(self.slavename) ctx['instant_json']['slave'] = {"url": slave_url, "data": json.dumps(slave_dict, separators=(',', ':')), "waitForPush": s.master.config.autobahn_push, "pushFilters": { "buildStarted": filters, "buildFinished": filters, "stepStarted": filters, "stepFinished": filters, }} recent_builds_json = PastBuildsJsonResource(s, max_builds, slave_status=slave_status) recent_builds_dict = yield recent_builds_json.asDict(request) recent_builds_url = bbURL + path_to_json_past_slave_builds(request, self.slavename, max_builds) ctx['instant_json']['recent_builds'] = {"url": recent_builds_url, "data": json.dumps(recent_builds_dict, separators=(',', ':')), "waitForPush": s.master.config.autobahn_push, "pushFilters": { "buildStarted": filters, "buildFinished": filters, }} # connects over the last hour slave = s.getSlave(self.slavename) if slave: connect_count = slave.getConnectCount() if slave.isPaused(): pause_url = request.childLink("unpause") else: pause_url = request.childLink("pause") ctx.update(dict(slave=slave, slavename=slave.getFriendlyName(), shutdown_url=request.childLink("shutdown"), pause_url = pause_url, authz=self.getAuthz(request), this_url="../../../" + path_to_slave(request, slave), access_uri=slave.getAccessURI()), admin=unicode(slave.getAdmin() or '', 'utf-8'), host=unicode(slave.getHost() or '', 'utf-8'), slave_version=slave.getVersion(), show_builder_column=True, connect_count=connect_count) else: ctx.update(dict(slavename=self.slavename, shutdown_url=request.childLink("shutdown"))) template = request.site.buildbot_service.templates.get_template("buildslave.html") data = template.render(**ctx) defer.returnValue(data)
def content(self, req, cxt): b = self.builder_status # Grab all the parameters which are prefixed with 'property.'. # We'll use these to filter the builds and build requests we # show below. props = {} prop_prefix = 'property.' for arg, val in req.args.iteritems(): if arg.startswith(prop_prefix): props[arg[len(prop_prefix):]] = val[0] def prop_match(oprops): for key, val in props.iteritems(): if key not in oprops or val != str(oprops[key]): return False return True cxt['name'] = b.getName() cxt['description'] = b.getDescription() req.setHeader('Cache-Control', 'no-cache') slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt['current'] = [ self.builder(x, req) for x in b.getCurrentBuilds() if prop_match(x.getProperties())] cxt['pending'] = [] statuses = yield b.getPendingBuildRequestStatuses() for pb in statuses: changes = [] source = yield pb.getSourceStamp() submitTime = yield pb.getSubmitTime() bsid = yield pb.getBsid() properties = yield \ pb.master.db.buildsets.getBuildsetProperties(bsid) if not prop_match(properties): continue if source.changes: for c in source.changes: changes.append({'url': path_to_change(req, c), 'who': c.who, 'revision': c.revision, 'repo': c.repository}) cxt['pending'].append({ 'when': time.strftime("%b %d %H:%M:%S", time.localtime(submitTime)), 'delay': util.formatInterval(util.now() - submitTime), 'id': pb.brid, 'changes': changes, 'num_changes': len(changes), 'properties': properties, }) numbuilds = cxt['numbuilds'] = int(req.args.get('numbuilds', [self.numbuilds])[0]) maxsearch = int(req.args.get('maxsearch', [200])[0]) recent = cxt['recent'] = [] for build in b.generateFinishedBuilds( num_builds=int(numbuilds), max_search=maxsearch, filter_fn=lambda b: prop_match(b.getProperties())): recent.append(self.get_line_values(req, build, False)) sl = cxt['slaves'] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s['link'] = path_to_slave(req, slave) s['name'] = slave.getName() c = s['connected'] = slave.isConnected() s['paused'] = slave.isPaused() s['admin'] = slave.getAdmin() or u'' if c: connected_slaves += 1 cxt['connected_slaves'] = connected_slaves cxt['authz'] = self.getAuthz(req) cxt['builder_url'] = path_to_builder(req, b) buildForceContext(cxt, req, self.getBuildmaster(req), b.getName()) template = req.site.buildbot_service.templates.get_template("builder.html") defer.returnValue(template.render(**cxt))
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') builder = self.build_status.getBuilder() cxt['builder'] = builder cxt['builder_name'] = builder.getFriendlyName() cxt['build_number'] = b.getNumber() cxt['builder_name_link'] = urllib.quote( self.build_status.getBuilder().getName(), safe='') cxt['b'] = b project = cxt['selectedproject'] = builder.getProject() cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) cxt['path_to_builders'] = path_to_builders(req, project) cxt['path_to_codebases'] = path_to_codebases(req, project) cxt['build_url'] = path_to_build(req, b, False) cxt['slave_debug_url'] = self.getBuildmaster( req).config.slave_debug_url cxt['customBuildUrls'] = b.getCustomUrls() codebases_arg = cxt['codebases_arg'] = getCodebasesArg(request=req) cxt['build_chain_top_build_url'] = yield b.getTopBuildUrl( codebases_arg) if not b.isFinished(): cxt['stop_build_chain'] = False step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for build slave]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for build slave]" % step.getName( ) else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime( "%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ssList = b.getSourceStamps() sourcestamps = cxt['sourcestamps'] = ssList all_got_revisions = b.getAllGotRevisions() cxt['got_revisions'] = all_got_revisions try: slave_obj = status.getSlave(b.getSlavename()) if slave_obj is not None: cxt['slave_friendly_name'] = slave_obj.getFriendlyName() cxt['slave_url'] = path_to_slave(req, slave_obj) else: cxt['slave_friendly_name'] = b.getSlavename() cxt['slave_url'] = "" except KeyError: pass if b.resume: cxt['resume'] = b.resume cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isFinished(): if s.isHidden(): continue step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not-started" step['time_to_run'] = "" cxt['steps'].append(step) step['link'] = path_to_step(req, s) step['text'] = " ".join(s.getText()) urls = [] getUrls = s.getURLs().items() for k, v in s.getURLs().items(): if isinstance(v, dict): if 'results' in v.keys() and v['results'] in css_classes: url_dict = dict(logname=k, url=v['url'] + codebases_arg, results=css_classes[v['results']]) else: url_dict = dict(logname=k, url=v['url'] + codebases_arg) else: url_dict = dict(logname=k, url=v + codebases_arg) urls.append(url_dict) step['urls'] = urls step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink( "steps/%s/logs/%s%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(logname, safe=''), codebases_arg)), 'name': logname }) scheduler = b.getProperty("scheduler", None) parameters = {} master = self.getBuildmaster(req) for sch in master.allSchedulers(): if isinstance(sch, ForceScheduler) and scheduler == sch.name: for p in sch.all_fields: parameters[p.name] = p ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): if not isinstance(value, dict): cxt_value = unicode(value) else: cxt_value = value if name == 'submittedTime': cxt_value = time.ctime(value) p = {'name': name, 'value': cxt_value, 'source': source} if len(cxt_value) > 500: p['short_value'] = cxt_value[:500] if name in parameters: param = parameters[name] if isinstance(param, TextParameter): p['text'] = param.value_to_text(value) p['cols'] = param.cols p['rows'] = param.rows p['label'] = param.label ps.append(p) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) cxt['elapsed'] = None if end and start: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) elif start: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) has_changes = False for ss in sourcestamps: has_changes = has_changes or ss.changes cxt['has_changes'] = has_changes cxt['authz'] = self.getAuthz(req) filters = {"number": b.getNumber()} build_json = BuildJsonResource(status, b) build_dict = yield build_json.asDict(req) cxt['instant_json']['build'] = { "url": path_to_json_build(status, req, builder.name, b.getNumber()), "data": json.dumps(build_dict, separators=(',', ':')), "waitForPush": status.master.config.autobahn_push, "pushFilters": { "buildStarted": filters, "buildFinished": filters, "stepStarted": filters, "stepFinished": filters, } } template = req.site.buildbot_service.templates.get_template( "build.html") defer.returnValue(template.render(**cxt))
def content(self, req, cxt): b = self.builder_status cxt['name'] = b.getName() req.setHeader('Cache-Control', 'no-cache') slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()] cxt['pending'] = [] for pb in b.getPendingBuilds(): source = pb.getSourceStamp() changes = [] if source.changes: for c in source.changes: changes.append({ 'url': path_to_change(req, c), 'who': c.who, 'revision': c.revision, 'repo': c.repository }) cxt['pending'].append({ 'when': time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())), 'delay': util.formatInterval(util.now() - pb.getSubmitTime()), 'id': pb.brid, 'changes': changes, 'num_changes': len(changes), }) numbuilds = int(req.args.get('numbuilds', ['5'])[0]) recent = cxt['recent'] = [] for build in b.generateFinishedBuilds(num_builds=int(numbuilds)): recent.append(self.get_line_values(req, build, False)) sl = cxt['slaves'] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s['link'] = path_to_slave(req, slave) s['name'] = slave.getName() c = s['connected'] = slave.isConnected() if c: s['admin'] = unicode(slave.getAdmin() or '', 'utf-8') connected_slaves += 1 cxt['connected_slaves'] = connected_slaves cxt['authz'] = self.getAuthz(req) cxt['builder_url'] = path_to_builder(req, b) template = req.site.buildbot_service.templates.get_template( "builder.html") return template.render(**cxt)
def body(self, req): s = self.getStatus(req) slave = s.getSlave(self.slavename) my_builders = [] for bname in s.getBuilderNames(): b = s.getBuilder(bname) for bs in b.getSlaves(): slavename = bs.getName() if bs.getName() == self.slavename: my_builders.append(b) # Current builds current_builds = [] for b in my_builders: for cb in b.getCurrentBuilds(): if cb.getSlavename() == self.slavename: current_builds.append(cb) data = [] projectName = s.getProjectName() data.append("<a href=\"%s\">%s</a>\n" % (self.path_to_root(req), projectName)) data.append("<h1>Build Slave: %s</h1>\n" % html.escape(self.slavename)) access_uri = slave.getAccessURI() if access_uri: data.append("<a href=\"%s\">Click to Access Slave</a>" % html.escape(access_uri)) shutdown_url = req.childLink("shutdown") if not slave.isConnected(): data.append("<h2>NOT CONNECTED</h2>\n") elif self.getControl(req): if not slave.getGraceful(): data.append('''<form method="POST" action="%s"> <input type="submit" value="Gracefully Shutdown"> </form>''' % shutdown_url) else: data.append("Gracefully shutting down...\n") if current_builds: data.append("<h2>Currently building:</h2>\n") data.append("<ul>\n") thisURL = "../../../" + path_to_slave(req, slave) for build in current_builds: data.append("<li>%s</li>\n" % self.build_line(build, req)) data.append("</ul>\n") else: data.append("<h2>no current builds</h2>\n") # Recent builds data.append("<h2>Recent builds:</h2>\n") data.append("<ul>\n") n = 0 try: max_builds = int(req.args.get('numbuilds')[0]) except: max_builds = 10 for build in s.generateFinishedBuilds(builders=[b.getName() for b in my_builders]): if build.getSlavename() == self.slavename: n += 1 data.append("<li>%s</li>\n" % self.make_line(req, build, True)) if n > max_builds: break data.append("</ul>\n") data.append(self.footer(s, req)) return "".join(data)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName( ) else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime( "%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ss = cxt['ss'] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt['most_recent_rev_build'] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: cxt['got_revision'] = str(got_revision) try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isHidden(): continue if s.isFinished(): step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) step_logs, step_urls, step_aliases = getStepLogsURLsAndAliases( s, False, lambda l: req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(l.getName(), safe=''))), ) step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName(), safe='')) step['text'] = " ".join(s.getText()) step['urls'] = step_urls step['nest_level'] = s.getNestLevel() step['logs'] = step_logs step['aliases'] = {} seen_aliases = set() for base, aliases in step_aliases.iteritems(): step['aliases'][base] = [{ 'text': a[0], 'url': a[1], } for a in aliases] seen_aliases.add(base) seen_aliases.difference_update(s['logname'] for s in step['urls']) seen_aliases.difference_update(s['name'] for s in step['logs']) # Append link-less log anchors for unbased aliases to attach to. # # We include an empty link so that custom templates that don't # support aliases don't crash when trying to render these anchors. # This will cause waterfalls that have alias data but haven't # updated their templates to render them to show blank links. This # is okay, since waterfalls that accept alias data should have # their templates updated to render this data. for base in sorted(seen_aliases): step['logs'].append({'name': base, 'link': ''}) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = {'name': name, 'value': value, 'source': source} if len(value) > 500: p['short_value'] = value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) cxt['exactly'] = (ss.revision is not None) or b.getChanges() cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template( "build.html") return template.render(**unicodify(cxt))
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName( ) else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime( "%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ss = cxt['ss'] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt['most_recent_rev_build'] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: cxt['got_revision'] = str(got_revision) try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isHidden(): continue if s.isFinished(): step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName(), safe='')) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step['nest_level'] = s.getNestLevel() step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(logname, safe=''))), 'name': logname }) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = {'name': name, 'value': value, 'source': source} if len(value) > 500: p['short_value'] = value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) cxt['exactly'] = (ss.revision is not None) or b.getChanges() cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template( "build.html") return template.render(**cxt)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName() else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ssList = b.getSourceStamps() sourcestamps = cxt['sourcestamps'] = ssList all_got_revisions = b.getAllGotRevisions() cxt['got_revisions'] = all_got_revisions try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isFinished(): if s.isHidden(): continue step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName(), safe='')) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append({'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(logname, safe=''))), 'name': logname}) scheduler = b.getProperty("scheduler", None) parameters = {} master = self.getBuildmaster(req) for sch in master.allSchedulers(): if isinstance(sch, ForceScheduler) and scheduler == sch.name: for p in sch.all_fields: parameters[p.name] = p ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): if not isinstance(value, dict): cxt_value = unicode(value) else: cxt_value = value p = {'name': name, 'value': cxt_value, 'source': source} if len(cxt_value) > 500: p['short_value'] = cxt_value[:500] if name in parameters: param = parameters[name] if isinstance(param, TextParameter): p['text'] = param.value_to_text(value) p['cols'] = param.cols p['rows'] = param.rows p['label'] = param.label ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) has_changes = False for ss in sourcestamps: has_changes = has_changes or ss.changes cxt['has_changes'] = has_changes cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template("build.html") return template.render(**cxt)
def content(self, req, cxt): status = self.getStatus(req) cxt = self.__prepare_context(req, cxt) slave_obj = None is_finished_build = self.build_status.isFinished() if is_finished_build: cxt['result_css'] = css_classes[self.build_status.getResults()] if is_finished_build and self.build_status.getTestResults(): cxt['tests_link'] = req.childLink("tests") try: slave_obj = status.getSlave(self.build_status.getSlavename()) except KeyError: pass if slave_obj: cxt['slave_friendly_name'] = slave_obj.getFriendlyName() cxt['slave_url'] = path_to_slave(req, slave_obj) if self.build_status.resume: cxt['resume'] = self.build_status.resume cxt['steps'] = yield get_steps( self.build_status.getSteps(), getCodebasesArg(req), req, ) parameters = self.__get_force_scheduler_parameters(req) cxt['properties'] = self.__get_properties(parameters) cxt['has_changes'] = any( map(lambda ss: ss.changes, self.build_status.getSourceStamps())) cxt['instant_json']['build'] = yield self.__prepare_instant_json( status, req) cxt['chained_build'] = yield req.site.buildbot_service.master.db.buildrequests.getBuildChain( self.build_status.buildChainID, ) current_build = next( ifilter(lambda x: x['id'] in self.build_status.brids, cxt['chained_build']), None, ) builder_project = self.build_status.getBuilder().getProject() if current_build: cxt['top_build_url'], cxt[ 'top_build_name'] = get_url_and_name_build_in_chain( current_build['startbrid'], cxt['chained_build'], builder_project, req, ) cxt['parent_build_url'], cxt[ 'parent_build_name'] = get_url_and_name_build_in_chain( current_build['triggeredbybrid'], cxt['chained_build'], builder_project, req, ) template = req.site.buildbot_service.templates.get_template( "build.html") defer.returnValue(template.render(**cxt))
def body(self, req): b = self.build_status status = self.getStatus(req) projectName = status.getProjectName() projectURL = status.getProjectURL() data = ('<div class="title"><a href="%s">%s</a></div>\n' % (self.path_to_root(req), projectName)) builder_name = b.getBuilder().getName() data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" % (path_to_builder(req, b.getBuilder()), builder_name, b.getNumber())) if not b.isFinished(): data += "<h2>Build In Progress</h2>" when = b.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "<div>ETA %ds (%s)</div>\n" % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL, self.isUsingUserPasswd(req)) if b.isFinished(): # Results map loosely to css_classes results = b.getResults() data += "<h2>Results:</h2>\n" text = " ".join(b.getText()) data += '<span class="%s">%s</span>\n' % (css_classes[results], text) if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url ss = b.getSourceStamp() data += "<h2>SourceStamp:</h2>\n" data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" # TODO: turn this into a table, or some other sort of definition-list # that doesn't take up quite so much vertical space try: slaveurl = path_to_slave(req, status.getSlave(b.getSlavename())) data += "<h2>Buildslave:</h2>\n <a href=\"%s\">%s</a>\n" % (html.escape(slaveurl), html.escape(b.getSlavename())) except KeyError: data += "<h2>Buildslave:</h2>\n %s\n" % html.escape(b.getSlavename()) data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason()) data += "<h2>Steps and Logfiles:</h2>\n" # TODO: # urls = self.original.getURLs() # ex_url_class = "BuildStep external" # for name, target in urls.items(): # text.append('[<a href="%s" class="%s">%s</a>]' % # (target, ex_url_class, html.escape(name))) data += "<ol>\n" for s in b.getSteps(): name = s.getName() time_to_run = 0 (start, end) = s.getTimes() if start and end: time_to_run = end - start if s.isFinished(): css_class = css_classes[s.getResults()[0]] elif s.isStarted(): css_class = "running" else: css_class = "" data += (' <li><span class="%s"><a href=\"%s\">%s</a> [%s] [%d seconds]</span>\n' % (css_class, req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()), time_to_run)) data += " <ol>\n" if s.getLogs(): for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink("steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) if s.getURLs(): for url in s.getURLs().items(): logname = url[0] logurl = url[1] data += (' <li><a href="%s">%s</a></li>\n' % (logurl, html.escape(logname))) data += "</ol>\n" data += " </li>\n" data += "</ol>\n" data += "<h2>Build Properties:</h2>\n" data += "<table><tr><th valign=\"left\">Name</th><th valign=\"left\">Value</th><th valign=\"left\">Source</th></tr>\n" for name, value, source in b.getProperties().asList(): value = str(value) if len(value) > 500: value = value[:500] + " .. [property value too long]" data += "<tr>" data += "<td>%s</td>" % html.escape(name) data += "<td>%s</td>" % html.escape(value) data += "<td>%s</td>" % html.escape(source) data += "</tr>\n" data += "</table>" data += "<h2>Blamelist:</h2>\n" if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "<div>no responsible users</div>\n" (start, end) = b.getTimes() data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % time.ctime(start) if end: data += "<tr><td>End</td><td>%s</td></tr>\n" % time.ctime(end) data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval(end - start) else: now = util.now() data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval(now - start) data += "</table>\n" if ss.changes: data += "<h2>All Changes</h2>\n" data += "<ol>\n" for c in ss.changes: data += "<li>" + c.asHTML() + "</li>\n" data += "</ol>\n" #data += html.PRE(b.changesText()) # TODO if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form method="post" action="%s" class="command rebuild">\n' % rebuildURL) data += make_name_user_passwd_form(self.isUsingUserPasswd(req)) data += make_extra_property_row(1) data += make_extra_property_row(2) data += make_extra_property_row(3) data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' data += self.footer(status, req) return data
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += "<h1>Builder: %s</h1>\n" % html.escape(b.getName()) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "<ul>\n" for i,build in enumerate(b.generateFinishedBuilds(num_builds=5)): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: slaveurl = path_to_slave(req, slave) data += "<li><b><a href=\"%s\">%s</a></b>: " % (html.escape(slaveurl), html.escape(slave.getName())) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = urllib.quote(req.childLink("force")) data += make_force_build_form(forceURL) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = urllib.quote(req.childLink("ping")) data += """ <form action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL # TODO: this stuff should be generated by a template of some sort projectURL = status.getProjectURL() projectName = status.getProjectName() data += '<hr /><div class="footer">\n' welcomeurl = self.path_to_root(req) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl data += "<br />\n" data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>' data += "-%s " % version if projectName: data += "working for the " if projectURL: data += "<a href=\"%s\">%s</a> project." % (projectURL, projectName) else: data += "%s project." % projectName data += "<br />\n" data += ("Page built: " + time.strftime("%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return data
def body(self, req): b = self.build_status status = self.getStatus(req) projectURL = status.getProjectURL() projectName = status.getProjectName() data = ('<div class="title"><a href="%s">%s</a></div>\n' % (self.path_to_root(req), projectName)) builder_name = b.getBuilder().getName() data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" % (path_to_builder( req, b.getBuilder()), builder_name, b.getNumber())) if not b.isFinished(): data += "<h2>Build In Progress</h2>" when = b.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "<div>ETA %ds (%s)</div>\n" % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL) if b.isFinished(): results = b.getResults() data += "<h2>Results:</h2>\n" text = " ".join(b.getText()) data += '<span class="%s">%s</span>\n' % (css_classes[results], text) if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url ss = b.getSourceStamp() data += "<h2>SourceStamp:</h2>\n" data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" # TODO: turn this into a table, or some other sort of definition-list # that doesn't take up quite so much vertical space try: slaveurl = path_to_slave(req, status.getSlave(b.getSlavename())) data += "<h2>Buildslave:</h2>\n <a href=\"%s\">%s</a>\n" % ( html.escape(slaveurl), html.escape(b.getSlavename())) except KeyError: data += "<h2>Buildslave:</h2>\n %s\n" % html.escape( b.getSlavename()) data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason()) data += "<h2>Steps and Logfiles:</h2>\n" # TODO: # urls = self.original.getURLs() # ex_url_class = "BuildStep external" # for name, target in urls.items(): # text.append('[<a href="%s" class="%s">%s</a>]' % # (target, ex_url_class, html.escape(name))) if b.getLogs(): # track time firsttime = time.time() lasttime = 0 data += "<ol>\n" for s in b.getSteps(): name = s.getName() (started, finished) = s.getTimes() if started == None: eltime = "not started yet..." else: firsttime = min(firsttime, started) if finished == None: lasttime = max(lasttime, time.time()) eltime = "current running time..." + self.formatTime( time.time() - started) else: lasttime = max(lasttime, finished) eltime = "total time..." + self.formatTime(finished - started) data += (" <li><a href=\"%s\">%s</a> [%s] %s\n" % (req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()), eltime)) if s.getLogs(): data += " <ol>\n" for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink( "steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) data += " </ol>\n" data += " </li>\n" data += "</ol>\n" data += "total elapsed time: " + self.formatTime(lasttime - firsttime) data += "<h2>Build Properties:</h2>\n" data += "<table><tr><th valign=\"left\">Name</th><th valign=\"left\">Value</th><th valign=\"left\">Source</th></tr>\n" for name, value, source in b.getProperties().asList(): value = str(value) if len(value) > 500: value = value[:500] + " .. [property value too long]" data += "<tr>" data += "<td>%s</td>" % html.escape(name) data += "<td>%s</td>" % html.escape(value) data += "<td>%s</td>" % html.escape(source) data += "</tr>\n" data += "</table>" data += "<h2>Blamelist:</h2>\n" if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "<div>no responsible users</div>\n" (start, end) = b.getTimes() data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % time.ctime(start) if end: data += "<tr><td>End</td><td>%s</td></tr>\n" % time.ctime(end) data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval( end - start) data += "</table>\n" if ss.changes: data += "<h2>All Changes</h2>\n" data += "<ol>\n" for c in ss.changes: data += "<li>" + c.asHTML() + "</li>\n" data += "</ol>\n" #data += html.PRE(b.changesText()) # TODO if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form action="%s" class="command rebuild">\n' % rebuildURL) data += make_row("Your name:", "<input type='text' name='username' />") data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' # TODO: this stuff should be generated by a template of some sort data += '<hr /><div class="footer">\n' welcomeurl = self.path_to_root(req) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl data += "<br />\n" data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>' data += "-%s " % version if projectName: data += "working for the " if projectURL: data += "<a href=\"%s\">%s</a> project." % (projectURL, projectName) else: data += "%s project." % projectName data += "<br />\n" data += ("Page built: " + time.strftime( "%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return data
def content(self, req, cxt): """ Mainly the same with parent class, but enumerates test results, too """ b = self.builder_status cxt['name'] = b.getName() req.setHeader('Cache-Control', 'no-cache') slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()] cxt['pending'] = [] for pb in b.getPendingBuilds(): source = pb.getSourceStamp() changes = [] if source.changes: for c in source.changes: changes.append({ 'url' : path_to_change(req, c), 'who' : c.who}) if source.revision: reason = source.revision else: reason = "no changes specified" cxt['pending'].append({ 'when': time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())), 'delay': util.formatInterval(util.now() - pb.getSubmitTime()), 'reason': reason, 'id': pb.brid, 'changes' : changes }) numbuilds = int(req.args.get('numbuilds', ['5'])[0]) recent = cxt['recent'] = [] tr_names = cxt['test_results_order'] = [] for build in b.generateFinishedBuilds(num_builds=int(numbuilds)): lvals = self.get_line_values(req, build, False) recent.append(lvals) for trn in lvals.get('test_result_order',[]): if trn not in tr_names: tr_names.append(trn) sl = cxt['slaves'] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s['link'] = path_to_slave(req, slave) s['name'] = slave.getName() c = s['connected'] = slave.isConnected() if c: s['admin'] = unicode(slave.getAdmin() or '', 'utf-8') connected_slaves += 1 cxt['connected_slaves'] = connected_slaves cxt['authz'] = self.getAuthz(req) cxt['builder_url'] = path_to_builder(req, b) template = req.site.buildbot_service.templates.get_template(self.tpl_page) return template.render(**cxt)
def content(self, req, cxt): b = self.builder_status # Grab all the parameters which are prefixed with 'property.'. # We'll use these to filter the builds and build requests we # show below. props = {} prop_prefix = 'property.' for arg, val in req.args.iteritems(): if arg.startswith(prop_prefix): props[arg[len(prop_prefix):]] = val[0] def prop_match(oprops): for key, val in props.iteritems(): if key not in oprops or val != str(oprops[key]): return False return True cxt['name'] = b.getName() cxt['description'] = b.getDescription() req.setHeader('Cache-Control', 'no-cache') slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt['current'] = [ self.builder(x, req) for x in b.getCurrentBuilds() if prop_match(x.getProperties()) ] cxt['pending'] = [] statuses = yield b.getPendingBuildRequestStatuses() for pb in statuses: changes = [] source = yield pb.getSourceStamp() submitTime = yield pb.getSubmitTime() bsid = yield pb.getBsid() properties = yield \ pb.master.db.buildsets.getBuildsetProperties(bsid) if not prop_match(properties): continue if source.changes: for c in source.changes: changes.append({ 'url': path_to_change(req, c), 'who': c.who, 'revision': c.revision, 'repo': c.repository }) cxt['pending'].append({ 'when': time.strftime("%b %d %H:%M:%S", time.localtime(submitTime)), 'delay': util.formatInterval(util.now() - submitTime), 'id': pb.brid, 'changes': changes, 'num_changes': len(changes), 'properties': properties, }) try: numbuilds = cxt['numbuilds'] = int( req.args.get('numbuilds', [self.numbuilds])[0]) except ValueError: numbuilds = cxt['numbuilds'] = 10 maxsearch = int(req.args.get('maxsearch', [200])[0]) recent = cxt['recent'] = [] for build in b.generateFinishedBuilds( num_builds=int(numbuilds), max_search=maxsearch, filter_fn=lambda b: prop_match(b.getProperties())): recent.append(self.get_line_values(req, build, False)) sl = cxt['slaves'] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s['link'] = path_to_slave(req, slave) s['name'] = slave.getName() c = s['connected'] = slave.isConnected() s['paused'] = slave.isPaused() s['admin'] = slave.getAdmin() or u'' if c: connected_slaves += 1 cxt['connected_slaves'] = connected_slaves cxt['authz'] = self.getAuthz(req) cxt['builder_url'] = path_to_builder(req, b) buildForceContext(cxt, req, self.getBuildmaster(req), b.getName()) template = req.site.buildbot_service.templates.get_template( "builder.html") defer.returnValue(template.render(**cxt))
def body(self, req): s = self.getStatus(req) slave = s.getSlave(self.slavename) my_builders = [] for bname in s.getBuilderNames(): b = s.getBuilder(bname) for bs in b.getSlaves(): slavename = bs.getName() if bs.getName() == self.slavename: my_builders.append(b) # Current builds current_builds = [] for b in my_builders: for cb in b.getCurrentBuilds(): if cb.getSlavename() == self.slavename: current_builds.append(cb) data = [] projectName = s.getProjectName() data.append("<a href=\"%s\">%s</a>\n" % (self.path_to_root(req), projectName)) data.append("<h1>Build Slave: %s</h1>\n" % html.escape(self.slavename)) access_uri = slave.getAccessURI() if access_uri: data.append("<a href=\"%s\">Click to Access Slave</a>" % html.escape(access_uri)) shutdown_url = req.childLink("shutdown") if not slave.isConnected(): data.append("<h2>NOT CONNECTED</h2>\n") elif self.getControl(req): if not slave.getGraceful(): data.append('''<form method="POST" action="%s"> <input type="submit" value="Gracefully Shutdown"> </form>''' % shutdown_url) else: data.append("Gracefully shutting down...\n") if current_builds: data.append("<h2>Currently building:</h2>\n") data.append("<ul>\n") thisURL = "../../../" + path_to_slave(req, slave) for build in current_builds: data.append("<li>%s</li>\n" % self.build_line(build, req)) data.append("</ul>\n") else: data.append("<h2>no current builds</h2>\n") # Recent builds data.append("<h2>Recent builds:</h2>\n") data.append("<ul>\n") n = 0 try: max_builds = int(req.args.get('numbuilds')[0]) except: max_builds = 10 for build in s.generateFinishedBuilds( builders=[b.getName() for b in my_builders]): if build.getSlavename() == self.slavename: n += 1 data.append("<li>%s</li>\n" % self.make_line(req, build, True)) if n > max_builds: break data.append("</ul>\n") data.append(self.footer(s, req)) return "".join(data)
def content(self, req, cxt): """ Mainly the same with parent class, but enumerates test results, too """ b = self.builder_status cxt["name"] = b.getName() req.setHeader("Cache-Control", "no-cache") slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt["current"] = [self.builder(x, req) for x in b.getCurrentBuilds()] cxt["pending"] = [] for pb in b.getPendingBuilds(): source = pb.getSourceStamp() changes = [] if source.changes: for c in source.changes: changes.append({"url": path_to_change(req, c), "who": c.who}) if source.revision: reason = source.revision else: reason = "no changes specified" cxt["pending"].append( { "when": time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())), "delay": util.formatInterval(util.now() - pb.getSubmitTime()), "reason": reason, "id": pb.brid, "changes": changes, } ) numbuilds = int(req.args.get("numbuilds", ["5"])[0]) recent = cxt["recent"] = [] tr_names = cxt["test_results_order"] = [] for build in b.generateFinishedBuilds(num_builds=int(numbuilds)): lvals = self.get_line_values(req, build, False) recent.append(lvals) for trn in lvals.get("test_result_order", []): if trn not in tr_names: tr_names.append(trn) sl = cxt["slaves"] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s["link"] = path_to_slave(req, slave) s["name"] = slave.getName() c = s["connected"] = slave.isConnected() if c: s["admin"] = unicode(slave.getAdmin() or "", "utf-8") connected_slaves += 1 cxt["connected_slaves"] = connected_slaves cxt["authz"] = self.getAuthz(req) cxt["builder_url"] = path_to_builder(req, b) template = req.site.buildbot_service.templates.get_template(self.tpl_page) return template.render(**cxt)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) cxt["b"] = b cxt["path_to_builder"] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): when = b.getETA() if when is not None: cxt["when"] = util.formatInterval(when) cxt["when_time"] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) else: cxt["result_css"] = css_classes[b.getResults()] if b.getTestResults(): cxt["tests_link"] = req.childLink("tests") ss = cxt["ss"] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt["most_recent_rev_build"] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" cxt["got_revision"] = got_revision try: cxt["slave_url"] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt["steps"] = [] for s in b.getSteps(): step = {"name": s.getName()} cxt["steps"].append(step) if s.isFinished(): step["css_class"] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step["time_to_run"] = util.formatInterval(end - start) elif s.isStarted(): step["css_class"] = "running" step["time_to_run"] = "running" else: step["css_class"] = "not_started" step["time_to_run"] = "" step["link"] = req.childLink("steps/%s" % urllib.quote(s.getName())) step["text"] = " ".join(s.getText()) step["urls"] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step["logs"] = [] for l in s.getLogs(): logname = l.getName() step["logs"].append( { "link": req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName()), urllib.quote(logname))), "name": logname, } ) ps = cxt["properties"] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = {"name": name, "value": value, "source": source} if len(value) > 500: p["short_value"] = value[:500] ps.append(p) cxt["responsible_users"] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt["start"] = time.ctime(start) if end: cxt["end"] = time.ctime(end) cxt["elapsed"] = util.formatInterval(end - start) else: now = util.now() cxt["elapsed"] = util.formatInterval(now - start) cxt["exactly"] = (ss.revision is not None) or b.getChanges() cxt["build_url"] = path_to_build(req, b) cxt["authz"] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template("build.html") return template.render(**cxt)
def body(self, req): b = self.build_status status = self.getStatus(req) projectURL = status.getProjectURL() projectName = status.getProjectName() data = ('<div class="title"><a href="%s">%s</a></div>\n' % (self.path_to_root(req), projectName)) builder_name = b.getBuilder().getName() data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" % (path_to_builder(req, b.getBuilder()), builder_name, b.getNumber())) if not b.isFinished(): data += "<h2>Build In Progress</h2>" when = b.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "<div>ETA %ds (%s)</div>\n" % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL, self.isUsingUserPasswd(req)) if b.isFinished(): # Results map loosely to css_classes results = b.getResults() data += "<h2>Results:</h2>\n" text = " ".join(b.getText()) data += '<span class="%s">%s</span>\n' % (css_classes[results], text) if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url ss = b.getSourceStamp() data += "<h2>SourceStamp:</h2>\n" data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" # TODO: turn this into a table, or some other sort of definition-list # that doesn't take up quite so much vertical space try: slaveurl = path_to_slave(req, status.getSlave(b.getSlavename())) data += "<h2>Buildslave:</h2>\n <a href=\"%s\">%s</a>\n" % (html.escape(slaveurl), html.escape(b.getSlavename())) except KeyError: data += "<h2>Buildslave:</h2>\n %s\n" % html.escape(b.getSlavename()) data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason()) data += "<h2>Steps and Logfiles:</h2>\n" # TODO: # urls = self.original.getURLs() # ex_url_class = "BuildStep external" # for name, target in urls.items(): # text.append('[<a href="%s" class="%s">%s</a>]' % # (target, ex_url_class, html.escape(name))) data += "<ol>\n" for s in b.getSteps(): name = s.getName() if s.isFinished(): css_class = css_classes[s.getResults()[0]] elif s.isStarted(): css_class = "running" else: css_class = "" data += (' <li><span class="%s"><a href=\"%s\">%s</a> [%s]</span>\n' % (css_class, req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()))) if s.getLogs(): data += " <ol>\n" for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink("steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) data += " </ol>\n" data += " </li>\n" data += "</ol>\n" data += "<h2>Build Properties:</h2>\n" data += "<table><tr><th valign=\"left\">Name</th><th valign=\"left\">Value</th><th valign=\"left\">Source</th></tr>\n" for name, value, source in b.getProperties().asList(): value = str(value) if len(value) > 500: value = value[:500] + " .. [property value too long]" data += "<tr>" data += "<td>%s</td>" % html.escape(name) data += "<td>%s</td>" % html.escape(value) data += "<td>%s</td>" % html.escape(source) data += "</tr>\n" data += "</table>" data += "<h2>Blamelist:</h2>\n" if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "<div>no responsible users</div>\n" (start, end) = b.getTimes() data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % time.ctime(start) if end: data += "<tr><td>End</td><td>%s</td></tr>\n" % time.ctime(end) data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval(end - start) data += "</table>\n" if ss.changes: data += "<h2>All Changes</h2>\n" data += "<ol>\n" for c in ss.changes: data += "<li>" + c.asHTML() + "</li>\n" data += "</ol>\n" #data += html.PRE(b.changesText()) # TODO if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form action="%s" class="command rebuild">\n' % rebuildURL) data += make_name_user_passwd_form(self.isUsingUserPasswd(req)) data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' # TODO: this stuff should be generated by a template of some sort data += '<hr /><div class="footer">\n' welcomeurl = self.path_to_root(req) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl data += "<br />\n" data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>' data += "-%s " % version if projectName: data += "working for the " if projectURL: data += "<a href=\"%s\">%s</a> project." % (projectURL, projectName) else: data += "%s project." % projectName data += "<br />\n" data += ("Page built: " + time.strftime("%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return data
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '' # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>No current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds</h2>\n" data += "<ul>\n" numbuilds = int(req.args.get('numbuilds', ['5'])[0]) for i, build in enumerate( b.generateFinishedBuilds(num_builds=int(numbuilds))): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: slaveurl = path_to_slave(req, slave) data += "<li><b><a href=\"%s\">%s</a></b>: " % ( html.escape(slaveurl), html.escape(slave.getName())) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(html.escape(slave.getHost())) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = path_to_builder(req, b) + '/force' data += make_force_build_form(forceURL, self.isUsingUserPasswd(req)) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = path_to_builder(req, b) + '/ping' data += """ <form method="post" action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL return data
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName( ) else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime( "%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ssList = b.getSourceStamps() sourcestamps = cxt['sourcestamps'] = ssList all_got_revisions = b.getAllGotRevisions() cxt['got_revisions'] = all_got_revisions try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName()} if s.isFinished(): if s.isHidden(): continue step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" cxt['steps'].append(step) step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName(), safe='')) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x: dict(url=x[1], logname=x[0]), s.getURLs().items()) step['logs'] = [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName(), safe=''), urllib.quote(logname, safe=''))), 'name': logname }) scheduler = b.getProperty("scheduler", None) parameters = {} master = self.getBuildmaster(req) for sch in master.allSchedulers(): if isinstance(sch, ForceScheduler) and scheduler == sch.name: for p in sch.all_fields: parameters[p.name] = p ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): if not isinstance(value, dict): cxt_value = unicode(value) else: cxt_value = value p = {'name': name, 'value': cxt_value, 'source': source} if len(cxt_value) > 500: p['short_value'] = cxt_value[:500] if name in parameters: param = parameters[name] if isinstance(param, TextParameter): p['text'] = param.value_to_text(value) p['cols'] = param.cols p['rows'] = param.rows p['label'] = param.label ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) exactly = True has_changes = False for ss in sourcestamps: exactly = exactly and (ss.revision is not None) has_changes = has_changes or ss.changes cxt['exactly'] = (exactly) or b.getChanges() cxt['has_changes'] = has_changes cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template( "build.html") return template.render(**cxt)
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += "<h1>Builder: %s</h1>\n" % html.escape(b.getName()) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "<ul>\n" for i, build in enumerate(b.generateFinishedBuilds(num_builds=5)): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: slaveurl = path_to_slave(req, slave) data += "<li><b><a href=\"%s\">%s</a></b>: " % ( html.escape(slaveurl), html.escape(slave.getName())) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = urllib.quote(req.childLink("force")) data += make_force_build_form(forceURL) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = urllib.quote(req.childLink("ping")) data += """ <form action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL # TODO: this stuff should be generated by a template of some sort projectURL = status.getProjectURL() projectName = status.getProjectName() data += '<hr /><div class="footer">\n' welcomeurl = self.path_to_root(req) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl data += "<br />\n" data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>' data += "-%s " % version if projectName: data += "working for the " if projectURL: data += "<a href=\"%s\">%s</a> project." % (projectURL, projectName) else: data += "%s project." % projectName data += "<br />\n" data += ("Page built: " + time.strftime( "%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return data
def content(self, req, cxt): b = self.builder_status cxt["name"] = b.getName() cxt["description"] = b.getDescription() req.setHeader("Cache-Control", "no-cache") slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt["current"] = [self.builder(x, req) for x in b.getCurrentBuilds()] cxt["pending"] = [] statuses = yield b.getPendingBuildRequestStatuses() for pb in statuses: changes = [] source = yield pb.getSourceStamp() submitTime = yield pb.getSubmitTime() bsid = yield pb.getBsid() properties = yield pb.master.db.buildsets.getBuildsetProperties(bsid) if source.changes: for c in source.changes: changes.append( {"url": path_to_change(req, c), "who": c.who, "revision": c.revision, "repo": c.repository} ) cxt["pending"].append( { "when": time.strftime("%b %d %H:%M:%S", time.localtime(submitTime)), "delay": util.formatInterval(util.now() - submitTime), "id": pb.brid, "changes": changes, "num_changes": len(changes), "properties": properties, } ) numbuilds = cxt["numbuilds"] = int(req.args.get("numbuilds", [self.numbuilds])[0]) recent = cxt["recent"] = [] for build in b.generateFinishedBuilds(num_builds=int(numbuilds)): recent.append(self.get_line_values(req, build, False)) sl = cxt["slaves"] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s["link"] = path_to_slave(req, slave) s["name"] = slave.getName() c = s["connected"] = slave.isConnected() s["paused"] = slave.isPaused() s["admin"] = unicode(slave.getAdmin() or "", "utf-8") if c: connected_slaves += 1 cxt["connected_slaves"] = connected_slaves cxt["authz"] = self.getAuthz(req) cxt["builder_url"] = path_to_builder(req, b) buildForceContext(cxt, req, self.getBuildmaster(req), b.getName()) template = req.site.buildbot_service.templates.get_template("builder.html") defer.returnValue(template.render(**cxt))
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): when = b.getETA() if when is not None: cxt['when'] = when cxt['when_time'] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) if self.build_control is not None: cxt['stop_url'] = urllib.quote(req.childLink("stop")) cxt['using_user_passwd'] = self.isUsingUserPasswd(req) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ss = cxt['ss'] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt['most_recent_rev_build'] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" cxt['got_revision'] = got_revision try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName() } cxt['steps'].append(step) time_to_run = 0 (start, end) = s.getTimes() if start and end: time_to_run = end - start # todo: format to 1h 5m 17s step['time_to_run'] = '%.1f' % time_to_run if s.isFinished(): step['css_class'] = css_classes[s.getResults()[0]] elif s.isStarted(): step['css_class'] = "running" else: step['css_class'] = "not_started" step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName())) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x:dict(url=x[1],logname=x[0]), s.getURLs().items()) step['logs']= [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName()), urllib.quote(logname))), 'name': logname }) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = { 'name': name, 'value': value, 'source': source} if len(value) > 500: p['short_value'] = value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) cxt['resubmit'] = b.isFinished() and self.builder_control is not None if cxt['resubmit']: cxt['exactly'] = (ss.revision is not None) or b.getChanges() cxt['rebuild_url'] = urllib.quote(req.childLink("rebuild")) cxt['using_user_passwd'] = self.isUsingUserPasswd(req) template = req.site.buildbot_service.templates.get_template("build.html") return template.render(**cxt)
def content(self, req, cxt): b = self.build_status status = self.getStatus(req) req.setHeader('Cache-Control', 'no-cache') cxt['b'] = b cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) if not b.isFinished(): step = b.getCurrentStep() if not step: cxt['current_step'] = "[waiting for Lock]" else: if step.isWaitingForLocks(): cxt['current_step'] = "%s [waiting for Lock]" % step.getName() else: cxt['current_step'] = step.getName() when = b.getETA() if when is not None: cxt['when'] = util.formatInterval(when) cxt['when_time'] = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) else: cxt['result_css'] = css_classes[b.getResults()] if b.getTestResults(): cxt['tests_link'] = req.childLink("tests") ss = cxt['ss'] = b.getSourceStamp() if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: cxt['most_recent_rev_build'] = True got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: cxt['got_revision'] = str(got_revision) try: cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) except KeyError: pass cxt['steps'] = [] for s in b.getSteps(): step = {'name': s.getName() } cxt['steps'].append(step) if s.isFinished(): step['css_class'] = css_classes[s.getResults()[0]] (start, end) = s.getTimes() step['time_to_run'] = util.formatInterval(end - start) elif s.isStarted(): if s.isWaitingForLocks(): step['css_class'] = "waiting" step['time_to_run'] = "waiting for locks" else: step['css_class'] = "running" step['time_to_run'] = "running" else: step['css_class'] = "not_started" step['time_to_run'] = "" step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName())) step['text'] = " ".join(s.getText()) step['urls'] = map(lambda x:dict(url=x[1],logname=x[0]), s.getURLs().items()) step['logs']= [] for l in s.getLogs(): logname = l.getName() step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" % (urllib.quote(s.getName()), urllib.quote(logname))), 'name': logname }) ps = cxt['properties'] = [] for name, value, source in b.getProperties().asList(): value = str(value) p = { 'name': name, 'value': value, 'source': source} if len(value) > 500: p['short_value'] = value[:500] ps.append(p) cxt['responsible_users'] = list(b.getResponsibleUsers()) (start, end) = b.getTimes() cxt['start'] = time.ctime(start) if end: cxt['end'] = time.ctime(end) cxt['elapsed'] = util.formatInterval(end - start) else: now = util.now() cxt['elapsed'] = util.formatInterval(now - start) cxt['exactly'] = (ss.revision is not None) or b.getChanges() cxt['build_url'] = path_to_build(req, b) cxt['authz'] = self.getAuthz(req) template = req.site.buildbot_service.templates.get_template("build.html") return template.render(**cxt)
def content(self, req, cxt): b = self.builder_status control = self.builder_control status = self.getStatus(req) cxt['name'] = b.getName() slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()] cxt['pending'] = [] for pb in b.getPendingBuilds(): changes = [] if pb.source.changes: for c in pb.source.changes: changes.append({ 'url' : path_to_change(req, c), 'who' : c.who}) elif pb.source.revision: reason = pb.source.revision else: reason = "no changes specified" cxt['pending'].append({ 'when': time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())), 'delay': util.formatInterval(util.now() - pb.getSubmitTime()), 'reason': reason, 'id': id(pb), 'changes' : changes }) if self.builder_control is not None: cxt['cancel_url'] = path_to_builder(req, b) + '/cancelbuild' numbuilds = int(req.args.get('numbuilds', ['5'])[0]) recent = cxt['recent'] = [] for build in b.generateFinishedBuilds(num_builds=int(numbuilds)): recent.append(self.get_line_values(req, build, False)) sl = cxt['slaves'] = [] for slave in slaves: s = {} sl.append(s) s['link'] = path_to_slave(req, slave) s['name'] = slave.getName() c = s['connected'] = slave.isConnected() if c: s['admin'] = slave.getAdmin() if control is not None and connected_slaves: cxt['force_url'] = path_to_builder(req, b) + '/force' cxt['use_user_passwd'] = self.isUsingUserPasswd(req) elif control is not None: cxt['all_slaves_offline'] = True if control is not None: cxt['ping_url'] = path_to_builder(req, b) + '/ping' template = req.site.buildbot_service.templates.get_template("builder.html") return template.render(**cxt)
def getChild(self, path, req): s = self.getStatus(req) slave = s.getSlave(self.slavename) if path == "shutdown" and self.getControl(req): slave.setGraceful(True) return Redirect(path_to_slave(req, slave))
def body(self, req): s = self.getStatus(req) slave = s.getSlave(self.slavename) my_builders = [] for bname in s.getBuilderNames(): b = s.getBuilder(bname) for bs in b.getSlaves(): slavename = bs.getName() if bs.getName() == self.slavename: my_builders.append(b) # Current builds current_builds = [] for b in my_builders: for cb in b.getCurrentBuilds(): if cb.getSlavename() == self.slavename: current_builds.append(cb) data = [] projectName = s.getProjectName() data.append("<a href=\"%s\">%s</a>\n" % (self.path_to_root(req), projectName)) data.append("<h1>Build Slave: %s</h1>\n" % html.escape(self.slavename)) access_uri = slave.getAccessURI() if access_uri: data.append("<a href=\"%s\">Click to Access Slave</a>" % html.escape(access_uri)) shutdown_url = req.childLink("shutdown") if not slave.isConnected(): data.append("<h2>NOT CONNECTED</h2>\n") elif self.getControl(req): if not slave.getGraceful(): data.append('''<form method="POST" action="%s"> <input type="submit" value="Gracefully Shutdown"> </form>''' % shutdown_url) else: data.append("Gracefully shutting down...\n") if current_builds: data.append("<h2>Currently building:</h2>\n") data.append("<ul>\n") thisURL = "../../../" + path_to_slave(req, slave) for build in current_builds: data.append("<li>%s</li>\n" % self.build_line(build, req)) data.append("</ul>\n") else: data.append("<h2>no current builds</h2>\n") # Recent builds data.append("<h2>Recent builds:</h2>\n") data.append("<ul>\n") n = 0 try: max_builds = int(req.args.get('numbuilds')[0]) except: max_builds = 10 for build in s.generateFinishedBuilds(builders=[b.getName() for b in my_builders]): if build.getSlavename() == self.slavename: n += 1 data.append("<li>%s</li>\n" % self.make_line(req, build, True)) if n > max_builds: break data.append("</ul>\n") projectURL = s.getProjectURL() projectName = s.getProjectName() data.append('<hr /><div class="footer">\n') welcomeurl = self.path_to_root(req) + "index.html" data.append("[<a href=\"%s\">welcome</a>]\n" % welcomeurl) data.append("<br />\n") data.append('<a href="http://buildbot.sourceforge.net/">Buildbot</a>') data.append("-%s " % version) if projectName: data.append("working for the ") if projectURL: data.append("<a href=\"%s\">%s</a> project." % (projectURL, projectName)) else: data.append("%s project." % projectName) data.append("<br />\n") data.append("Page built: " + time.strftime("%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data.append("</div>\n") return "".join(data)
def content(self, req, cxt): b = self.builder_status cxt['name'] = b.getName() cxt['description'] = b.getDescription() req.setHeader('Cache-Control', 'no-cache') slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()] cxt['pending'] = [] statuses = yield b.getPendingBuildRequestStatuses() for pb in statuses: changes = [] source = yield pb.getSourceStamp() submitTime = yield pb.getSubmitTime() bsid = yield pb.getBsid() properties = yield \ pb.master.db.buildsets.getBuildsetProperties(bsid) if source.changes: for c in source.changes: changes.append({ 'url' : path_to_change(req, c), 'who' : c.who, 'revision' : c.revision, 'repo' : c.repository }) cxt['pending'].append({ 'when': time.strftime("%b %d %H:%M:%S", time.localtime(submitTime)), 'delay': util.formatInterval(util.now() - submitTime), 'id': pb.brid, 'changes' : changes, 'num_changes' : len(changes), 'properties' : properties, }) numbuilds = int(req.args.get('numbuilds', [self.numbuilds])[0]) recent = cxt['recent'] = [] for build in b.generateFinishedBuilds(num_builds=int(numbuilds)): recent.append(self.get_line_values(req, build, False)) sl = cxt['slaves'] = [] connected_slaves = 0 for slave in slaves: s = {} sl.append(s) s['link'] = path_to_slave(req, slave) s['name'] = slave.getName() c = s['connected'] = slave.isConnected() if c: s['admin'] = unicode(slave.getAdmin() or '', 'utf-8') connected_slaves += 1 cxt['connected_slaves'] = connected_slaves cxt['authz'] = self.getAuthz(req) cxt['builder_url'] = path_to_builder(req, b) buildForceContext(cxt, req, self.getBuildmaster(req), b.getName()) template = req.site.buildbot_service.templates.get_template("builder.html") defer.returnValue(template.render(**cxt))