Esempio n. 1
0
    def getBox(self, req):
        urlbase = path_to_step(req, self.original)
        text = self.original.getText()
        if text is None:
            log.msg("getText() gave None", urlbase)
            text = []
        text = text[:]

        def native_link_fn(l):
            if l.hasContents():
                url = urlbase + "/logs/%s" % urllib.quote(l.getName())
            else:
                url = None
            return url

        logs, urls, _ = getStepLogsURLsAndAliases(
            self.original,
            False,
            native_link_fn,
        )

        cxt = dict(text=text, logs=logs, urls=urls)

        template = req.site.buildbot_service.templates.get_template(
            "box_macros.html")
        text = template.module.step_box(**unicodify(cxt))

        class_ = "BuildStep " + build_get_class(self.original)
        return Box(text,
                   class_=class_,
                   buildNumber=self.original.build_number,
                   builder=self.original.builder.getName(),
                   stepName=self.original.getName())
Esempio n. 2
0
    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()

        ctx.update(dict(slave=slave,
                        slavename=self.slavename,
                        current=current_builds,
                        recent=recent_builds,
                        shutdown_url=request.childLink("shutdown"),
                        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(**unicodify(ctx))
        return data
Esempio n. 3
0
    def content(self, request, ctx):
        s = self.getStatus(request)

        #?no_builders=1 disables build column
        show_builder_column = not (request.args.get('no_builders',
                                                    '0')[0]) == '1'
        ctx['show_builder_column'] = show_builder_column

        used_by_builder = {}
        for bname in s.getBuilderNames():
            b = s.getBuilder(bname)
            for bs in b.getSlaves():
                slavename = bs.getName()
                if slavename not in used_by_builder:
                    used_by_builder[slavename] = []
                used_by_builder[slavename].append(bname)

        slaves = ctx['slaves'] = []
        for name in util.naturalSort(s.getSlaveNames()):
            info = {}
            slaves.append(info)
            slave = s.getSlave(name)
            slave_status = s.botmaster.slaves[name].slave_status
            info['running_builds'] = len(slave_status.getRunningBuilds())
            info['link'] = request.childLink(urllib.quote(name, ''))
            info['name'] = name

            if show_builder_column:
                info['builders'] = []
                for b in used_by_builder.get(name, []):
                    info['builders'].append(
                        dict(link=request.childLink("../builders/%s" % b),
                             name=b))

            info['version'] = slave.getVersion()
            info['connected'] = slave.isConnected()
            info['connectCount'] = slave.getConnectCount()

            info['admin'] = unicode(slave.getAdmin() or '', 'utf-8')
            last = slave.lastMessageReceived()
            if last:
                info['last_heard_from_age'] = abbreviate_age(time.time() -
                                                             last)
                info['last_heard_from_time'] = time.strftime(
                    "%Y-%b-%d %H:%M:%S", time.localtime(last))

        template = request.site.buildbot_service.templates.get_template(
            "buildslaves.html")
        data = template.render(**unicodify(ctx))
        return data
Esempio n. 4
0
    def content(self, request, cxt):
        status = self.getStatus(request)

        if request.path == '/shutdown':
            return redirectTo(path_to_authfail(request), request)
        elif request.path == '/cancel_shutdown':
            return redirectTo(path_to_authfail(request), request)

        cxt.update(
            shutting_down=status.shuttingDown,
            shutdown_url=request.childLink("shutdown"),
            cancel_shutdown_url=request.childLink("cancel_shutdown"),
        )
        template = request.site.buildbot_service.templates.get_template(
            "root.html")
        return template.render(**unicodify(cxt))
Esempio n. 5
0
        def got_changes(allChanges):
            debugInfo["source_all"] = len(allChanges)
            revisions = list(self.filterRevisions(allChanges, max_revs=numRevs))
            debugInfo["revision_final"] = len(revisions)

            # Fetch all the builds for all builders until we get the next build
            # after lastRevision.
            builderList = None
            allBuilds = None
            if revisions:
                lastRevision = revisions[len(revisions) - 1].revision
                debugInfo["last_revision"] = lastRevision

                (builderList, allBuilds) = self.getAllBuildsForRevision(status,
                                                    request,
                                                    lastRevision,
                                                    numBuilds,
                                                    categories,
                                                    builders,
                                                    debugInfo,
                                                    revisions)

            debugInfo["added_blocks"] = 0
            debugInfo["from_cache"] = 0

            if request.args.get("display_cache", None):
                data = ""
                data += "\nGlobal Cache\n"
                data += self.cache.display()
                return data

            cxt.update(self.displayPage(request, status, builderList,
                                        allBuilds, revisions, categories,
                                        repository, branch, debugInfo))

            templates = request.site.buildbot_service.templates
            template = templates.get_template("console.html")
            cxt['mastername'] = (
                request.site.buildbot_service.master.properties['mastername'])
            data = template.render(unicodify(cxt))

            # Clean up the cache.
            if debugInfo["added_blocks"]:
              self.cache.trim()

            return data
Esempio n. 6
0
    def content(self, request, ctx):
        """Display a build in the same format as the waterfall page.
        The HTTP GET parameters are the builder name and the build
        number."""

        status = self.getStatus(request)
        request.setHeader('Cache-Control', 'no-cache')

        # Get the parameters.
        name = request.args.get("builder", [None])[0]
        number = request.args.get("number", [None])[0]
        if not name or not number:
            return "builder and number parameter missing"
        number = int(number)

        # Check if the builder in parameter exists.
        try:
            builder = status.getBuilder(name)
        except:
            return "unknown builder"

        # Check if the build in parameter exists.
        build = builder.getBuild(int(number))
        if not build:
            return "unknown build %s" % number

        rows = ctx['rows'] = []

        # Display each step, starting by the last one.
        for i in range(len(build.getSteps()) - 1, -1, -1):
            step = build.getSteps()[i]
            if step.isStarted() and step.getText():
                rows.append(IBox(step).getBox(request).td(align="center"))

        # Display the bottom box with the build number in it.
        ctx['build'] = IBox(build).getBox(request).td(align="center")

        template = request.site.buildbot_service.templates.get_template(
            "buildstatus.html")
        data = template.render(**unicodify(ctx))

        # We want all links to display in a new tab/window instead of in the
        # current one.
        # TODO: Move to template
        data = data.replace('<a ', '<a target="_blank"')
        return data
Esempio n. 7
0
 def getBox(self, req):
     b = self.original
     number = b.getNumber()
     url = path_to_build(req, b)
     reason = b.getReason()
     template = req.site.buildbot_service.templates.get_template(
         "box_macros.html")
     cxt = {
         'reason': reason,
         'url': url,
         'number': number,
     }
     text = template.module.build_box(**unicodify(cxt))
     class_ = "start"
     if b.isFinished() and not b.getSteps():
         # the steps have been pruned, so there won't be any indication
         # of whether it succeeded or failed.
         class_ = build_get_class(b)
     return Box([text], class_="BuildStep " + class_)
Esempio n. 8
0
    def content(self, request, cxt):
        status = self.getStatus(request)

        cxt['show_events_checked'] = request.args.get(
            "show_events", ["false"])[0].lower() == "true"
        cxt['branches'] = [b for b in request.args.get("branch", []) if b]
        cxt['failures_only'] = request.args.get("failures_only",
                                                ["false"])[0].lower() == "true"
        cxt['committers'] = [c for c in request.args.get("committer", []) if c]

        # this has a set of toggle-buttons to let the user choose the
        # builders
        show_builders = request.args.get("show", [])
        show_builders.extend(request.args.get("builder", []))
        cxt['show_builders'] = show_builders
        cxt['all_builders'] = status.getBuilderNames(
            categories=self.categories)

        # a couple of radio-button selectors for refresh time will appear
        # just after that text
        times = [
            ("none", "None"),
            ("60", "60 seconds"),
            ("300", "5 minutes"),
            ("600", "10 minutes"),
        ]
        current_reload_time = request.args.get("reload", ["none"])
        if current_reload_time:
            current_reload_time = current_reload_time[0]
        if current_reload_time not in [t[0] for t in times]:
            times.insert(0, (current_reload_time, current_reload_time))

        cxt['times'] = times
        cxt['current_reload_time'] = current_reload_time

        template = request.site.buildbot_service.templates.get_template(
            "waterfallhelp.html")
        return template.render(**unicodify(cxt))
Esempio n. 9
0
    def content(self, req, cxt):
        s = self.step_status
        b = s.getBuild()

        # 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.
        logs, _, _ = getStepLogsURLsAndAliases(
            s,
            True,
            lambda l: req.childLink("logs/%s" % urllib.quote(l.getName())),
        )
        cxt['logs'] = logs

        start, end = s.getTimes()

        if start:
            cxt['start'] = ctime(start)
            if end:
                cxt['end'] = ctime(end)
                cxt['elapsed'] = util.formatInterval(end - start)
            else:
                cxt['end'] = "Not Finished"
                cxt['elapsed'] = util.formatInterval(util.now() - start)

        cxt.update(
            dict(builder_link=path_to_builder(req, b.getBuilder()),
                 build_link=path_to_build(req, b),
                 b=b,
                 s=s,
                 result_css=css_classes[s.getResults()[0]]))

        template = req.site.buildbot_service.templates.get_template(
            "buildstep.html")
        return template.render(**unicodify(cxt))
Esempio n. 10
0
    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))
Esempio n. 11
0
    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'] = []
        wfd = defer.waitForDeferred(b.getPendingBuildRequestStatuses())
        yield wfd
        statuses = wfd.getResult()
        for pb in statuses:
            changes = []

            wfd = defer.waitForDeferred(pb.getSourceStamp())
            yield wfd
            source = wfd.getResult()

            wfd = defer.waitForDeferred(pb.getSubmitTime())
            yield wfd
            submitTime = wfd.getResult()

            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),
            })

        numbuilds = int(req.args.get('numbuilds', ['20'])[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)
        cxt['mastername'] = (
            req.site.buildbot_service.master.properties['mastername'])
        template = req.site.buildbot_service.templates.get_template(
            "builder.html")
        yield template.render(**unicodify(cxt))
Esempio n. 12
0
    def content(self, req, cxt):
        status = self.getStatus(req)

        builders = req.args.get("builder", status.getBuilderNames())
        branches = [b for b in req.args.get("branch", []) if b]

        # get counts of pending builds for each builder
        brstatus_ds = []
        brcounts = {}

        def keep_count(statuses, builderName):
            brcounts[builderName] = len(statuses)

        for builderName in builders:
            builder_status = status.getBuilder(builderName)
            d = builder_status.getPendingBuildRequestStatuses()
            d.addCallback(keep_count, builderName)
            brstatus_ds.append(d)
        wfd = defer.waitForDeferred(defer.gatherResults(brstatus_ds))
        yield wfd
        wfd.getResult()

        cxt['branches'] = branches
        bs = cxt['builders'] = []

        building = 0
        online = 0
        base_builders_url = path_to_root(req) + "builders/"
        for bn in builders:
            bld = {
                'link': base_builders_url + urllib.quote(bn, safe=''),
                'name': bn
            }
            bs.append(bld)

            builder = status.getBuilder(bn)
            builds = list(
                builder.generateFinishedBuilds(map_branches(branches),
                                               num_builds=1))
            if builds:
                b = builds[0]
                bld['build_url'] = (bld['link'] + "/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()

                bld['build_label'] = label
                bld['build_text'] = " ".join(b.getText())
                bld['build_css_class'] = build_get_class(b)

            current_box = ICurrentBox(builder).getBox(status, brcounts)
            bld['current_box'] = current_box.td()

            builder_status = builder.getState()[0]
            if builder_status == "building":
                building += 1
                online += 1
            elif builder_status != "offline":
                online += 1

        cxt['authz'] = self.getAuthz(req)
        cxt['num_building'] = building
        cxt['num_online'] = online

        template = req.site.buildbot_service.templates.get_template(
            "builders.html")
        yield template.render(**unicodify(cxt))
Esempio n. 13
0
    def content_with_db_data(self, changes, brcounts, request, ctx):
        status = self.getStatus(request)
        ctx['refresh'] = self.get_reload_time(request)

        # we start with all Builders available to this Waterfall: this is
        # limited by the config-file -time categories= argument, and defaults
        # to all defined Builders.
        allBuilderNames = status.getBuilderNames(categories=self.categories)
        builders = [status.getBuilder(name) for name in allBuilderNames]

        # but if the URL has one or more builder= arguments (or the old show=
        # argument, which is still accepted for backwards compatibility), we
        # use that set of builders instead. We still don't show anything
        # outside the config-file time set limited by categories=.
        showBuilders = request.args.get("show", [])
        showBuilders.extend(request.args.get("builder", []))
        if showBuilders:
            builders = [b for b in builders if b.name in showBuilders]

        # now, if the URL has one or category= arguments, use them as a
        # filter: only show those builders which belong to one of the given
        # categories.
        showCategories = request.args.get("category", [])
        if showCategories:
            builders = [b for b in builders if b.category in showCategories]

        # If the URL has the failures_only=true argument, we remove all the
        # builders that are not currently red or won't be turning red at the end
        # of their current run.
        failuresOnly = request.args.get("failures_only", ["false"])[0]
        if failuresOnly.lower() == "true":
            builders = [b for b in builders if not self.isSuccess(b)]

        (changeNames, builderNames, timestamps, eventGrid, sourceEvents) = \
                      self.buildGrid(request, builders, changes)

        # start the table: top-header material
        locale_enc = locale.getdefaultlocale()[1]
        if locale_enc is not None:
            locale_tz = unicode(time.tzname[time.localtime()[-1]], locale_enc)
        else:
            locale_tz = unicode(time.tzname[time.localtime()[-1]])
        ctx['tz'] = locale_tz
        ctx['changes_url'] = request.childLink("../changes")

        bn = ctx['builders'] = []

        for name in builderNames:
            builder = status.getBuilder(name)
            top_box = ITopBox(builder).getBox(request)
            current_box = ICurrentBox(builder).getBox(status, brcounts)
            bn.append({
                'name':
                name,
                'category':
                builder.category,
                'url':
                request.childLink("../builders/%s" %
                                  urllib.quote(name, safe='')),
                'top':
                top_box.text,
                'top_class':
                top_box.class_,
                'status':
                current_box.text,
                'status_class':
                current_box.class_,
            })

        ctx.update(
            self.phase2(request, changeNames + builderNames, timestamps,
                        eventGrid, sourceEvents))

        def with_args(req, remove_args=[], new_args=[], new_path=None):
            # sigh, nevow makes this sort of manipulation easier
            newargs = req.args.copy()
            for argname in remove_args:
                newargs[argname] = []
            if "branch" in newargs:
                newargs["branch"] = [b for b in newargs["branch"] if b]
            for k, v in new_args:
                if k in newargs:
                    newargs[k].append(v)
                else:
                    newargs[k] = [v]
            newquery = "&amp;".join([
                "%s=%s" % (urllib.quote(k), urllib.quote(v)) for k in newargs
                for v in newargs[k]
            ])
            if new_path:
                new_url = new_path
            elif req.prepath:
                new_url = req.prepath[-1]
            else:
                new_url = ''
            if newquery:
                new_url += "?" + newquery
            return new_url

        if timestamps:
            bottom = timestamps[-1]
            ctx['nextpage'] = with_args(request, ["last_time"],
                                        [("last_time", str(int(bottom)))])

        helpurl = path_to_root(request) + "waterfall/help"
        ctx['help_url'] = with_args(request, new_path=helpurl)

        if self.get_reload_time(request) is not None:
            ctx['no_reload_page'] = with_args(request, remove_args=["reload"])

        template = request.site.buildbot_service.templates.get_template(
            "waterfall.html")
        ctx['mastername'] = (
            request.site.buildbot_service.master.properties['mastername'])
        data = template.render(**unicodify(ctx))
        return data