def call_msg_handlers(self, t, s, b, subject, stanza): if t == 'error': return if subject: j = JID(s) if not j.userhost() in self.g.keys(): self.log.log( 'ignored subject from %s, stanza was %s' % (escape(s), escape(stanza.toXml())), 3) else: self.log.log( 'got subject from %s, stanza was %s, let\'s call topichandlers' % (escape(s), escape(stanza.toXml())), 1) if j.resource: for i in self.topichandlers: self.call(i, s, subject) else: for i in self.topichandlers: self.call(i, s, b) else: delayed = [ i for i in stanza.children if (i.__class__ == domish.Element) and ( (i.name == 'delay') or ( (i.name == 'x') and (i.uri == 'jabber:x:delay'))) ] if delayed: dl = True else: dl = False for i in self.msghandlers: if (t == 'groupchat') or not i[1]: self.call(i[0], s, b, dl)
def performAction(self, req): authz = self.getAuthz(req) res = yield authz.actionAllowed(self.action, req, self.build_status) if not res: defer.returnValue(path_to_authzfail(req)) return b = self.build_status log.msg("web stopBuild of build %s:%s" % \ (b.getBuilder().getName(), b.getNumber())) name = authz.getUsernameFull(req) comments = req.args.get("comments", ["<no reason specified>"])[0] comments.decode(getRequestCharset(req)) # html-quote both the username and comments, just to be safe reason = ("The web-page 'stop build' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) c = interfaces.IControl(self.getBuildmaster(req)) bldrc = c.getBuilder(self.build_status.getBuilder().getName()) if bldrc: bldc = bldrc.getBuild(self.build_status.getNumber()) if bldc: bldc.stopBuild(reason) defer.returnValue(path_to_builder(req, self.build_status.getBuilder()))
def GenStepBox(stepstatus): """Generates a box for one step.""" class_ = build_get_class(stepstatus) style = '' if class_ and class_ in styles: style = styles[class_] stepname = stepstatus.getName() text = stepstatus.getText() or [] text = text[:] base_url = '%sbuilders/%s/builds/%d/steps' % ( waterfall_url, urllib.quote(stepstatus.getBuild().getBuilder().getName(), safe=''), stepstatus.getBuild().getNumber()) for steplog in stepstatus.getLogs(): name = steplog.getName() log.msg('name = %s' % name) url = '%s/%s/logs/%s' % ( base_url, urllib.quote(stepname, safe=''), urllib.quote(name)) text.append('<a href="%s">%s</a>' % (url, html.escape(name))) for name, target in stepstatus.getURLs().iteritems(): text.append('<a href="%s">%s</a>' % (target, html.escape(name))) fmt = '<tr><td style="%s">%s</td></tr>' return fmt % (style, '<br/>'.join(text))
def stop(self, req, auth_ok=False): # check if this is allowed if not auth_ok: if not self.getAuthz(req).actionAllowed('stopBuild', req, self.build_status): return Redirect(path_to_authfail(req)) b = self.build_status log.msg("web stopBuild of build %s:%s" % \ (b.getBuilder().getName(), b.getNumber())) name = req.args.get("username", ["<unknown>"])[0] comments = req.args.get("comments", ["<no reason specified>"])[0] # html-quote both the username and comments, just to be safe reason = ("The web-page 'stop build' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) c = interfaces.IControl(self.getBuildmaster(req)) bldrc = c.getBuilder(self.build_status.getBuilder().getName()) if bldrc: bldc = bldrc.getBuild(self.build_status.getNumber()) if bldc: bldc.stopBuild(reason) # we're at http://localhost:8080/svn-hello/builds/5/stop?[args] and # we want to go to: http://localhost:8080/svn-hello r = Redirect(path_to_builder(req, self.build_status.getBuilder())) d = defer.Deferred() reactor.callLater(1, d.callback, r) return DeferredResource(d)
def performAction(self, req): authz = self.getAuthz(req) res = yield authz.actionAllowed(self.action, req, self.build_status) if not res: defer.returnValue(path_to_authzfail(req)) return b = self.build_status log.msg("web stopBuild of build %s:%s" % (b.getBuilder().getName(), b.getNumber())) name = authz.getUsernameFull(req) comments = _get_comments_from_request(req) # html-quote both the username and comments, just to be safe reason = ("The web-page 'stop build' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) c = interfaces.IControl(self.getBuildmaster(req)) bldrc = c.getBuilder(self.build_status.getBuilder().getName()) if bldrc: bldc = bldrc.getBuild(self.build_status.getNumber()) if bldc: bldc.stopBuild(reason) defer.returnValue(path_to_builder(req, self.build_status.getBuilder()))
def stop(self, req, auth_ok=False): # check if this is allowed if not auth_ok: return StopBuildActionResource(self.build_status) b = self.build_status log.msg("web stopBuild of build %s:%s" % (b.getBuilder().getName(), b.getNumber())) name = self.getAuthz(req).getUsernameFull(req) comments = _get_comments_from_request(req) # html-quote both the username and comments, just to be safe reason = ("The web-page 'stop build' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) c = interfaces.IControl(self.getBuildmaster(req)) bldrc = c.getBuilder(self.build_status.getBuilder().getName()) if bldrc: bldc = bldrc.getBuild(self.build_status.getNumber()) if bldc: bldc.stopBuild(reason) # we're at http://localhost:8080/svn-hello/builds/5/stop?[args] and # we want to go to: http://localhost:8080/svn-hello r = Redirect(path_to_builder(req, self.build_status.getBuilder())) d = defer.Deferred() reactor.callLater(1, d.callback, r) return DeferredResource(d)
def force(self, req): """ Custom properties can be passed from the web form. To do this, subclass this class, overriding the force() method. You can then determine the properties (usually from form values, by inspecting req.args), then pass them to this superclass force method. """ name = req.args.get("username", ["<unknown>"])[0] reason = req.args.get("comments", ["<no reason specified>"])[0] branch = req.args.get("branch", [""])[0] revision = req.args.get("revision", [""])[0] r = "The web-page 'force build' button was pressed by '%s': %s\n" \ % (html.escape(name), html.escape(reason)) log.msg("web forcebuild of builder '%s', branch='%s', revision='%s'" " by user '%s'" % (self.builder_status.getName(), branch, revision, name)) if not self.builder_control: # TODO: tell the web user that their request was denied log.msg("but builder control is disabled") return Redirect("..") if self.isUsingUserPasswd(req): if not self.authUser(req): return Redirect("../../authfail") # keep weird stuff out of the branch and revision strings. TODO: # centralize this somewhere. if not re.match(r'^[\w\.\-\/]*$', branch): log.msg("bad branch '%s'" % branch) return Redirect("..") if not re.match(r'^[\w\.\-\/]*$', revision): log.msg("bad revision '%s'" % revision) return Redirect("..") if not branch: branch = None if not revision: revision = None # TODO: if we can authenticate that a particular User pushed the # button, use their name instead of None, so they'll be informed of # the results. # TODO2: we can authenticate that a particular User pushed the button # now, so someone can write this support. but it requires a # buildbot.changes.changes.Change instance which is tedious at this # stage to compute s = SourceStamp(branch=branch, revision=revision) req = BuildRequest(r, s, builderName=self.builder_status.getName()) try: self.builder_control.requestBuildSoon(req) except interfaces.NoSlaveError: # TODO: tell the web user that their request could not be # honored pass # send the user back to the builder page return Redirect(".")
def renderFailure(self, failure, request): try: xml = request.d.toxml() except: xml = "" # if not hasattr(request, 'channel'): # log.msg("The request got away from me before I could render an error page.") # log.err(failure) # return failure if not self.failed: self.failed = 1 if failure: request.write( "<html><head><title>%s: %s</title></head><body>\n" % (html.escape(str( failure.type)), html.escape(str(failure.value)))) else: request.write( "<html><head><title>Failure!</title></head><body>\n") utils.renderFailure(failure, request) request.write("<h3>Here is the partially processed DOM:</h3>") request.write("\n<pre>\n") request.write(html.escape(xml)) request.write("\n</pre>\n") request.write("</body></html>") request.finish() return failure
def chatlogs_topic_handler(source, subject, immediately=False): j = jid.JID(source) room = j.userhost() #bot.g[room].topic = subject #print 'try print subject..' #print [subject] TOPICS[room] = subject nick = j.resource #print [nick] room_subject = censor_msg( replace_links(escape(subject).replace('\n', '<br/>'))) if (bot.g[room].get_option('chatlogs', config.CHATLOGS_ENABLE) == 'on'): if nick: nick = censor_msg(escape(nick)) #print [nick] m = lang.msg('chatlog_change_subject', (nick, room_subject), lang.getLang(source)) #print [m] m = u'<font class="roomcsubject">' + m + u'</font>\n' #print [m] else: m = lang.msg('chatlog_subject', (room_subject, ), lang.getLang(source)) m = u'<div class="roomsubject">' + m + u'</div>\n' #print 'let\'s write_to_log' #print (room, m, nick <> None) if immediately: write_to_log_(room, m, nick <> None, nick <> None) else: write_to_log(room, m, nick <> None, nick <> None) else: bot.log.log('got subject.. but logs disabled', 2)
def to_html(self, href_base="", timestamps="short-local"): d = self.e['d'] time_short, time_extended = web_format_time(d['time'], timestamps) msg = html.escape(log.format_message(d)) if 'failure' in d: lines = str(d['failure']).split("\n") html_lines = [html.escape(line) for line in lines] f_html = "\n".join(html_lines) msg += " FAILURE:<pre>%s</pre>" % f_html level = d.get('level', log.OPERATIONAL) level_s = "" if level >= log.UNUSUAL: level_s = self.LEVELMAP.get(level, "") + " " details = " ".join(["Event #%d" % d['num'], "TubID=%s" % self.e['from'], "Incarnation=%s" % self.incarnation, time_extended]) label = '<span title="%s">%s</span>' % (details, time_short) data = '%s [<span id="E%s"><a href="%s#E%s">%d</a></span>]: %s%s' \ % (label, self.anchor_index, href_base, self.anchor_index, d['num'], level_s, msg) if self.is_trigger: data += " [INCIDENT-TRIGGER]" return data
def performAction(self, req): d = self.getAuthz(req).actionAllowed(self.action, req, self.build_status) wfd = defer.waitForDeferred(d) yield wfd res = wfd.getResult() if not res: yield path_to_authfail(req) return b = self.build_status log.msg("web stopBuild of build %s:%s" % \ (b.getBuilder().getName(), b.getNumber())) name = req.args.get("username", ["<unknown>"])[0] comments = req.args.get("comments", ["<no reason specified>"])[0] # html-quote both the username and comments, just to be safe reason = ("The web-page 'stop build' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) c = interfaces.IControl(self.getBuildmaster(req)) bldrc = c.getBuilder(self.build_status.getBuilder().getName()) if bldrc: bldc = bldrc.getBuild(self.build_status.getNumber()) if bldc: bldc.stopBuild(reason) yield path_to_builder(req, self.build_status.getBuilder()) return
def rebuild(self, req): if self.isUsingUserPasswd(req): if not self.authUser(req): return Redirect("../../../authfailed") b = self.build_status bc = self.builder_control builder_name = b.getBuilder().getName() log.msg("web rebuild of build %s:%s" % (builder_name, b.getNumber())) name = req.args.get("username", ["<unknown>"])[0] comments = req.args.get("comments", ["<no reason specified>"])[0] reason = ("The web-page 'rebuild' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) extraProperties = getAndCheckProperties(req) if not bc or not b.isFinished() or extraProperties is None: log.msg("could not rebuild: bc=%s, isFinished=%s" % (bc, b.isFinished())) # TODO: indicate an error else: bc.resubmitBuild(b, reason, extraProperties) # we're at # http://localhost:8080/builders/NAME/builds/5/rebuild?[args] # Where should we send them? # # Ideally it would be to the per-build page that they just started, # but we don't know the build number for it yet (besides, it might # have to wait for a current build to finish). The next-most # preferred place is somewhere that the user can see tangible # evidence of their build starting (or to see the reason that it # didn't start). This should be the Builder page. r = Redirect("../..") # the Builder's page d = defer.Deferred() reactor.callLater(1, d.callback, r) return DeferredResource(d)
def chatlogs_leave_handler(item, typ, reason): # typ: 0: leave # 1: kick # 2: ban # 3: rename if item.room and (item.room.get_option('chatlogs', config.CHATLOGS_ENABLE) == 'on'): if typ == 0: if reason: m = lang.msg('chatlog_leaved_reason', (escape(reason), ), lang.getLang(item.jid)) else: m = lang.get('chatlog_leaved', lang.getLang(item.jid)) elif typ == 1: if reason: m = lang.msg('chatlog_kicked_reason', (escape(reason), ), lang.getLang(item.jid)) else: m = lang.get('chatlog_kicked', lang.getLang(item.jid)) elif typ == 2: if reason: m = lang.msg('chatlog_banned_reason', (escape(reason), ), lang.getLang(item.jid)) else: m = lang.get('chatlog_banned', lang.getLang(item.jid)) elif typ == 3: m = lang.msg('chatlog_changed_nick', (escape(item.nick), ), lang.getLang(item.jid)) if typ == 3: nick = reason else: nick = item.nick m = u'<span class="ml">%s %s</span>' % (escape(nick), m) write_to_log(item.room.jid, m)
def ToHtml(text): """Convert a string in a wiki-style format into HTML.""" indent = 0 in_item = False output = [] for line in text.splitlines(False): match = re.match(r'^( +)\- (.*)$', line) if match: if indent < len(match.group(1)): indent = len(match.group(1)) elif indent > len(match.group(1)): while indent > len(match.group(1)): #output.append('</ul>') output.append('<br/><br/>') indent -= 2 #if in_item: # Close previous item #output.append('</li>') #output.append('<li>') in_item = True line = match.group(2) elif indent: if line.startswith((' ' * indent) + ' '): # List continuation line = line.strip() output.append('<br>') else: # List is done if in_item: #output.append('</li>') in_item = False while indent > 0: #output.append('</div>') indent -= 2 if line.startswith('/'): if not '?' in line: line_full = line + '?as_text=1' else: line_full = line + '&as_text=1' output.append('<a href="' + html.escape(line_full) + '">' + html.escape(line) + '</a>') else: output.append(html.escape(line).replace(' ', ' ')) if not in_item: output.append('<br>') #if in_item: #output.append('</li>') while indent > 0: #output.append('</div>') indent -= 2 return '\n'.join(output)
def performAction(self, req): authz = self.getAuthz(req) d = authz.actionAllowed(self.action, req, self.build_status) wfd = defer.waitForDeferred(d) yield wfd res = wfd.getResult() if not res: yield path_to_authfail(req) return b = self.build_status log.msg("web stopBuild of build %s:%s" % \ (b.getBuilder().getName(), b.getNumber())) name = authz.getUsername(req) comments = req.args.get("comments", ["<no reason specified>"])[0] # html-quote both the username and comments, just to be safe reason = ("The web-page 'stop build' button was pressed by " "'%s': %s\n" % (html.escape(name), html.escape(comments))) c = interfaces.IControl(self.getBuildmaster(req)) bldrc = c.getBuilder(self.build_status.getBuilder().getName()) if bldrc: bldc = bldrc.getBuild(self.build_status.getNumber()) if bldc: bldc.stopBuild(reason) yield path_to_builder(req, self.build_status.getBuilder()) return
def performAction(self, req): # check if this is allowed d = self.getAuthz(req).actionAllowed(self.action, req, self.builder_status) wfd = defer.waitForDeferred(d) yield wfd res = wfd.getResult() if not res: log.msg("..but not authorized") yield path_to_authfail(req) return master = self.getBuildmaster(req) # keep weird stuff out of the branch revision, and property strings. branch_validate = master.config.validation['branch'] revision_validate = master.config.validation['revision'] if not branch_validate.match(self.req_args['branch']): log.msg("bad branch '%s'" % self.req_args['branch']) yield path_to_builder(req, self.builder_status) return if not revision_validate.match(self.req_args['revision']): log.msg("bad revision '%s'" % self.req_args['revision']) yield path_to_builder(req, self.builder_status) return properties = getAndCheckProperties(req) if properties is None: yield path_to_builder(req, self.builder_status) return if not self.req_args['branch']: self.req_args['branch'] = None if not self.req_args['revision']: self.req_args['revision'] = None d = master.db.sourcestamps.addSourceStamp( branch=self.req_args['branch'], revision=self.req_args['revision'], project=self.req_args['project'], repository=self.req_args['repository']) wfd = defer.waitForDeferred(d) yield wfd ssid = wfd.getResult() r = ("The web-page 'force build' button was pressed by '%s': %s\n" % (html.escape( self.req_args['name']), html.escape(self.req_args['reason']))) d = master.addBuildset(builderNames=[self.builder_status.getName()], ssid=ssid, reason=r, properties=properties.asDict()) wfd = defer.waitForDeferred(d) yield wfd tup = wfd.getResult() # check that (bsid, brids) were properly stored if not isinstance(tup, (int, dict)): log.err("(ignored) while trying to force build") # send the user back to the builder page yield path_to_builder(req, self.builder_status)
def force(self, req, auth_ok=False): name = req.args.get("username", ["<unknown>"])[0] reason = req.args.get("comments", ["<no reason specified>"])[0] branch = req.args.get("branch", [""])[0] revision = req.args.get("revision", [""])[0] repository = req.args.get("repository", [""])[0] project = req.args.get("project", [""])[0] r = "The web-page 'force build' button was pressed by '%s': %s\n" \ % (html.escape(name), html.escape(reason)) log.msg("web forcebuild of builder '%s', branch='%s', revision='%s'," " repository='%s', project='%s' by user '%s'" % (self.builder_status.getName(), branch, revision, repository, project, name)) # check if this is allowed if not auth_ok: if not self.getAuthz(req).actionAllowed('forceBuild', req, self.builder_status): log.msg("..but not authorized") return Redirect(path_to_authfail(req)) # keep weird stuff out of the branch revision, and property strings. # TODO: centralize this somewhere. if not re.match(r'^[\w.+/~-]*$', branch): log.msg("bad branch '%s'" % branch) return Redirect(path_to_builder(req, self.builder_status)) if not re.match(r'^[ \w\.\-\/]*$', revision): log.msg("bad revision '%s'" % revision) return Redirect(path_to_builder(req, self.builder_status)) properties = getAndCheckProperties(req) if properties is None: return Redirect(path_to_builder(req, self.builder_status)) if not branch: branch = None if not revision: revision = None # TODO: if we can authenticate that a particular User pushed the # button, use their name instead of None, so they'll be informed of # the results. # TODO2: we can authenticate that a particular User pushed the button # now, so someone can write this support. but it requires a # buildbot.changes.changes.Change instance which is tedious at this # stage to compute s = SourceStamp(branch=branch, revision=revision, project=project, repository=repository) try: c = interfaces.IControl(self.getBuildmaster(req)) bc = c.getBuilder(self.builder_status.getName()) bc.submitBuildRequest(s, r, properties) except interfaces.NoSlaveError: # TODO: tell the web user that their request could not be # honored pass # send the user back to the builder page return Redirect(path_to_builder(req, self.builder_status))
def body(self, req): s = self.step_status b = s.getBuild() builder_name = b.getBuilder().getName() build_num = b.getNumber() data = "" data += '<h1>BuildStep <a href="%s">%s</a>:' % (path_to_builder(req, b.getBuilder()), builder_name) data += '<a href="%s">#%d</a>' % (path_to_build(req, b), build_num) data += ":%s</h1>\n" % s.getName() if s.isFinished(): data += "<h2>Finished</h2>\n" "<p>%s</p>\n" % html.escape("%s" % s.getText()) else: data += "<h2>Not Finished</h2>\n" "<p>ETA %s seconds</p>\n" % s.getETA() exp = s.getExpectations() if exp: data += "<h2>Expectations</h2>\n" "<ul>\n" for e in exp: data += "<li>%s: current=%s, target=%s</li>\n" % (html.escape(e[0]), e[1], e[2]) data += "</ul>\n" (start, end) = s.getTimes() if not start: start_text = end_text = elapsed = "Not Started" else: start_text = ctime(start) if end: end_text = ctime(end) elapsed = util.formatInterval(end - start) else: end_text = "Not Finished" elapsed = util.formatInterval(util.now() - start) data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % start_text data += "<tr><td>End</td><td>%s</td></tr>\n" % end_text data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % elapsed data += "</table>\n" logs = s.getLogs() if logs: data += "<h2>Logs</h2>\n" "<ul>\n" for logfile in logs: if logfile.hasContents(): # FIXME: If the step name has a / in it, this is broken # either way. If we quote it but say '/'s are safe, # it chops up the step name. If we quote it and '/'s # are not safe, it escapes the / that separates the # step name from the log number. logname = logfile.getName() logurl = req.childLink("logs/%s" % urllib.quote(logname)) data += '<li><a href="%s">%s</a></li>\n' % (logurl, html.escape(logname)) else: data += "<li>%s</li>\n" % html.escape(logname) data += "</ul>\n" return data
def error_handler(self, m): try: if m['isError'] == 1: self.log.err(escape(repr(m))) reactor.stop() else: self.log.log(escape(repr(m))) except: print m
def call_cmd_handlers(self, t, s, body, subject, stanza): if subject: return #found or create item groupchat = s.split('/')[0] nick = s[len(groupchat)+1:] try: item = self.g[groupchat][nick] except: item = new_item(self) item.jid = s item.realjid = s if item.room and (item.nick == self.muc.get_nick(item.room.jid)): self.log.log(u'own message from %s ignored' % (escape(item.jid), ), 2) return #check for bad words if item.room and (t == 'groupchat'): self.check_text(item, body) #launch rewrite engines commands = [(t, item, body, stanza)] itercount = 0 rl = config.REWRITE_POWER changed = True while changed and (len(commands) < rl) and (itercount < rl): itercount += 1 self.log.log(escape('launch rewrite engines.. step %s, commands=%s' % (itercount, commands)), 1) changed = False for engine in self.rewriteengines: r_commands = [] for command in commands: r_command = self.call(engine, command) if r_command: r_commands = r_commands + r_command changed = True else: r_commands = r_commands + [command] commands = r_commands self.log.log(escape('rewrite engines done, itercount=%s, commands=%s' % (itercount, commands)), 1) if itercount == rl: item.lmsg(t, 'rewrite_cycle', rl) elif len(commands) >= rl: item.lmsg(t, 'rewrite_too_many_commands', rl) else: #execute commands, generated by rewrite engines commands = [command for command in commands if self.check_for_ddos(command[1].jid)] # check if not DDOS for command in commands: [t, s, b, stanza] = command params = b.split() if len(params): cmd = b.split()[0] params = b[len(cmd)+1:] for i in self.cmdhandlers: if cmd.lower() == i[1]: if s.allowed(i[2]): if (s.room and s.room.bot) or not i[3]: self.log.log(u'Calling command handler <b>%s</b> for command <font color=red>%s</font> from <font color=blue>%s (%s)</font><br/>stanza: <font color=grey>%s</font>' % (escape(repr(i[0])), escape(b), escape(s.jid), escape(repr(s)), escape(stanza.toXml())), 4) try: i[0](t, s, params) except: m = ''.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) self.log.err(escape(m)) item.lmsg(t, 'ERROR', config.ERRLOGFILE) else: s.lmsg(t, 'muc_only') else: s.lmsg(t, 'not_allowed')
def performAction(self, req): # check if this is allowed d = self.getAuthz(req).actionAllowed(self.action, req, self.builder_status) wfd = defer.waitForDeferred(d) yield wfd res = wfd.getResult() if not res: log.msg("..but not authorized") yield path_to_authfail(req) return master = self.getBuildmaster(req) # keep weird stuff out of the branch revision, and property strings. branch_validate = master.config.validation['branch'] revision_validate = master.config.validation['revision'] if not branch_validate.match(self.req_args['branch']): log.msg("bad branch '%s'" % self.req_args['branch']) yield path_to_builder(req, self.builder_status) return if not revision_validate.match(self.req_args['revision']): log.msg("bad revision '%s'" % self.req_args['revision']) yield path_to_builder(req, self.builder_status) return properties = getAndCheckProperties(req) if properties is None: yield path_to_builder(req, self.builder_status) return if not self.req_args['branch']: self.req_args['branch'] = None if not self.req_args['revision']: self.req_args['revision'] = None d = master.db.sourcestamps.addSourceStamp( branch=self.req_args['branch'], revision=self.req_args['revision'], project=self.req_args['project'], repository=self.req_args['repository']) wfd = defer.waitForDeferred(d) yield wfd ssid = wfd.getResult() r = ("The web-page 'force build' button was pressed by '%s': %s\n" % (html.escape(self.req_args['name']), html.escape(self.req_args['reason']))) d = master.addBuildset(builderNames=[self.builder_status.getName()], ssid=ssid, reason=r, properties=properties.asDict()) wfd = defer.waitForDeferred(d) yield wfd tup = wfd.getResult() # check that (bsid, brids) were properly stored if not isinstance(tup, (int, dict)): log.err("(ignored) while trying to force build") # send the user back to the builder page yield path_to_builder(req, self.builder_status)
def error_handler(self, m): try: if m['isError'] == 1: self.log.err(escape(repr(m))) #reactor.stop() else: self.log.log(escape(repr(m)), 4) except: print m
def make_buildset(ssid): r = ( "The web-page 'force build' button was pressed by '%s': %s\n" % (html.escape(name), html.escape(reason))) return master.addBuildset( builderNames=[self.builder_status.getName()], ssid=ssid, reason=r, properties=None)
def call(self, f, *args, **kwargs): try: return f(*args, **kwargs) except: m = '; '.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) m = m.decode('utf8', 'replace') m = u'<font color=red><b>ERROR:</b></font> %s\n<br/>\n(f, *args, *kwargs) was <font color=grey>(%s)</font>' \ % (escape(m), escape(repr((f, args, kwargs)))) self.log.err(m) return 0
def check_text(self, source, text): #if source.room and (source.room.bot.nick == self.muc.get_nick(source.room.jid)): # return #ignore own messages/presences if not text: return #ignore empty messages/statuses self.log.log(u'checking %s (from %s)' % (escape(text), escape(source.jid)), 1) bad_word = self.censor.respond(text) if bad_word: self.log.log(u'found bad word <%s>, let\'s call bad_handlers!' % (escape(bad_word), ), 3) self.call_bad_handlers(source, text, bad_word) else: self.log.log(u'bad words not found (result: %s)' % (bad_word, ), 1)
def body(self, req): s = self.step_status b = s.getBuild() builder_name = b.getBuilder().getName() build_num = b.getNumber() data = "" data += ('<h1>BuildStep <a href="%s">%s</a>:' % (path_to_builder(req, b.getBuilder()), builder_name)) data += '<a href="%s">#%d</a>' % (path_to_build(req, b), build_num) data += ":%s</h1>\n" % s.getName() if s.isFinished(): data += ("<h2>Finished</h2>\n" "<p>%s</p>\n" % html.escape("%s" % s.getText())) else: data += ("<h2>Not Finished</h2>\n" "<p>ETA %s seconds</p>\n" % s.getETA()) exp = s.getExpectations() if exp: data += ("<h2>Expectations</h2>\n" "<ul>\n") for e in exp: data += "<li>%s: current=%s, target=%s</li>\n" % \ (html.escape(e[0]), e[1], e[2]) data += "</ul>\n" (start, end) = s.getTimes() data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % ctime(start) if end: data += "<tr><td>End</td><td>%s</td></tr>\n" % ctime(end) data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval( end - start) data += "</table>\n" logs = s.getLogs() if logs: data += ("<h2>Logs</h2>\n" "<ul>\n") for logfile in logs: if logfile.hasContents(): # FIXME: If the step name has a / in it, this is broken # either way. If we quote it but say '/'s are safe, # it chops up the step name. If we quote it and '/'s # are not safe, it escapes the / that separates the # step name from the log number. logname = logfile.getName() logurl = req.childLink("logs/%s" % urllib.quote(logname)) data += ('<li><a href="%s">%s</a></li>\n' % (logurl, html.escape(logname))) else: data += '<li>%s</li>\n' % html.escape(logname) data += "</ul>\n" return data
def force(self, req, auth_ok=False): name = req.args.get("username", ["<unknown>"])[0] reason = req.args.get("comments", ["<no reason specified>"])[0] branch = req.args.get("branch", [""])[0] revision = req.args.get("revision", [""])[0] repository = req.args.get("repository", [""])[0] project = req.args.get("project", [""])[0] r = "The web-page 'force build' button was pressed by '%s': %s\n" \ % (html.escape(name), html.escape(reason)) log.msg("web forcebuild of builder '%s', branch='%s', revision='%s'," " repository='%s', project='%s' by user '%s'" % ( self.builder_status.getName(), branch, revision, repository, project, name)) # check if this is allowed if not auth_ok: if not self.getAuthz(req).actionAllowed('forceBuild', req, self.builder_status): log.msg("..but not authorized") return Redirect(path_to_authfail(req)) # keep weird stuff out of the branch revision, and property strings. # TODO: centralize this somewhere. if not re.match(r'^[\w.+/~-]*$', branch): log.msg("bad branch '%s'" % branch) return Redirect(path_to_builder(req, self.builder_status)) if not re.match(r'^[ \w\.\-\/]*$', revision): log.msg("bad revision '%s'" % revision) return Redirect(path_to_builder(req, self.builder_status)) properties = getAndCheckProperties(req) if properties is None: return Redirect(path_to_builder(req, self.builder_status)) if not branch: branch = None if not revision: revision = None # TODO: if we can authenticate that a particular User pushed the # button, use their name instead of None, so they'll be informed of # the results. # TODO2: we can authenticate that a particular User pushed the button # now, so someone can write this support. but it requires a # buildbot.changes.changes.Change instance which is tedious at this # stage to compute s = SourceStamp(branch=branch, revision=revision, project=project, repository=repository) try: c = interfaces.IControl(self.getBuildmaster(req)) bc = c.getBuilder(self.builder_status.getName()) bc.submitBuildRequest(s, r, properties) except interfaces.NoSlaveError: # TODO: tell the web user that their request could not be # honored pass # send the user back to the builder page return Redirect(path_to_builder(req, self.builder_status))
def body(self, request): dotname = ".".join(self.name) logs = self.test_result.getLogs() lognames = logs.keys() lognames.sort() data = "<h1>%s</h1>\n" % html.escape(dotname) for name in lognames: data += "<h2>%s</h2>\n" % html.escape(name) data += "<pre>" + logs[name] + "</pre>\n\n" return data
def chatlogs_join_handler(item): if item.room and (item.room.get_option('chatlogs', config.CHATLOGS_ENABLE) == 'on'): _nick = escape(item.nick) m = u'<span class="mj">%s <%s> %s %s, %s (%s [%s])</span>' % ( _nick, item.fulljid, lang.get('chatlog_joined', lang.getLang( item.jid)), lang.get(item.affiliation, lang.getLang( item.jid)), lang.get(item.role, lang.getLang( item.jid)), escape(item.status), item.show) write_to_log(item.room.jid, m)
def call_msg_handlers(self, t, s, b, subject, stanza): if subject: j = JID(s) if not j.userhost() in self.g.keys(): self.log.log('ignored subject from %s, stanza was %s' % (escape(s), escape(stanza.toXml())), 3) else: self.log.log('got subject from %s, stanza was %s, let\'s call topichandlers' % (escape(s), escape(stanza.toXml())), 1) for i in self.topichandlers: self.call(i, s, subject) else: for i in self.msghandlers: if (t == 'groupchat') or not i[1]: self.call(i[0], s, b)
def call(self, f, *args, **kwargs): try: return f(*args, **kwargs) except: m = '; '.join( traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) m = m.decode('utf8', 'replace') m = u'<font color=red><b>ERROR:</b></font> %s\n<br/>\n(f, *args, *kwargs) was <font color=grey>(%s)</font>' \ % (escape(m), escape(repr((f, args, kwargs)))) self.log.err(m) return -1
def chatlogs_msg_handler(source, body): if not body: return j = jid.JID(source) room = j.userhost() nick = j.resource if not nick: nick = room if (room in bot.g.keys()) and (bot.g[room].get_option('chatlogs', config.CHATLOGS_ENABLE)=='on'): if body.startswith(u'/me ') and (len(body)>4): m = u'<font class="mne">* %s %s</font>' % (escape(nick), replace_links(escape(body[4:]).replace('\n', '<br/>'))) else: m = u'<font class="mn"><%s></font> %s' % (escape(nick), replace_links(escape(body).replace('\n', '<br/>'))) write_to_log(room, m)
def ToHtml(text): """Convert a string in a wiki-style format into HTML.""" indent = 0 in_item = False output = [] for line in text.splitlines(False): match = re.match(r'^( +)\- (.*)$', line) if match: if indent < len(match.group(1)): output.append('<ul>') indent = len(match.group(1)) elif indent > len(match.group(1)): while indent > len(match.group(1)): output.append('</ul>') indent -= 2 if in_item: # Close previous item output.append('</li>') output.append('<li>') in_item = True line = match.group(2) elif indent: if line.startswith((' ' * indent) + ' '): # List continuation line = line.strip() else: # List is done if in_item: output.append('</li>') in_item = False while indent > 0: output.append('</ul>') indent -= 2 if line.startswith('/'): if not '?' in line: line_full = line + '?as_text=1' else: line_full = line + '&as_text=1' output.append('<a href="' + html.escape(line_full) + '">' + html.escape(line) + '</a>') else: output.append(html.escape(line).replace(' ', ' ')) if not in_item: output.append('<br>') if in_item: output.append('</li>') while indent > 0: output.append('</ul>') indent -= 2 return '\n'.join(output)
def msg(self, t, s, b): if len(b) > msglimit: b = b[:msglimit]+'... (truncated)' b = b.strip() self.bot.log.log(escape(u'attempt to send message to %s (type "%s", body: %s)' % (s, t, b)), 3) if (s in self.bot.g.keys()) or (t=='chat'): if b == '': b = '[empty message]' self.bot.wrapper.msg(t, s, b) else: s = s.split('/') groupchat = s[0] nick = '/'.join(s[1:]) self.bot.log.log(escape(u'send message to %s (type "%s", body: %s)' % (groupchat, t, b)), 3) self.bot.wrapper.msg(t, groupchat, '%s: %s' % (nick, b))
def chatlogs_msg_handler(source, body, delayed): if not body: return else: body = body.strip() j = jid.JID(source) room = j.userhost() nick = j.resource if not nick: nick = room if (room in bot.g.keys()) and (bot.g[room].get_option('chatlogs', config.CHATLOGS_ENABLE)=='on'): if body.startswith(u'/me ') and (len(body)>4): m = u'<span class="mne">* %s %s</span>' % (escape(nick), replace_links(escape(body[4:]).replace('\n', '<br/>'))) else: m = u'<span class="mn"><%s></span> %s' % (escape(nick), replace_links(escape(body).replace('\n', '<br/>'))) write_to_log(room, m)
def write_to_log_(groupchat, text, with_timestamp=True, with_br=True): global next global prev p1 = '%s/%s' % (config.CHATLOGS_DIR, groupchat.encode('utf8', 'replace')) p2 = '%s/%s' % (p1, time.strftime('%Y')) p3 = '%s/%s' % (p2, time.strftime('%m')) p4 = '%s/%s.html' % (p3, time.strftime('%d')) if (groupchat in LOG_FILES) and (LOG_FILES[groupchat] <> p4): close_log(LOG_FILES[groupchat]) LOG_FILES[groupchat] = p4 topic = TOPICS.get(groupchat) if topic: chatlogs_topic_handler(groupchat, topic, immediately=True) LOG_FILES[groupchat] = p4 if not os.access(p4, os.F_OK): check_dir(p1) check_dir(p2) check_dir(p3) fp = file(p4, 'w') user, server = groupchat.split(u'@') header = log_header.replace('$user', user).replace('$server', server).replace( '$year', time.strftime('%Y')) header = header.replace('$month', time.strftime('%m')).replace( '$day', time.strftime('%d')) header = header.replace('$lang', lang.getLang(groupchat)) prev = time.strftime('../../%Y/%m/%d.html', time.localtime(time.time() - 86400)) next = time.strftime('../../%Y/%m/%d.html', time.localtime(time.time() + 86400)) header = header.replace('$next', next).replace('$prev', prev) list = groupchat for item in bot.g[groupchat].items.keys(): _i = bot.g[groupchat].items[item] list = u'%s <%s> %s, %s (%s [%s])/n' % ( escape(_i.nick), _i.fulljid, lang.get(_i.affiliation, lang.getLang(groupchat)), lang.get(_i.role, lang.getLang(groupchat)), escape( _i.status), _i.show) header = header.replace('$list', list) fp.write(header.encode('utf8', 'replace')) fp.close() if with_timestamp: tm = time.strftime( u'<a name="%H:%M:%S" href="#%H:%M:%S" class="ts">[%H:%M:%S]</a>') else: tm = u'' text = u'%s %s' % (tm, text) if with_br: text = text + u'<br/>' fp = file(p4, 'a') fp.write(text.encode('utf8', 'replace')) fp.close()
def ToHtml(text): """Convert a string in a wiki-style format into HTML.""" indent = 0 in_item = False output = [] for line in text.splitlines(False): match = re.match(r"^( +)\- (.*)$", line) if match: if indent < len(match.group(1)): output.append("<ul>") indent = len(match.group(1)) elif indent > len(match.group(1)): while indent > len(match.group(1)): output.append("</ul>") indent -= 2 if in_item: # Close previous item output.append("</li>") output.append("<li>") in_item = True line = match.group(2) elif indent: if line.startswith((" " * indent) + " "): # List continuation line = line.strip() else: # List is done if in_item: output.append("</li>") in_item = False while indent > 0: output.append("</ul>") indent -= 2 if line.startswith("/"): if not "?" in line: line_full = line + "?as_text=1" else: line_full = line + "&as_text=1" output.append('<a href="' + html.escape(line_full) + '">' + html.escape(line) + "</a>") else: output.append(html.escape(line).replace(" ", " ")) if not in_item: output.append("<br>") if in_item: output.append("</li>") while indent > 0: output.append("</ul>") indent -= 2 return "\n".join(output)
def msg(self, t, s, b): b = self.bot.clear_text(b) # clear_text(unicode) is from plugins/shared/utils.py if len(b) > msglimit: b = b[:msglimit] + '... (truncated)' b = b.strip() self.bot.log.log(escape(u'attempt to send message to %s (type "%s", body: %s)' % (s, t, b)), 3) if (s in self.bot.g.keys()) or (t <> 'groupchat'): self.bot.wrapper.msg(t, s, b) else: s = s.split('/') groupchat = s[0] nick = '/'.join(s[1:]) self.bot.log.log(escape(u'send message to %s (type "%s", body: %s)' % (groupchat, t, b)), 3) self.bot.wrapper.msg(t, groupchat, '%s: %s' % (nick, b))
def check_text(self, source, text): #if source.room and (source.room.bot.nick == self.muc.get_nick(source.room.jid)): # return #ignore own messages/presences if not text: return #ignore empty messages/statuses self.log.log( u'checking %s (from %s)' % (escape(text), escape(source.jid)), 1) bad_word = self.censor.respond(text) if bad_word: self.log.log( u'found bad word <%s>, let\'s call bad_handlers!' % (escape(bad_word), ), 3) self.call_bad_handlers(source, text, bad_word) else: self.log.log(u'bad words not found (result: %s)' % (bad_word, ), 1)
def get_HTML_box(self, url): """Return the contents of a TD cell for the waterfall display. @param url: the URL that points to an HTML page that will render using our asHTML method. The Change is free to use this or ignore it as it pleases. @return: the HTML that will be put inside the table cell. Typically this is just a single href named after the author of the change and pointing at the passed-in 'url'. """ who = self.getShortAuthor() return '<a href="%s" title="%s">%s</a>' % ( url, html.escape(self.comments), html.escape(who))
def get_HTML_box(self, url): """Return the contents of a TD cell for the waterfall display. @param url: the URL that points to an HTML page that will render using our asHTML method. The Change is free to use this or ignore it as it pleases. @return: the HTML that will be put inside the table cell. Typically this is just a single href named after the author of the change and pointing at the passed-in 'url'. """ who = self.getShortAuthor() return '<a href="%s" title="%s">%s</a>' % (url, html.escape(self.comments), html.escape(who))
def body(self, req): s = self.step_status step_name = s.getName().split(' ')[-1] data = '' if not s.isFinished(): data += ('<h2>Not Finished</h2>\n' '<p>ETA %s seconds</p>\n' % s.getETA()) else: r = s.getResults() if r[0] in (SUCCESS, WARNINGS): data += '<h2 class="success">Finished %s successfully</h2\n' % step_name elif r[0] == FAILURE: data += '<h2 class="failure">Finished %s unsuccessfully</h2\n' % step_name elif r[0] == EXCEPTION: data += '<h2 class="exception">Finished %s on an exception</h2\n' % step_name if step_name == 'check' and len(s.getText()) > 1 and \ s.getResults()[0] in (SUCCESS, WARNINGS): data += '<ul>' for x in s.getText()[1:]: data += '<li>%s</li>' % x data += '</ul>' else: if len(s.getText()) > 1: data += '<p>%s</p>\n' % ' '.join(s.getText()[1:]) logs = s.getLogs() if logs: data += ("<h2>Logs</h2>\n" "<ul>\n") for logfile in logs: if logfile.hasContents(): # FIXME: If the step name has a / in it, this is broken # either way. If we quote it but say '/'s are safe, # it chops up the step name. If we quote it and '/'s # are not safe, it escapes the / that separates the # step name from the log number. logname = logfile.getName() logurl = req.childLink("logs/%s" % urllib.quote(logname)) data += ('<li><a href="%s">%s</a></li>\n' % (logurl, html.escape(logname))) else: logname = logfile.getName() data += '<li>%s</li>\n' % html.escape(logname) data += "</ul>\n" return data
def _call(self, f, tc, *args, **kwargs): try: self.log.log(escape('=== started thread #%s' % (tc, )), 1) try: f(*args, **kwargs) except: m = '; '.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) m = m.decode('utf8', 'replace') m = u'<font color=red><b>UNCATCHED ERROR:</b></font> %s\n<br/>\n(f, *args, *kwargs, thread) was <font color=grey>(%s)</font>' \ % (escape(m), escape(repr((f, args, kwargs, tc)))) self.log.err(m) self.log.log(escape('=== finished thread #%s' % (tc, )), 1) except: m = ''.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) print 'STOP: ', m self.log.err(escape(m)) self.log.err('=== failed thread #%s' % (self.tc, ))
def asHTML(self): links = [] for file in self.files: link = filter(lambda s: s.find(file) != -1, self.links) if len(link) == 1: # could get confused links.append('<a href="%s"><b>%s</b></a>' % (link[0], file)) else: links.append('<b>%s</b>' % file) revlink = "" if self.revision: if getattr(self, 'revlink', ""): revision = 'Revision: <a href="%s"><b>%s</b></a>\n' % ( self.revlink, self.revision) else: revision = "Revision: <b>%s</b><br />\n" % self.revision branch = "" if self.branch: branch = "Branch: <b>%s</b><br />\n" % self.branch kwargs = { 'who' : html.escape(self.who), 'at' : self.getTime(), 'files' : html.UL(links) + '\n', 'revision': revision, 'branch' : branch, 'comments': html.PRE(self.comments) } return html_tmpl % kwargs
def force(self, req, builderNames): master = self.getBuildmaster(req) owner = self.getAuthz(req).getUsernameFull(req) schedulername = req.args.get("forcescheduler", ["<unknown>"])[0] if schedulername == "<unknown>": defer.returnValue((path_to_builder(req, self.builder_status), "forcescheduler arg not found")) return args = {} # decode all of the args encoding = getRequestCharset(req) for name, argl in req.args.iteritems(): if name == "checkbox": # damn html's ungeneric checkbox implementation... for cb in argl: args[cb.decode(encoding)] = True else: args[name] = [arg.decode(encoding) for arg in argl] for sch in master.allSchedulers(): if schedulername == sch.name: try: yield sch.force(owner, builderNames, **args) msg = "" except ValidationError, e: msg = html.escape(e.message.encode('ascii', 'ignore')) break
def buildForceContextForField(req, default_props, sch, field, master, buildername): pname = "%s.%s" % (sch.name, field.fullName) default = field.default if "list" in field.type: choices = field.getChoices(master, sch, buildername) if choices: default = choices[0] default_props[pname + ".choices"] = choices default = req.args.get(pname, [default])[0] if "bool" in field.type: default = "checked" if default else "" elif isinstance(default, unicode): # filter out unicode chars, and html stuff default = html.escape(default.encode('utf-8', 'ignore')) default_props[pname] = default if "nested" in field.type: for subfield in field.fields: buildForceContextForField(req, default_props, sch, subfield, master, buildername)
def _notify_status(self, response=None): if not self._running: return time_passed = time.time() - self._notify_update_last_time if time_passed < self._notify_update_interval: reactor.callLater(self._notify_update_interval - time_passed, self._notify_status) return self._notify_update_last_time = time.time() mins, secs = divmod(time.time() - self.start_time, 60) hours, mins = divmod(mins, 60) ret = {'id': self.id, 'log_id': self.log_id, 'name': self.workflow.name, 'master': socket.gethostname(), 'time': "%02d:%02d:%02d" % (hours, mins, secs), 'user': getpass.getuser(), 'graph': self.workflow_graph, 'log_addr': self.mongo_log_addr, 'slaves': self._agent.nodes if self.is_master else [], 'plots': "http://%s:%d" % (socket.gethostname(), self.webagg_port), 'custom_plots': "<br/>".join(self.plots_endpoints), 'description': "<br />".join(escape(self.workflow.__doc__ or "").split("\n"))} url = "http://%s:%d/update" % (root.common.web.host, root.common.web.port) headers = Headers({b'User-Agent': [b'twisted']}) body = FileBodyProducer(BytesIO(json.dumps(ret).encode('charmap'))) self.debug("Uploading status update to %s", url) d = self._web_status_agent.request( b'POST', url.encode('ascii'), headers=headers, bodyProducer=body) d.addCallback(self._notify_status) d.addErrback(self._on_notify_status_error)
def childFactory(self, ctx, name): ophandle = name if ophandle not in self.handles: raise WebError("unknown/expired handle '%s'" % escape(ophandle), NOT_FOUND) (monitor, renderer, when_added) = self.handles[ophandle] request = IRequest(ctx) t = get_arg(ctx, "t", "status") if t == "cancel" and request.method == "POST": monitor.cancel() # return the status anyways, but release the handle self._release_ophandle(ophandle) else: retain_for = get_arg(ctx, "retain-for", None) if retain_for is not None: self._set_timer(ophandle, int(retain_for)) if monitor.is_finished(): if boolean_of_arg(get_arg(ctx, "release-after-complete", "false")): self._release_ophandle(ophandle) if retain_for is None: # this GET is collecting the ophandle, so change its timer self._set_timer(ophandle, self.COLLECTED_HANDLE_LIFETIME) status = monitor.get_status() if isinstance(status, Failure): return defer.fail(status) return renderer
def body(self, req): status = self.getStatus(req) control = self.getControl(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] data = "" data += "<h2>Latest builds: %s</h2>\n" % ", ".join(branches) data += "<table>\n" building = False online = 0 base_builders_url = self.path_to_root(req) + "builders/" for bn in builders: base_builder_url = base_builders_url + urllib.quote(bn, safe='') builder = status.getBuilder(bn) data += "<tr>\n" data += '<td class="box"><a href="%s">%s</a></td>\n' \ % (base_builder_url, html.escape(bn)) builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] url = (base_builder_url + "/builds/%d" % b.getNumber()) try: label = b.getProperty("got_revision") except KeyError: label = None if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() text = ['<a href="%s">%s</a>' % (url, label)] text.extend(b.getText()) box = Box(text, b.getColor(), class_="LastBuild box %s" % build_get_class(b)) data += box.td(align="center") else: data += '<td class="LastBuild box" >no build</td>\n' current_box = ICurrentBox(builder).getBox(status) data += current_box.td(align="center") builder_status = builder.getState()[0] if builder_status == "building": building = True online += 1 elif builder_status != "offline": online += 1 data += "</table>\n" if control is not None: if building: stopURL = "builders/_all/stop" data += make_stop_form(stopURL, True, "Builds") if online: forceURL = "builders/_all/force" data += make_force_build_form(forceURL, True) return data
def performAction(self, req): authz = self.getAuthz(req) res = yield authz.actionAllowed(self.action, req, self.build_status) if not res: defer.returnValue(path_to_authzfail(req)) return b = self.build_status log.msg("web stopEntireBuildChain of build %s:%s" % \ (b.getBuilder().getName(), b.getNumber())) name = authz.getUsernameFull(req) reason = ( "The web-page 'Stop Entire Build Chain' button was pressed by '%s'\n" % html.escape(name)) master = interfaces.IControl(self.getBuildmaster(req)) buildername = self.build_status.getBuilder().getName() number = self.build_status.getNumber() builderc = master.getBuilder(buildername) if builderc: build = builderc.getBuild(number) if build: yield self.stopEntireBuildChain(master, build, buildername, reason) build.stopBuild(reason) defer.returnValue(path_to_build(req, self.build_status))
def buildForceContext(cxt, req, master, buildername=None): force_schedulers = {} default_props = {} for sch in master.allSchedulers(): if isinstance(sch, ForceScheduler) and (buildername is None or (buildername in sch.builderNames)): force_schedulers[sch.name] = sch for p in sch.all_fields: pname = "%s.%s" % (sch.name, p.name) default = p.default if isinstance(p, InheritBuildParameter): # yes, I know, its bad to overwrite the parameter attribute, # but I dont have any other simple way of doing this atm. p.choices = p.compatible_builds(master.status, buildername) if p.choices: default = p.choices[0] default = req.args.get(pname, [default])[0] if p.type == "bool": default_props[pname] = default and "checked" or "" else: # filter out unicode chars, and html stuff if type(default) == unicode: default = html.escape(default.encode( 'ascii', 'ignore')) default_props[pname] = default cxt['force_schedulers'] = force_schedulers cxt['default_props'] = default_props
def force(self, req, builderNames): master = self.getBuildmaster(req) owner = self.getAuthz(req).getUsernameFull(req) schedulername = req.args.get("forcescheduler", ["<unknown>"])[0] if schedulername == "<unknown>": defer.returnValue((path_to_builder(req, self.builder_status), "forcescheduler arg not found")) return args = {} # decode all of the args encoding = getRequestCharset(req) for name, argl in req.args.iteritems(): if name == "checkbox": # damn html's ungeneric checkbox implementation... for cb in argl: args[cb.decode(encoding)] = True else: args[name] = [ arg.decode(encoding) for arg in argl ] for sch in master.allSchedulers(): if schedulername == sch.name: try: yield sch.force(owner, builderNames, **args) msg = "" except ValidationError, e: msg = html.escape(e.message.encode('ascii','ignore')) break
def _call(self, f, tc, *args, **kwargs): try: self.log.log(escape('=== started thread #%s' % (tc, )), 1) try: f(*args, **kwargs) except: m = '; '.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) m = m.decode('utf8', 'replace') m = u'<font color=red><b>UNCATCHED ERROR:</b></font> %s\n<br/>\n(f, *args, *kwargs, thread) was <font color=grey>(%s)</font>' \ % (escape(m), escape(repr((f, args, kwargs, tc)))) self.log.err(m) self.log.log(escape('=== finished thread #%s' % (tc, )), 1) except: m = ''.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) print 'STOP: ', m self.log.err(escape(m)) self.log.err('=^= failed thread #%s' % (self.tc, ))