Ticket #99: Queue.diff

File Queue.diff, 11.6 kB (added by cli, 4 months ago)

Patch that might introduce some of the features requested here.

  • buildbot-0.7.8-orig/buildbot/process/builder.py

    old new  
    333333    def __repr__(self): 
    334334        return "<Builder '%s' at %d>" % (self.name, id(self)) 
    335335 
    336  
     336    # Is this the method to cancel double queued builds? 
    337337    def submitBuildRequest(self, req): 
     338        for breq in self.buildable: 
     339            if breq == req: 
     340                # Check if install_set is on and languages equal 
     341                # This is an ugly hack!!! 
     342                if req.properties.has_key('install_set') and breq.properties.has_key('install_set') and \ 
     343                    req.properties.has_key('languages') and breq.properties.has_key('languages'): 
     344                    if breq.properties['languages'] == req.properties['languages'] and \ 
     345                        breq.properties['install_set'] == req.properties['install_set']: 
     346                        print "DEBUG: Build %s skipped!" % req 
     347                        return 
     348                    else: 
     349                        # Enable install_set 
     350                        breq.properties['install_set'] = 'on'  
     351                        print "DEBUG: Build %s merged!" % req 
     352                        return                   
     353                else: 
     354                    print "DEBUG: Build %s skipped!" % req 
     355                    return 
     356         
    338357        req.submittedAt = now() 
    339358        self.buildable.append(req) 
    340359        req.requestSubmitted(self) 
    341360        self.builder_status.addBuildRequest(req.status) 
    342361        self.maybeStartBuild() 
     362        return 
    343363 
    344364    def cancelBuildRequest(self, req): 
    345365        if req in self.buildable: 
     
    714734            return 
    715735 
    716736        ss = bs.getSourceStamp(absolute=True) 
    717         req = base.BuildRequest(reason, ss, self.original.name) 
     737        # The properties need to be passed again 
     738        log.msg("Resubmit build #%s" % bs.getNumber()) 
     739        log.msg("Resubmit build %s" % bs.getProperties()) 
     740        req = base.BuildRequest(reason, ss, self.original.name, bs.getProperties()) 
    718741        self.requestBuild(req) 
    719742 
    720743    def getPendingBuilds(self): 
    721         # return IBuildRequestControl objects 
    722         raise NotImplementedError 
     744        """Return a list of L{IBuildRequestControl} objects for this Builder. 
     745        Each one corresponds to a pending build that has not yet started (due 
     746        to a scarcity of build slaves). These upcoming builds can be canceled 
     747        through the control object.""" 
     748        return self.original.buildable 
    723749 
    724750    def getBuild(self, number): 
    725751        return self.original.getBuild(number) 
  • buildbot-0.7.8-orig/buildbot/process/properties.py

    old new  
    3939 
    4040    def __getitem__(self, name): 
    4141        """Just get the value for this property.""" 
    42         rv = self.properties[name][0] 
    43         return rv 
     42        if self.has_key(name): 
     43            return self.properties[name][0] 
     44        else: 
     45            return None 
     46         
     47    def __setitem__(self, key, value): 
     48        self.properties[key] = (value, "Merged") 
    4449 
    4550    def has_key(self, name): 
    4651        return self.properties.has_key(name) 
  • buildbot-0.7.8-orig/buildbot/status/web/baseweb.py

    old new  
    2020from buildbot.status.web.slaves import BuildSlavesResource 
    2121from buildbot.status.web.xmlrpc import XMLRPCServer 
    2222from buildbot.status.web.about import AboutBuildbot 
     23from buildbot.status.web.queue import QueueStatusResource 
    2324 
    2425# this class contains the status services (WebStatus and the older Waterfall) 
    2526# which can be put in c['status']. It also contains some of the resources 
  • buildbot-0.7.8-orig/buildbot/status/web/builder.py

    old new  
    99from buildbot.status.web.base import HtmlResource, make_row, \ 
    1010     make_force_build_form, OneLineMixin 
    1111from buildbot.process.base import BuildRequest 
     12from buildbot.process.properties import Properties 
    1213from buildbot.sourcestamp import SourceStamp 
    1314from buildbot import version, util 
    1415 
     
    5051  <input type="submit" value="Stop Build" /> 
    5152</form>''' % stopURL 
    5253        return data 
     54     
     55    def makeRemoveFromQueueButton(self, req, buildnum): 
     56        stopURL = urllib.quote(req.childLink("builds/%d/remove" % buildnum)) 
     57        data = ''' 
     58<form action="%s" class="command stopbuild" style="display:inline"> 
     59  <input type="submit" value="Remove Build" /> 
     60</form>''' % stopURL 
     61        return data 
    5362 
    5463    def body(self, req): 
    5564        b = self.builder_status 
     
    7685            data += "</ul>\n" 
    7786        else: 
    7887            data += "<h2>no current builds</h2>\n" 
     88             
     89        # Then a section with the queued build requests 
     90        data += "<h2>Pending Builds:</h2>\n" 
     91        # Retrieve the builders queue 
     92        pendingBuilds = b.getPendingBuilds() 
     93        if pendingBuilds: 
     94            # Determine the build numbers of the queue builds. 
     95            # Sadly we cannot remove the build from the queue with this 
     96            # number as it is not valid yet. 
     97            nextBuildNumber = b.nextBuildNumber 
     98            data += "<ul>\n" 
     99            for buildRequestStatus in pendingBuilds: 
     100                sourceStamp = buildRequestStatus.getSourceStamp() 
     101                data += "<li>#%u " % nextBuildNumber 
     102                data += "Branch: %s " % sourceStamp.branch 
     103                data += "[rev=%s]" % sourceStamp.revision 
     104                data += self.makeRemoveFromQueueButton(req, nextBuildNumber) 
     105                data += "</li>" 
     106                nextBuildNumber += 1 
     107            data += "</ul>\n" 
     108        else: 
     109            data += "No pending builds" 
    79110 
    80111        # Then a section with the last 5 builds, with the most recent build 
    81112        # distinguished from the rest. 
     
    190221        if not revision: 
    191222            revision = None 
    192223 
     224        install_set = req.args.get("install_set", [""])[0] 
     225        languages   = req.args.get("languages", [""])[0] 
     226 
     227        customBuildProps = Properties() 
     228        customBuildProps.setProperty("install_set", install_set, "") 
     229        customBuildProps.setProperty("languages", languages, "") 
     230 
    193231        # TODO: if we can authenticate that a particular User pushed the 
    194232        # button, use their name instead of None, so they'll be informed of 
    195233        # the results. 
    196234        s = SourceStamp(branch=branch, revision=revision) 
    197         req = BuildRequest(r, s, builderName=self.builder_status.getName()
     235        req = BuildRequest(r, s, builderName=self.builder_status.getName(), properties=customBuildProps
    198236        try: 
    199237            self.builder_control.requestBuildSoon(req) 
    200238        except interfaces.NoSlaveError: 
  • buildbot-0.7.8-orig/buildbot/status/web/build.py

    old new  
    1111from buildbot.status.web.tests import TestsResource 
    1212from buildbot.status.web.step import StepsResource 
    1313from buildbot import version, util 
     14from buildbot.status.web.queue import QueueStatusResource 
    1415 
    1516# /builders/$builder/builds/$buildnum 
    1617class StatusResourceBuild(HtmlResource): 
     
    5657            results = b.getResults() 
    5758            data += "<h2>Results:</h2>\n" 
    5859            text = " ".join(b.getText()) 
    59             data += '<span class="%s">%s</span>\n' % (css_classes[results], 
    60                                                       text) 
     60            if results != None: 
     61                data += '<span class="%s">%s</span>\n' % (css_classes[results], text) 
    6162            if b.getTestResults(): 
    6263                url = req.childLink("tests") 
    6364                data += "<h3><a href=\"%s\">test results</a></h3>\n" % url 
     
    284285                    build_control = None 
    285286                return StatusResourceBuild(build_status, build_control, 
    286287                                           self.builder_control) 
     288            else: 
     289                # Probably a build that was not started yet 
     290                return QueueStatusResource(path, req, num, self.builder_status, self.builder_control) 
    287291 
    288292        return HtmlResource.getChild(self, path, req) 
    289293 
  • buildbot-0.7.8-orig/buildbot/status/web/queue.py

    old new  
     1from twisted.web.util import Redirect, DeferredResource 
     2from twisted.internet import defer, reactor 
     3from buildbot.status.web.base import HtmlResource 
     4 
     5# Shows the queue of a Builder 
     6class QueueStatusResource(HtmlResource): 
     7    def __init__(self, path, req, num, builder_status, builder_control): 
     8        HtmlResource.__init__(self) 
     9        self.path = path 
     10        self.req  = req 
     11        self.num  = num 
     12        self.builder_status = builder_status 
     13        self.builder_control = builder_control 
     14         
     15    def body(self, request):     
     16        return "" 
     17     
     18    # Removes a build from a builders queue 
     19    def removeFromQueue(self, req): 
     20        # Delete the build request from queue 
     21        idx = self.builder_status.nextBuildNumber - self.num 
     22         
     23        if idx >= 0: 
     24            buildables = self.builder_control.getPendingBuilds() 
     25            buildables[idx].cancel() 
     26 
     27        # we're at http://localhost:8080/svn-hello/builds/5/stop?[args] and 
     28        # we want to go to: http://localhost:8080/svn-hello 
     29        r = Redirect("../..") 
     30        d = defer.Deferred() 
     31        reactor.callLater(1, d.callback, r) 
     32        return DeferredResource(d) 
     33         
     34    def getChild(self, path, req): 
     35        if path == "remove": 
     36            return self.removeFromQueue(req) 
     37        else: 
     38            return HtmlResource.getChild(self, path, req) 
     39         
  • buildbot-0.7.8-orig/buildbot/status/web/waterfall.py

    old new  
    129129        number = b.getNumber() 
    130130        url = path_to_build(req, b) 
    131131        reason = b.getReason() 
    132         text = ('<a title="Reason: %s" href="%s">Build %d</a>' 
    133                 % (html.escape(reason), url, number)) 
     132        if reason == None: 
     133            reason = "No specific reason" 
     134             
     135        branch = b.getProperty('branch') 
     136        if branch == None: 
     137            branch = "ERROR: No CWS/MWS provided!" 
     138             
     139        text = ('<a title="Reason: %s | CWS: %s" href="%s">Build %d<br/>CWS/MWS: %s</a>' 
     140                % (html.escape(reason), html.escape(branch), url, number, html.escape(branch))) 
    134141        color = "yellow" 
    135142        class_ = "start" 
    136143        if b.isFinished() and not b.getSteps():