1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17  from twisted.web import html 
 18  from twisted.web.util import Redirect, DeferredResource 
 19  from twisted.internet import defer, reactor 
 20   
 21  import urllib, time 
 22  from twisted.python import log 
 23  from buildbot.status.web.base import HtmlResource, \ 
 24       css_classes, path_to_build, path_to_builder, path_to_slave, \ 
 25       getAndCheckProperties, path_to_authfail 
 26   
 27  from buildbot.status.web.step import StepsResource 
 28  from buildbot.status.web.tests import TestsResource 
 29  from buildbot import util, interfaces 
 30   
 31   
 32   
 33   
 35      addSlash = True 
 36   
 40   
 41 -    def getPageTitle(self, request): 
  42          return ("Buildbot: %s Build #%d" % 
 43                  (self.build_status.getBuilder().getName(), 
 44                   self.build_status.getNumber())) 
  45   
 46 -    def content(self, req, cxt): 
  47          b = self.build_status 
 48          status = self.getStatus(req) 
 49          req.setHeader('Cache-Control', 'no-cache') 
 50   
 51          cxt['b'] = b 
 52          cxt['path_to_builder'] = path_to_builder(req, b.getBuilder()) 
 53   
 54          if not b.isFinished(): 
 55              step = b.getCurrentStep() 
 56              if not step: 
 57                  cxt['current_step'] = "[waiting for Lock]" 
 58              else: 
 59                  if step.isWaitingForLocks(): 
 60                      cxt['current_step'] = "%s [waiting for Lock]" % step.getName() 
 61                  else: 
 62                      cxt['current_step'] = step.getName() 
 63              when = b.getETA() 
 64              if when is not None: 
 65                  cxt['when'] = util.formatInterval(when) 
 66                  cxt['when_time'] = time.strftime("%H:%M:%S", 
 67                                                  time.localtime(time.time() + when)) 
 68   
 69          else: 
 70              cxt['result_css'] = css_classes[b.getResults()] 
 71              if b.getTestResults(): 
 72                  cxt['tests_link'] = req.childLink("tests") 
 73   
 74          ss = cxt['ss'] = b.getSourceStamp() 
 75   
 76          if ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes: 
 77              cxt['most_recent_rev_build'] = True 
 78   
 79   
 80          got_revision = None 
 81          try: 
 82              got_revision = b.getProperty("got_revision") 
 83          except KeyError: 
 84              pass 
 85          if got_revision: 
 86              cxt['got_revision'] = str(got_revision) 
 87   
 88          try: 
 89              cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename())) 
 90          except KeyError: 
 91              pass 
 92   
 93          cxt['steps'] = [] 
 94   
 95          for s in b.getSteps(): 
 96              step = {'name': s.getName() } 
 97              cxt['steps'].append(step) 
 98   
 99              if s.isFinished(): 
100                  step['css_class'] = css_classes[s.getResults()[0]] 
101                  (start, end) = s.getTimes() 
102                  step['time_to_run'] = util.formatInterval(end - start) 
103              elif s.isStarted(): 
104                  if s.isWaitingForLocks(): 
105                      step['css_class'] = "waiting" 
106                      step['time_to_run'] = "waiting for locks" 
107                  else: 
108                      step['css_class'] = "running" 
109                      step['time_to_run'] = "running" 
110              else: 
111                  step['css_class'] = "not_started" 
112                  step['time_to_run'] = "" 
113   
114              step['link'] = req.childLink("steps/%s" % urllib.quote(s.getName())) 
115              step['text'] = " ".join(s.getText()) 
116              step['urls'] = map(lambda x:dict(url=x[1],logname=x[0]), s.getURLs().items()) 
117   
118              step['logs']= [] 
119              for l in s.getLogs(): 
120                  logname = l.getName() 
121                  step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" % 
122                                             (urllib.quote(s.getName()), 
123                                              urllib.quote(logname))),  
124                                        'name': logname }) 
125   
126          ps = cxt['properties'] = [] 
127          for name, value, source in b.getProperties().asList(): 
128              value = unicode(value) 
129              p = { 'name': name, 'value': value, 'source': source}             
130              if len(value) > 500: 
131                  p['short_value'] = value[:500] 
132   
133              ps.append(p) 
134   
135           
136          cxt['responsible_users'] = list(b.getResponsibleUsers()) 
137   
138          (start, end) = b.getTimes() 
139          cxt['start'] = time.ctime(start) 
140          if end: 
141              cxt['end'] = time.ctime(end) 
142              cxt['elapsed'] = util.formatInterval(end - start) 
143          else: 
144              now = util.now() 
145              cxt['elapsed'] = util.formatInterval(now - start) 
146               
147          cxt['exactly'] = (ss.revision is not None) or b.getChanges() 
148   
149          cxt['build_url'] = path_to_build(req, b) 
150          cxt['authz'] = self.getAuthz(req) 
151   
152          template = req.site.buildbot_service.templates.get_template("build.html") 
153          return template.render(**cxt) 
 154   
155 -    def stop(self, req, auth_ok=False): 
 183   
185           
186          if not self.getAuthz(req).actionAllowed('forceBuild', req, self.build_status.getBuilder()): 
187              return Redirect(path_to_authfail(req)) 
188   
189           
190          c = interfaces.IControl(self.getBuildmaster(req)) 
191          bc = c.getBuilder(self.build_status.getBuilder().getName()) 
192   
193          b = self.build_status 
194          builder_name = b.getBuilder().getName() 
195          log.msg("web rebuild of build %s:%s" % (builder_name, b.getNumber())) 
196          name = req.args.get("username", ["<unknown>"])[0] 
197          comments = req.args.get("comments", ["<no reason specified>"])[0] 
198          reason = ("The web-page 'rebuild' button was pressed by " 
199                    "'%s': %s\n" % (name, comments)) 
200          extraProperties = getAndCheckProperties(req) 
201          if not bc or not b.isFinished() or extraProperties is None: 
202              log.msg("could not rebuild: bc=%s, isFinished=%s" 
203                      % (bc, b.isFinished())) 
204               
205          else: 
206              d = bc.rebuildBuild(b, reason, extraProperties) 
207              d.addErrback(log.err, "while rebuilding a build") 
208           
209           
210           
211           
212           
213           
214           
215           
216           
217           
218   
219          r = Redirect(path_to_builder(req, self.build_status.getBuilder())) 
220          d = defer.Deferred() 
221          reactor.callLater(1, d.callback, r) 
222          return DeferredResource(d) 
 223   
 235   
236   
238      addSlash = True 
239   
243   
244 -    def content(self, req, cxt): 
 245          return "subpages shows data for each build" 
 246   
 258