Ticket #138: 0006-Add-force-stop-buttons-that-affect-all-builders.patch

File 0006-Add-force-stop-buttons-that-affect-all-builders.patch, 8.4 KB (added by tsuna, 3 years ago)

[PATCH 06/11] Add force/stop buttons that affect all builders.

  • buildbot/status/web/baseweb.py

    From 9eccfbc8b3c05c4ad1fec531ad3ef8bb401f877e Mon Sep 17 00:00:00 2001
    From: Benoit Sigoure <tsuna@lrde.epita.fr>
    Date: Thu, 8 Nov 2007 17:25:13 +0100
    Subject: [PATCH 06/11] Add force/stop buttons that affect all builders.
    
    	The `Latest Build' and `Recent Builds' pages now have a button to
    	force or stop a build on all builders.  It's more convenient to
    	trigger a build on all builders (a feature that has frequently been
    	asked).
    	* status/web/baseweb.py (OneLinePerBuild.body):  Print forms to
    	force/stop builds on all builders, depending on the state of
    	builders.
    	(OneBoxPerBuilder.body): Ditto.
    	(WebStatus): Document the new `_all/{force,stop}' URLs.
    	* status/web/builder.py (StatusResourceAllBuilders): New class.
    	(BuildersResource.getChild): Handle the special child `_all' that
    	dispatches commands on all builders.
    
    Signed-off-by: Benoit Sigoure <tsuna@lrde.epita.fr>
    ---
     buildbot/status/web/baseweb.py |   41 ++++++++++++++++++++++++++-
     buildbot/status/web/builder.py |   60 ++++++++++++++++++++++++++++++++++++++--
     2 files changed, 96 insertions(+), 5 deletions(-)
    
    diff --git a/buildbot/status/web/baseweb.py b/buildbot/status/web/baseweb.py
    index 9475334..aa9551b 100644
    a b  
    1111from buildbot.interfaces import IControl, IStatusReceiver 
    1212 
    1313from buildbot.status.web.base import HtmlResource, Box, \ 
    14      build_get_class, ICurrentBox, OneLineMixin, map_branches 
     14     build_get_class, ICurrentBox, OneLineMixin, map_branches, \ 
     15     make_stop_form, make_force_build_form 
    1516from buildbot.status.web.waterfall import WaterfallStatusResource 
    1617from buildbot.status.web.changes import ChangesResource 
    1718from buildbot.status.web.builder import BuildersResource 
     
    105106            data += ("<p>of builders: %s</p>\n" % (", ".join(builders))) 
    106107        data += "<ul>\n" 
    107108        got = 0 
     109        building = False 
     110        online = 0 
    108111        for build in g: 
    109112            got += 1 
    110113            data += " <li>" + self.make_line(req, build) + "</li>\n" 
     114            builder_status = build.getBuilder().getState()[0] 
     115            if builder_status == "building": 
     116                building = True 
     117                online += 1 
     118            elif builder_status != "offline": 
     119                online += 1 
    111120        if not got: 
    112121            data += " <li>No matching builds found</li>\n" 
    113122        data += "</ul>\n" 
     123 
     124        if building: 
     125            stopURL = "builders/_all/stop" 
     126            data += make_stop_form(stopURL) 
     127        if online: 
     128            forceURL = "builders/_all/force" 
     129            data += make_force_build_form(forceURL) 
     130 
    114131        return data 
    115132 
    116133 
     
    165182 
    166183    def body(self, req): 
    167184        status = self.getStatus(req) 
    168          
     185 
    169186        builders = req.args.get("builder", status.getBuilderNames()) 
    170187        branches = [b for b in req.args.get("branch", []) if b] 
    171188 
     
    173190 
    174191        data += "<h2>Latest builds: %s</h2>\n" % ", ".join(branches) 
    175192        data += "<table>\n" 
     193 
     194        building = False 
     195        online = 0 
    176196        for bn in builders: 
    177197            builder = status.getBuilder(bn) 
    178198            data += "<tr>\n" 
     
    200220                data += '<td class="LastBuild box" >no build</td>\n' 
    201221            current_box = ICurrentBox(builder).getBox(status) 
    202222            data += current_box.td(align="center") 
     223 
     224            builder_status = builder.getState()[0] 
     225            if builder_status == "building": 
     226                building = True 
     227                online += 1 
     228            elif builder_status != "offline": 
     229                online += 1 
     230 
    203231        data += "</table>\n" 
     232 
     233        if building: 
     234            stopURL = "builders/_all/stop" 
     235            data += make_stop_form(stopURL) 
     236        if online: 
     237            forceURL = "builders/_all/force" 
     238            data += make_force_build_form(forceURL) 
     239 
    204240        return data 
    205241 
    206242 
     
    254290     /builders/BUILDERNAME/builds/NUM/steps/STEPNAME/logs/LOGNAME: a StatusLog 
    255291     /builders/BUILDERNAME/builds/NUM/tests : summarize test results 
    256292     /builders/BUILDERNAME/builds/NUM/tests/TEST.NAME: results of one test 
     293     /builders/_all/{force,stop}: force a build/stop building on all builders. 
    257294     /changes : summarize all ChangeSources 
    258295     /changes/CHANGENUM: a page describing a single Change 
    259296     /schedulers/SCHEDULERNAME: a page describing a Scheduler, including 
  • buildbot/status/web/builder.py

    diff --git a/buildbot/status/web/builder.py b/buildbot/status/web/builder.py
    index f67fb45..4ea47cf 100644
    a b  
    1111from buildbot.process.base import BuildRequest 
    1212from buildbot.sourcestamp import SourceStamp 
    1313 
    14 from buildbot.status.web.build import BuildsResource 
     14from buildbot.status.web.build import BuildsResource, StatusResourceBuild 
    1515 
    1616# /builders/$builder 
    1717class StatusResourceBuilder(HtmlResource, OneLineMixin): 
     
    114114            pingURL = urllib.quote(req.childLink("ping")) 
    115115            data += """ 
    116116            <form action="%s" class='command pingbuilder'> 
    117             <p>To ping the buildslave(s), push the 'Ping' button</p> 
     117            <p>To ping the buildslave(s), click the 'Ping' button</p> 
    118118 
    119119            <input type="submit" value="Ping Builder" /> 
    120120            </form> 
     
    151151        if not revision: 
    152152            revision = None 
    153153 
    154         # TODO: if we can authenticate that a particular User pushed the 
     154        # TODO: if we can authenticate that a particular User clicked the 
    155155        # button, use their name instead of None, so they'll be informed of 
    156156        # the results. 
    157157        s = SourceStamp(branch=branch, revision=revision) 
     
    200200        return HtmlResource.getChild(self, path, req) 
    201201 
    202202 
     203# /builders/_all 
     204class StatusResourceAllBuilders(HtmlResource, OneLineMixin): 
     205 
     206    def __init__(self, status, control): 
     207        HtmlResource.__init__(self) 
     208        self.status = status 
     209        self.control = control 
     210 
     211    def getChild(self, path, req): 
     212        if path == "force": 
     213            return self.force(req) 
     214        if path == "stop": 
     215            return self.stop(req) 
     216 
     217        return HtmlResource.getChild(self, path, req) 
     218 
     219    def force(self, req): 
     220        for bname in self.status.getBuilderNames(): 
     221            builder_status = self.status.getBuilder(bname) 
     222            builder_control = None 
     223            c = self.getControl(req) 
     224            if c: 
     225                builder_control = c.getBuilder(bname) 
     226            build = StatusResourceBuilder(builder_status, builder_control) 
     227            build.force(req) 
     228        return Redirect("../../waterfall") 
     229 
     230    def stop(self, req): 
     231        for bname in self.status.getBuilderNames(): 
     232            builder_status = self.status.getBuilder(bname) 
     233            builder_control = None 
     234            c = self.getControl(req) 
     235            if c: 
     236                builder_control = c.getBuilder(bname) 
     237            (state, current_builds) = builder_status.getState() 
     238            if state != "building": 
     239                continue 
     240            for b in current_builds: 
     241                build_status = builder_status.getBuild(b.number) 
     242                if not build_status: 
     243                    continue 
     244                if builder_control: 
     245                    build_control = builder_control.getBuild(b.number) 
     246                else: 
     247                    build_control = None 
     248                build = StatusResourceBuild(build_status, build_control, 
     249                                            builder_control) 
     250                build.stop(req) 
     251        return Redirect("../../waterfall") 
     252 
     253 
    203254# /builders 
    204255class BuildersResource(HtmlResource): 
    205256    title = "Builders" 
     
    231282            if c: 
    232283                builder_control = c.getBuilder(path) 
    233284            return StatusResourceBuilder(builder_status, builder_control) 
     285        if path == "_all": 
     286            return StatusResourceAllBuilders(self.getStatus(req), 
     287                                             self.getControl(req)) 
    234288 
    235289        return HtmlResource.getChild(self, path, req) 
    236290