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