Ejemplo n.º 1
0
    def content(self, req, cxt):
        status = self.getStatus(req)

        cxt['path_to_codebases'] = path_to_codebases(req, self.project.name)
        cxt['selectedproject'] = self.project.name

        codebases = {}
        getCodebasesArg(req, codebases)
        project_json = SingleProjectJsonResource(status, self.project)
        project_dict = yield project_json.asDict(req)
        url = status.getBuildbotURL() + path_to_json_builders(req, self.project.name)
        filters = {
            "project": self.project.name,
            "sources": codebases
        }
        cxt['instant_json']['builders'] = {"url": url,
                                           "data": json.dumps(project_dict, separators=(',', ':')),
                                           "waitForPush": status.master.config.autobahn_push,
                                           "pushFilters": {
                                               "buildStarted": filters,
                                               "buildFinished": filters,
                                               "requestSubmitted": filters,
                                               "requestCancelled": filters,
                                               "stepStarted": filters,
                                               "stepFinished": filters,
                                           }}


        template = req.site.buildbot_service.templates.get_template("builders.html")
        defer.returnValue(template.render(**cxt))
Ejemplo n.º 2
0
    def asDict(self, request):
        result = {'builders': []}

        #Get codebases
        codebases = {}
        getCodebasesArg(request=request, codebases=codebases)
        result['latestRevisions'] = yield self.getLatestRevision(codebases)

        encoding = getRequestCharset(request)
        branches = [
            branch.decode(encoding)
            for branch in request.args.get("branch", []) if branch
        ]

        result['comparisonURL'] = path_to_comparison(request,
                                                     self.project_status.name,
                                                     codebases)

        defers = []
        for name in self.children:
            child = self.getChildWithDefault(name, request)
            d = child.asDict(request, codebases, branches, True)
            defers.append(d)

        for d in defers:
            r = yield d
            result['builders'].append(r)

        defer.returnValue(result)
Ejemplo n.º 3
0
    def asDict(self, request):
        #Get codebases
        codebases = {}
        getCodebasesArg(request=request, codebases=codebases)

        # Get pending request filtered + sorted
        pendingBuilds = yield self.builder.getPendingBuildRequestStatusesDicts(
            codebases=codebases)
        defer.returnValue(pendingBuilds)
Ejemplo n.º 4
0
    def asDict(self, request, params=None):
        include_steps = True
        include_props = True

        # We pass params only if we are doing this directly and not from a user
        args = request.args
        if params is not None:
            args = params

        if "steps" in args:
            include_steps = True if "1" in args["steps"] else False
        if "props" in args:
            include_props = True if "1" in args["props"] else False

        results = getResultsArg(request)

        if self.builder_status is not None:
            codebases = {}
            getCodebasesArg(request=request, codebases=codebases)
            encoding = getRequestCharset(request)
            branches = [
                b.decode(encoding) for b in request.args.get("branch", []) if b
            ]

            builds = yield self.builder_status.generateFinishedBuildsAsync(
                branches=map_branches(branches),
                codebases=codebases,
                results=results,
                num_builds=self.number)

            defer.returnValue([
                b.asDict(request,
                         include_artifacts=True,
                         include_failure_url=True,
                         include_steps=include_steps,
                         include_properties=include_props) for b in builds
            ])
            return

        if self.slave_status is not None:
            slavename = self.slave_status.getName()
            builds = yield self.status.generateFinishedBuildsAsync(
                num_builds=self.number, results=results, slavename=slavename)

            defer.returnValue([
                rb.asDict(request=request, include_steps=False)
                for rb in builds
            ])
            return
Ejemplo n.º 5
0
    def asDict(self, request=None):
        from buildbot.status.web.base import getCodebasesArg
        result = {}
        # Constant
        result['name'] = self.getName()

        # Transient
        result['text'] = self.getText()
        result['results'] = self.getResults()
        result['isStarted'] = self.isStarted()
        result['isFinished'] = self.isFinished()
        result['statistics'] = self.statistics
        result['times'] = self.getTimes()
        result['expectations'] = self.getExpectations()
        result['eta'] = self.getETA()
        result['step_number'] = self.step_number
        result['hidden'] = self.hidden

        args = getCodebasesArg(request)
        result['logs'] = [[
            l.getName(),
            self.build.builder.status.getURLForThing(l) + args
        ] for l in self.getLogs()]

        result["urls"] = self.getURLs()

        if request is not None:
            from buildbot.status.web.base import path_to_step
            result['url'] = path_to_step(request, self)

        return result
Ejemplo n.º 6
0
    def asDict(self,
               request=None,
               include_artifacts=False,
               include_failure_url=False,
               include_steps=True,
               include_properties=True):
        from buildbot.status.web.base import getCodebasesArg
        result = self.asBaseDict(request,
                                 include_artifacts=include_artifacts,
                                 include_failure_url=include_failure_url)

        # TODO(maruel): Add.
        #result['test_results'] = self.getTestResults()
        args = getCodebasesArg(request)
        result['logs'] = [[
            l.getName(),
            self.master.status.getURLForThing(l) + args
        ] for l in self.getLogs()]

        result['isWaiting'] = False

        if include_steps:
            result['steps'] = [bss.asDict(request) for bss in self.steps]

        result = self.currentStepDict(result)

        # Transient
        if include_properties:
            result['properties'] = self.getProperties().asList()

        return result
Ejemplo n.º 7
0
    def getURLForBuild(self, builder_name, build_number, friendly_name=None, sourcestamps=None):
        if friendly_name is None:
            friendly_name = builder_name

        url = {}
        prefix = self.getBuildbotURL()
        url['path'] = prefix + self.getBuildersPath(builder_name, build_number) \
                      + getCodebasesArg(sourcestamps=sourcestamps)
        url['text'] = self.getURLText(friendly_name, build_number)
        return url
Ejemplo n.º 8
0
    def asDict(self, request):
        results = {}
        #Get codebases
        codebases = {}
        getCodebasesArg(request=request, codebases=codebases)

        # If max > buildCacheSize, it'll trash the cache...
        cache_size = self.builder_status.master.config.caches['Builds']
        max = int(RequestArg(request, 'max', cache_size))
        for i in range(0, max):
            child = self.getChildWithDefault(-i, request)
            if not isinstance(child, BuildJsonResource):
                continue

            if len(codebases
                   ) == 0 or child.build_status.builder.foundCodebasesInBuild(
                       child.build_status, codebases):
                results[child.build_status.getNumber()] = child.asDict(request)

        return results
Ejemplo n.º 9
0
        def getMasterURL(bmdict, builder_name, build_number):
            url = {}

            buildbotURL = bmdict['buildbotURL'] if bmdict and 'buildbotURL' in bmdict else ''
            if not buildbotURL:
                log.msg("Did not find buildbotURL for buildrequest self.master.db.mastersconfig.getMasterURL(%d)"
                        % brid)

            url['path'] = buildbotURL + self.getBuildersPath(builder_name, build_number) \
                          + getCodebasesArg(sourcestamps=sourcestamps)
            url['text'] = self.getURLText(name, build_number)
            return url
Ejemplo n.º 10
0
    def asDict(self,
               request,
               codebases=None,
               branches=None,
               base_build_dict=False,
               params=None):

        # We pass params only if we are doing this directly and not from a user
        args = request.args
        if params is not None:
            args = params

        include_build_steps = self.getRequestArgumentValue(
            args=args, parameter="build_steps", defaultValue=True)
        include_build_props = self.getRequestArgumentValue(
            args=args, parameter="build_props", defaultValue=True)
        include_pending_builds = self.getRequestArgumentValue(
            args=args, parameter="pending_builds", defaultValue=False)

        if codebases is None or branches is None:
            #Get codebases
            codebases = {}
            getCodebasesArg(request=request, codebases=codebases)
            encoding = getRequestCharset(request)
            branches = [
                branch.decode(encoding)
                for branch in request.args.get("branch", []) if branch
            ]

        builder_dict = yield self.builder_dict(
            self.builder, codebases, request, branches, base_build_dict,
            include_build_steps, include_build_props, include_pending_builds)

        if self.latest_rev:
            builder_dict['latestRevisions'] = yield self.getLatestRevision(
                codebases)

        defer.returnValue(builder_dict)
Ejemplo n.º 11
0
    def asDict(self, request, params=None):
        include_steps = True
        include_props = True

        # We pass params only if we are doing this directly and not from a user
        args = request.args
        if params is not None:
            args = params

        if "steps" in args:
            include_steps = True if "1" in args["steps"] else False
        if "props" in args:
            include_props = True if "1" in args["props"] else False

        #Get codebases
        codebases = {}
        getCodebasesArg(request=request, codebases=codebases)

        builds = self.builder_status.getCachedBuilds(codebases=codebases)

        return [
            b.asDict(include_steps=include_steps,
                     include_properties=include_props) for b in builds
        ]
Ejemplo n.º 12
0
    def render_GET(self, req):
        self._setContentType(req)
        self.req = req

        if self.original.isFinished():
            req.setHeader("Cache-Control", "max-age=604800")
        else:
            req.setHeader("Cache-Control", "no-cache")

        # If plaintext is requested just return the content of the logfile
        if self.asDownload:
            with_headers = "_with_headers" if self.withHeaders else ""
            base_name = self.original.step.getName(
            ) + "_" + self.original.getName() + with_headers
            base_name = re.sub(r'[\W]', '_', base_name) + ".log"
            req.setHeader("Content-Disposition",
                          "attachment; filename =\"" + base_name + "\"")
            return self.original.getTextWithHeaders(
            ) if self.withHeaders else self.original.getText()

        # Or open in new window
        if self.newWindow:
            req.setHeader("Content-Disposition", "inline")
            return self.original.getTextWithHeaders(
            ) if self.withHeaders else self.original.getText()

        # Else render the logs template

        self.template = req.site.buildbot_service.templates.get_template(
            "logs.html")
        self.chunk_template = req.site.buildbot_service.templates.get_template(
            "log_chunk.html")
        builder = self.original.step.build.builder
        build_id = self.original.step.build.number
        url_dict = self.original.master.status.getURLForBuild(
            builder.getName(), build_id)

        if self.iFrame:
            data = self.chunk_template.module.page_header(version)
            data = data.encode('utf-8')
            req.write(data)
            self.original.subscribeConsumer(ChunkConsumer(req, self))
            return server.NOT_DONE_YET

        cxt = self.getContext(req)
        build = self.original.step.build
        builder_status = build.builder
        project = builder_status.getProject()
        cxt["pageTitle"] = "Log File Contents"
        cxt["new_window_url"] = req.path + "/plaintext"
        cxt["new_window_with_headers_url"] = req.path + "/plaintext_with_headers"
        cxt["download_url"] = req.path + "/download"
        cxt["download_with_headers_url"] = req.path + "/download_with_headers"
        cxt["iframe_url"] = req.path + "/iframe"
        cxt["builder_name"] = builder.getFriendlyName()
        cxt['path_to_builder'] = path_to_builder(req, builder_status)
        cxt['path_to_builders'] = path_to_builders(req, project)
        cxt["builder_url"] = url_dict['path'] + getCodebasesArg(request=req)
        cxt['path_to_codebases'] = path_to_codebases(req, project)
        cxt['path_to_build'] = path_to_build(req, build)
        cxt['build_number'] = build.getNumber()
        cxt['selectedproject'] = project

        data = self.template.render(**cxt)
        data = data.encode('utf-8')
        req.write(data)

        return ""
Ejemplo n.º 13
0
    def content(self, req, cxt):
        b = self.builder_status
        master = self.getBuildmaster(req)

        # 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

        project = cxt['selectedproject'] = b.getProject()
        cxt['name'] = b.getName()
        cxt['friendly_name'] = b.getFriendlyName()

        cxt['description'] = b.getDescription()
        req.setHeader('Cache-Control', 'no-cache')

        codebases = {}
        getCodebasesArg(request=req, codebases=codebases)

        num_builds = int(req.args.get('numbuilds', [self.numbuilds])[0])

        cxt['builder_url'] = path_to_builder(req, b, codebases=True)
        cxt['path_to_codebases'] = path_to_codebases(req, project)
        cxt['path_to_builders'] = path_to_builders(req, project)
        cxt['builder_name'] = b.getName()

        cxt['rt_update'] = req.args

        filters = {
            "project": self.builder_status.project,
            "builderName": b.getName(),
            "sources": codebases
        }

        project_params = {
            "build_steps": ["0"],
            "build_props": ["0"]
        }

        project_json = SingleProjectBuilderJsonResource(self.status, self.builder_status, latest_rev=True)
        project_dict = yield project_json.asDict(req, params=project_params)
        url = self.status.getBuildbotURL() + path_to_json_project_builder(req, project, self.builder_status.name)
        filtered_tags = filter_tags_by_codebases(project_dict['tags'],
                                                 codebases,
                                                 master.config.tag_as_branch_regex,
                                                 master.config.regex_branches)
        cxt['instant_json']['project'] = {"url": url,
                                          "data": json.dumps(project_dict, separators=(',', ':')),
                                          "tags": filtered_tags,
                                          "waitForPush": self.status.master.config.autobahn_push,
                                          "pushFilters": {
                                              "buildStarted": filters,
                                              "buildFinished": filters,
                                              "stepStarted": filters,
                                              "stepFinished": filters,
                                          }}

        pending_json = SinglePendingBuildsJsonResource(self.status, self.builder_status)
        pending_dict = yield pending_json.asDict(req)
        pending_url = self.status.getBuildbotURL() + path_to_json_pending(req, self.builder_status.name)
        cxt['instant_json']['pending_builds'] = {"url": pending_url,
                                                 "data": json.dumps(pending_dict, separators=(',', ':')),
                                                 "waitForPush": self.status.master.config.autobahn_push,
                                                 "pushFilters": {
                                                     "buildStarted": filters,
                                                     "requestSubmitted": filters,
                                                     "requestCancelled": filters,
                                                 }}

        builds_params = {
            "steps": ["0"],
        }

        builds_json = PastBuildsJsonResource(self.status, num_builds,  builder_status=self.builder_status)
        builds_dict = yield builds_json.asDict(req, params=builds_params)
        builds_url = self.status.getBuildbotURL() + path_to_json_past_builds(req, self.builder_status.name,
                                                                             num_builds, filter_data=True)
        cxt['instant_json']['builds'] = {"url": builds_url,
                                         "data": json.dumps(builds_dict, separators=(',', ':')),
                                         "waitForPush": self.status.master.config.autobahn_push,
                                         "pushFilters": {
                                             "buildFinished": filters
                                         }}

        slave_params = {
            "build_steps": ["0"],
            "build_props": ["0"],
            "builders": ["0"]
        }
        slaves = b.getSlaves()
        slaves_array = [SlaveJsonResource(self.status, ss).asDict(req, params=slave_params)
                        for ss in slaves]
        slaves_dict = FilterOut(slaves_array)
        url = self.status.getBuildbotURL() + path_to_json_builder_slaves(self.builder_status.getName())
        cxt['instant_json']["slaves"] = self.getSlavesJsonResource(filters, url, slaves_dict)

        startslaves = BuilderStartSlavesJsonResources(self.status, self.builder_status)
        startslaves_dict = yield startslaves.asDict(req)
        url = self.status.getBuildbotURL() + \
              path_to_json_builder_startslaves(self.builder_status.getName()) + "?filter=1"
        cxt['instant_json']["start_slaves"] = self.getSlavesJsonResource(filters, url, startslaves_dict)

        cxt['numbuilds'] = int(req.args.get('numbuilds', [self.numbuilds])[0])

        buildForceContext(cxt, req, self.getBuildmaster(req), b.getName())
        template = req.site.buildbot_service.templates.get_template("builder.html")
        defer.returnValue(template.render(**cxt))
Ejemplo n.º 14
0
    def asBaseDict(self,
                   request=None,
                   include_current_step=False,
                   include_artifacts=False,
                   include_failure_url=False):
        from buildbot.status.web.base import getCodebasesArg

        result = {}
        sourcestamps = self.getSourceStamps()
        status = self.master.status
        args = getCodebasesArg(request, sourcestamps=sourcestamps)

        # Constant
        result['builderName'] = self.builder.name
        result['builderFriendlyName'] = self.builder.getFriendlyName()
        result['number'] = self.getNumber()
        result['reason'] = self.getReason()
        result['submittedTime'] = self.submitted
        result['owners'] = self.owners
        result['brids'] = self.brids
        result['buildChainID'] = self.buildChainID
        result['blame'] = self.getResponsibleUsers()
        result['url'] = status.getURLForThing(self)
        result['url']['path'] += args
        result['builder_url'] = status.getURLForThing(self.builder) + args
        result['builder_tags'] = self.builder.tags
        result['build_tags'] = self.getBuildTags()

        if self.resume:
            result['resume'] = self.resume

        if self.resumeSlavepool:
            result['resumeSlavepool'] = self.resumeSlavepool

        if include_failure_url:
            result['failure_url'] = self.get_failure_of_interest()
            if result['failure_url'] is not None:
                result['failure_url'] += args

        if include_artifacts:
            result['artifacts'] = self.get_artifacts()

        # Transient
        result['times'] = self.getTimes()
        result['text'] = self.getText()
        result['results'] = self.getResults()
        result['slave'] = self.getSlavename()
        slave = status.getSlave(self.getSlavename())
        if slave is not None:
            result['slave_friendly_name'] = slave.getFriendlyName()
            result['slave_url'] = status.getURLForThing(slave)
        result['eta'] = self.getETA()

        #Lazy importing here to avoid python import errors
        from buildbot.status.web.base import css_classes
        result['results_text'] = css_classes.get(result['results'], "")

        if include_current_step:
            result = self.currentStepDict(result)

        # Constant
        project = None
        for p, obj in status.getProjects().iteritems():
            if p == self.builder.project:
                project = obj
                break

        def getCodebaseObj(repo):
            for c in project.codebases:
                if c.values()[0]['repository'] == repo:
                    return c.values()[0]

        stamp_array = []
        for ss in sourcestamps:
            d = ss.asDict(status)
            c = getCodebaseObj(d['repository'])
            if c is not None and c.has_key("display_repository"):
                d['display_repository'] = c['display_repository']
            else:
                d['display_repository'] = d['repository']

            stamp_array.append(d)

        result['sourceStamps'] = stamp_array

        return result
Ejemplo n.º 15
0
    def __prepare_context(self, request, cxt=None):
        """ This method prepares context for templates

        :param request: http request object
        :param cxt: default context variable
        :type cxt: dictionary
        :return: dictionary with variables for template
        """
        if not cxt:
            context = {}
        else:
            context = cxt.copy()

        builder = self.build_status.getBuilder()

        context['builder_name'] = builder.name
        context['builder_friendly_name'] = builder.getFriendlyName()
        context['selected_project'] = builder.getProject()

        context['build_number'] = self.build_status.getNumber()
        context['custom_build_urls'] = self.build_status.getCustomUrls()
        context['source_stamps'] = self.build_status.getSourceStamps()
        context['got_revisions'] = self.build_status.getAllGotRevisions()
        context['slave_friendly_name'] = self.build_status.getSlavename()
        context['build_reason'] = self.build_status.getReason()
        context['build_is_resuming'] = self.build_status.isResuming()
        context['build_is_finished'] = self.build_status.isFinished()

        context['path_to_builder'] = path_to_builder(
            request, self.build_status.getBuilder())
        context['path_to_builders'] = path_to_builders(request,
                                                       builder.getProject())
        context['path_to_codebases'] = path_to_codebases(
            request, builder.getProject())
        context['build_url'] = path_to_build(request, self.build_status, False)
        context['slave_debug_url'] = self.getBuildmaster(
            request).config.slave_debug_url
        context['codebases_arg'] = getCodebasesArg(request=request)
        context['parent_build_url'] = None
        context['top_build_url'] = None

        start, end = self.build_status.getTimes()
        context['start'] = time.ctime(start)
        context['end'] = time.ctime(end) if end else None
        context['elapsed'] = None
        if not end:
            end = util.now()
        if start:
            context['elapsed'] = util.formatInterval(end - start)

        context['authz'] = self.getAuthz(request)
        context['has_changes'] = False
        context['tests_link'] = None
        context['resume'] = None
        context['top_build_name'] = None
        context['parent_build_name'] = None
        context['result_css'] = ""
        context['slave_url'] = ""
        context['steps'] = []
        context['properties'] = []

        return context
Ejemplo n.º 16
0
    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))
Ejemplo n.º 17
0
    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))