Пример #1
0
    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 = 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)

        # 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)
Пример #2
0
    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 = 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)

        # 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)
Пример #3
0
    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()))
Пример #4
0
    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()))
Пример #5
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)
Пример #6
0
    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
Пример #7
0
    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
Пример #8
0
    def performAction(self, req):
        url = None
        authz = self.getAuthz(req)
        res = yield authz.actionAllowed(self.action, req, self.builder)

        if not res:
            url = path_to_authzfail(req)
        else:
            # get a control object
            c = interfaces.IControl(self.getBuildmaster(req))
            bc = c.getBuilder(self.builder.getName())

            b = self.build_status
            builder_name = urllib.quote(self.builder.getName(), safe='')
            builder_name_link = urllib.quote(self.builder.getName(), safe='')
            log.msg("web rebuild of build %s:%s" %
                    (builder_name, b.getNumber()))
            name = authz.getUsernameFull(req)
            comments = req.args.get("comments", ["<no reason specified>"])[0]
            comments.decode(getRequestCharset(req))
            reason = ("The web-page 'rebuild' button was pressed "
                      "'%s': %s\n" % (name, comments))

            useSourcestamp = req.args.get("useSourcestamp", None)
            if useSourcestamp and useSourcestamp == ['updated']:
                absolute = False
            else:
                absolute = True

            msg = ""
            extraProperties = getAndCheckProperties(req)
            if not bc or not b.isFinished() or extraProperties is None:
                msg = "could not rebuild: "
                if b.isFinished():
                    msg += "build still not finished "
                if bc:
                    msg += "could not get builder control"
            else:
                tup = yield bc.rebuildBuild(
                    b,
                    reason=reason,
                    extraProperties=extraProperties,
                    absolute=absolute,
                    newOwner=authz.getUsernameFull(req))
                # rebuildBuild returns None on error (?!)
                if not tup:
                    msg = "rebuilding a build failed " + str(tup)
            # 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.

            url = path_to_builder(req, self.builder), msg
        defer.returnValue(url)
Пример #9
0
    def performAction(self, req):
        url = None
        authz = self.getAuthz(req)
        res = yield authz.actionAllowed(self.action, req, self.builder)

        if not res:
            url = path_to_authzfail(req)
        else:
            # get a control object
            c = interfaces.IControl(self.getBuildmaster(req))
            bc = c.getBuilder(self.builder.getName())

            b = self.build_status
            builder_name = self.builder.getName()
            log.msg("web rebuild of build %s:%s" % (builder_name, b.getNumber()))
            name =authz.getUsernameFull(req)
            comments = req.args.get("comments", ["<no reason specified>"])[0]
            comments.decode(getRequestCharset(req))
            reason = ("The web-page 'rebuild' button was pressed by "
                      "'%s': %s\n" % (name, comments))

            useSourcestamp = req.args.get("useSourcestamp", None)
            if useSourcestamp and useSourcestamp==['updated']:
                absolute=False
            else:
                absolute=True

            msg = ""
            extraProperties = getAndCheckProperties(req)
            if not bc or not b.isFinished() or extraProperties is None:
                msg = "could not rebuild: "
                if b.isFinished():
                    msg += "build still not finished "
                if bc:
                    msg += "could not get builder control"
            else:
                tup = yield bc.rebuildBuild(b, 
                    reason=reason, 
                    extraProperties=extraProperties,
                    absolute=absolute)
                # rebuildBuild returns None on error (?!)
                if not tup:
                    msg = "rebuilding a build failed "+ str(tup)
            # 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.

            url = path_to_builder(req, self.builder), msg
        defer.returnValue(url)
Пример #10
0
    def decode_request_arguments(request):
        args = {}
        encoding = getRequestCharset(request)

        for name, argl in request.args.iteritems():
            if name == 'checkbox':
                for cb in argl:
                    args[cb.decode(encoding)] = True
            else:
                args[name] = [arg.decode(encoding) for arg in argl]

        return args
Пример #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

        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
Пример #12
0
    def performAction(self, req):
        url = None
        authz = self.getAuthz(req)
        res = yield authz.actionAllowed(self.action, req, self.builder)

        if not res:
            url = path_to_authzfail(req)
        else:
            # get a control object
            c = interfaces.IControl(self.getBuildmaster(req))
            bc = c.getBuilder(self.builder.getName())

            b = self.build_status
            builder_name = self.builder.getName()
            log.msg("web rebuild of build %s:%s" %
                    (builder_name, b.getNumber()))
            name = authz.getUsernameFull(req)
            comments = req.args.get("comments", ["<no reason specified>"])[0]
            comments.decode(getRequestCharset(req))
            reason = ("The web-page 'rebuild' button was pressed by "
                      "'%s': %s\n" % (name, comments))
            msg = ""
            extraProperties = getAndCheckProperties(req)
            if not bc or not b.isFinished() or extraProperties is None:
                msg = "could not rebuild: "
                if b.isFinished():
                    msg += "build still not finished "
                if bc:
                    msg += "could not get builder control"
            else:
                tup = yield bc.rebuildBuild(b, reason, extraProperties)
                # check that (bsid, brids) were properly stored
                if not (isinstance(tup, tuple) and isinstance(tup[0], int)
                        and isinstance(tup[1], dict)):
                    msg = "rebuilding a build failed " + str(tup)
            # 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.

            url = path_to_builder(req, self.builder), msg
        defer.returnValue(url)
Пример #13
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)
Пример #14
0
    def performAction(self, req):
        # check if this is allowed
        res = yield self.getAuthz(req).actionAllowed(self.action, req,
                                             self.builder_status)
        if not res:
            log.msg("..but not authorized")
            defer.returnValue(path_to_authzfail(req))
            return

        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 = req.args.copy()

        # decode all of the args
        encoding = getRequestCharset(req)
        for name, argl in args.iteritems():
            args[name] = [ arg.decode(encoding) for arg in argl ]

        # damn html's ungeneric checkbox implementation...
        for cb in args.get("checkbox", []):
            args[cb] = True

        builder_name = self.builder_status.getName()

        for sch in master.allSchedulers():
            if schedulername == sch.name:
                try:
                    yield sch.force(owner, builder_name, **args)
                    msg = ""
                except ValidationError, e:
                    msg = html.escape(e.message.encode('ascii','ignore'))
                break
Пример #15
0
    def performAction(self, req):
        # check if this is allowed
        res = yield self.getAuthz(req).actionAllowed(self.action, req,
                                             self.builder_status)
        if not res:
            log.msg("..but not authorized")
            defer.returnValue(path_to_authzfail(req))
            return

        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 = req.args.copy()

        # decode all of the args
        encoding = getRequestCharset(req)
        for name, argl in args.iteritems():
            args[name] = [ arg.decode(encoding) for arg in argl ]

        # damn html's ungeneric checkbox implementation...
        for cb in args.get("checkbox", []):
            args[cb] = True

        builder_name = self.builder_status.getName()

        for sch in master.allSchedulers():
            if schedulername == sch.name:
                try:
                    yield sch.force(owner, builder_name, **args)
                    msg = ""
                except ValidationError, e:
                    msg = html.escape(e.message.encode('ascii','ignore'))
                break
Пример #16
0
    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 cancel 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 'Cancel Build' button was pressed by "
                  "'%s': %s\n" % (html.escape(name), html.escape(comments)))

        if self.build_status.getResults() == RESUME:
            yield self.build_status.builder.cancelBuildRequestsOnResume(
                self.build_status.getNumber())

        defer.returnValue(path_to_build(req, self.build_status))
Пример #17
0
    def content(self, req, cxt):
        status = self.getStatus(req)
        encoding = getRequestCharset(req)

        builders = req.args.get("builder", status.getBuilderNames())
        branches = [ b.decode(encoding)
                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)
        yield defer.gatherResults(brstatus_ds)

        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())
                label = None
                all_got_revisions = b.getAllGotRevisions()
                # If len = 1 then try if revision can be used as label.
                if len(all_got_revisions) == 1:
                    label = all_got_revisions[all_got_revisions.keys()[0]]
                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
        buildForceContext(cxt, req, self.getBuildmaster(req))
        template = req.site.buildbot_service.templates.get_template("builders.html")
        defer.returnValue(template.render(**cxt))
Пример #18
0
def _get_comments_from_request(req):
    comments = req.args.get("comments", ["<no reason specified>"])[0]
    return comments.decode(getRequestCharset(req))
Пример #19
0
def _get_comments_from_request(req):
    comments = req.args.get("comments", ["<no reason specified>"])[0]
    return comments.decode(getRequestCharset(req))
Пример #20
0
    def do_test_getRequestCharset(self, hdr, exp):
        req = mock.Mock()
        req.getHeader.return_value = hdr

        self.assertEqual(base.getRequestCharset(req), exp)
Пример #21
0
    def content(self, req, cxt):
        status = self.getStatus(req)
        encoding = getRequestCharset(req)

        showTags = req.args.get("tag", [])
        if not showTags:
            showTags = req.args.get("category", [])
            if not showTags:
                showTags = None

        builders = req.args.get("builder",
                                status.getBuilderNames(tags=showTags))
        branches = [
            b.decode(encoding) 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)
        yield defer.gatherResults(brstatus_ds)

        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=''),
                'tags': status.getBuilder(bn).tags,
                '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())
                label = None
                all_got_revisions = b.getAllGotRevisions()
                # If len = 1 then try if revision can be used as label.
                if len(all_got_revisions) == 1:
                    label = all_got_revisions[all_got_revisions.keys()[0]]
                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
        buildForceContext(cxt, req, self.getBuildmaster(req))
        template = req.site.buildbot_service.templates.get_template(
            "builders.html")
        defer.returnValue(template.render(**cxt))
    def do_test_getRequestCharset(self, hdr, exp):
        req = mock.Mock()
        req.getHeader.return_value = hdr

        self.assertEqual(base.getRequestCharset(req), exp)
Пример #23
0
    def content(self, request, cxt):
        status = self.getStatus(request)

        args = request.args.copy()

        # decode all of the args
        encoding = getRequestCharset(request)
        for name, argl in args.iteritems():
            if '_branch' in name:
                args[name] = [
                    self.decodeFromURL(arg, encoding) for arg in argl
                ]

        #Get builder info
        builder_status = None
        if args.has_key("builder_name") and len(args["builder_name"]) == 1:
            builder_status = status.getBuilder(
                self.decodeFromURL(args["builder_name"][0], encoding))
            bm = self.getBuildmaster(request)

            cxt['slaves'] = [
                s for s in builder_status.getSlaves() if s.isConnected()
            ]
            cxt['slaves'] = sorted(cxt['slaves'],
                                   key=attrgetter('friendly_name'))

            #Get branches
            encoding = getRequestCharset(request)
            branches = [
                b.decode(encoding) for b in args.get("branch", []) if b
            ]
            cxt['branches'] = branches

            return_page = ""
            if args.has_key("return_page"):
                return_page = args['return_page']
                if not isinstance(return_page, basestring):
                    return_page = args['return_page'][0]

            #Add scheduler info
            buildForceContext(cxt, request, self.getBuildmaster(request),
                              builder_status.getName())

            #URL to force page with return param
            url = args['builder_url'][0]
            url_parts = list(urlparse(url))

            if len(url_parts) > 0 and len(return_page) > 0:
                return_page = "&returnpage={0}".format(return_page)
            else:
                return_page = "?returnpage={0}".format(return_page)
            cxt['return_page'] = return_page

            url_parts[2] += "/force"
            url_parts[4] += return_page
            force_url = urlunparse(url_parts)
            cxt['force_url'] = force_url

            authz = self.getAuthz(request)
            cxt['is_admin'] = yield authz.getUserAttr(request, 'is_admin', 0)
            cxt['rt_update'] = args
            request.args = args

            template = request.site.buildbot_service.templates.get_template(
                "force_build_dialog.html")
            defer.returnValue(template.render(**cxt))

        else:
            page = ErrorPage(INTERNAL_SERVER_ERROR, "Missing parameters",
                             "Not all parameters were given")
            defer.returnValue(page.render(request))