1
2 from twisted.web import html
3 from twisted.web.util import Redirect
4
5 import re, urllib, time
6 from twisted.python import log
7 from buildbot import interfaces
8 from buildbot.status.web.base import HtmlResource, BuildLineMixin, \
9 path_to_build, path_to_slave, path_to_builder, path_to_change, \
10 path_to_root, getAndCheckProperties, ICurrentBox, build_get_class, \
11 map_branches, path_to_authfail
12 from buildbot.sourcestamp import SourceStamp
13
14 from buildbot.status.web.build import BuildsResource, StatusResourceBuild
15 from buildbot import util
16
17
19 addSlash = True
20
24
26 return "Buildbot: %s" % self.builder_status.getName()
27
50
51 - def content(self, req, cxt):
52 b = self.builder_status
53
54 cxt['name'] = b.getName()
55
56 slaves = b.getSlaves()
57 connected_slaves = [s for s in slaves if s.isConnected()]
58
59 cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()]
60
61 cxt['pending'] = []
62 for pb in b.getPendingBuilds():
63 source = pb.getSourceStamp()
64 changes = []
65
66 if source.changes:
67 for c in source.changes:
68 changes.append({ 'url' : path_to_change(req, c),
69 'who' : c.who})
70 if source.revision:
71 reason = source.revision
72 else:
73 reason = "no changes specified"
74
75 cxt['pending'].append({
76 'when': time.strftime("%b %d %H:%M:%S", time.localtime(pb.getSubmitTime())),
77 'delay': util.formatInterval(util.now() - pb.getSubmitTime()),
78 'reason': reason,
79 'id': pb.brid,
80 'changes' : changes
81 })
82
83 numbuilds = int(req.args.get('numbuilds', ['5'])[0])
84 recent = cxt['recent'] = []
85 for build in b.generateFinishedBuilds(num_builds=int(numbuilds)):
86 recent.append(self.get_line_values(req, build, False))
87
88 sl = cxt['slaves'] = []
89 connected_slaves = 0
90 for slave in slaves:
91 s = {}
92 sl.append(s)
93 s['link'] = path_to_slave(req, slave)
94 s['name'] = slave.getName()
95 c = s['connected'] = slave.isConnected()
96 if c:
97 s['admin'] = slave.getAdmin()
98 connected_slaves += 1
99 cxt['connected_slaves'] = connected_slaves
100
101 cxt['authz'] = self.getAuthz(req)
102 cxt['builder_url'] = path_to_builder(req, b)
103
104 template = req.site.buildbot_service.templates.get_template("builder.html")
105 return template.render(**cxt)
106
107 - def force(self, req, auth_ok=False):
108 name = req.args.get("username", ["<unknown>"])[0]
109 reason = req.args.get("comments", ["<no reason specified>"])[0]
110 branch = req.args.get("branch", [""])[0]
111 revision = req.args.get("revision", [""])[0]
112
113 r = "The web-page 'force build' button was pressed by '%s': %s\n" \
114 % (html.escape(name), html.escape(reason))
115 log.msg("web forcebuild of builder '%s', branch='%s', revision='%s'"
116 " by user '%s'" % (self.builder_status.getName(), branch,
117 revision, name))
118
119
120 if not auth_ok:
121 if not self.getAuthz(req).actionAllowed('forceBuild', req, self.builder_status):
122 log.msg("..but not authorized")
123 return Redirect(path_to_authfail(req))
124
125
126
127 if not re.match(r'^[\w\.\-\/]*$', branch):
128 log.msg("bad branch '%s'" % branch)
129 return Redirect(path_to_builder(req, self.builder_status))
130 if not re.match(r'^[\w\.\-\/]*$', revision):
131 log.msg("bad revision '%s'" % revision)
132 return Redirect(path_to_builder(req, self.builder_status))
133 properties = getAndCheckProperties(req)
134 if properties is None:
135 return Redirect(path_to_builder(req, self.builder_status))
136 if not branch:
137 branch = None
138 if not revision:
139 revision = None
140
141
142
143
144
145
146
147
148 s = SourceStamp(branch=branch, revision=revision)
149 try:
150 c = interfaces.IControl(self.getBuildmaster(req))
151 bc = c.getBuilder(self.builder_status.getName())
152 bc.submitBuildRequest(s, r, properties, now=True)
153 except interfaces.NoSlaveError:
154
155
156 pass
157
158 return Redirect(path_to_builder(req, self.builder_status))
159
160 - def ping(self, req):
170
172 try:
173 request_id = req.args.get("id", [None])[0]
174 if request_id == "all":
175 cancel_all = True
176 else:
177 cancel_all = False
178 request_id = int(request_id)
179 except:
180 request_id = None
181
182 authz = self.getAuthz(req)
183 if request_id:
184 c = interfaces.IControl(self.getBuildmaster(req))
185 bc = c.getBuilder(self.builder_status.getName())
186 for build_req in bc.getPendingBuilds():
187 if cancel_all or (build_req.brid == request_id):
188 log.msg("Cancelling %s" % build_req)
189 if authz.actionAllowed('cancelPendingBuild', req, build_req):
190 build_req.cancel()
191 else:
192 return Redirect(path_to_authfail(req))
193 if not cancel_all:
194 break
195 return Redirect(path_to_builder(req, self.builder_status))
196
208
209
210
255
256
257
259 title = "Builders"
260 addSlash = True
261
262 - def content(self, req, cxt):
263 status = self.getStatus(req)
264
265 builders = req.args.get("builder", status.getBuilderNames())
266 branches = [b for b in req.args.get("branch", []) if b]
267
268 cxt['branches'] = branches
269 bs = cxt['builders'] = []
270
271 building = 0
272 online = 0
273 base_builders_url = path_to_root(req) + "builders/"
274 for bn in builders:
275 bld = { 'link': base_builders_url + urllib.quote(bn, safe=''),
276 'name': bn }
277 bs.append(bld)
278
279 builder = status.getBuilder(bn)
280 builds = list(builder.generateFinishedBuilds(map_branches(branches),
281 num_builds=1))
282 if builds:
283 b = builds[0]
284 bld['build_url'] = (bld['link'] + "/builds/%d" % b.getNumber())
285 try:
286 label = b.getProperty("got_revision")
287 except KeyError:
288 label = None
289 if not label or len(str(label)) > 20:
290 label = "#%d" % b.getNumber()
291
292 bld['build_label'] = label
293 bld['build_text'] = " ".join(b.getText())
294 bld['build_css_class'] = build_get_class(b)
295
296 current_box = ICurrentBox(builder).getBox(status)
297 bld['current_box'] = current_box.td()
298
299 builder_status = builder.getState()[0]
300 if builder_status == "building":
301 building += 1
302 online += 1
303 elif builder_status != "offline":
304 online += 1
305
306 cxt['authz'] = self.getAuthz(req)
307 cxt['num_building'] = building
308 cxt['num_online'] = online
309
310 template = req.site.buildbot_service.templates.get_template("builders.html")
311 return template.render(**cxt)
312
322