OLD | NEW |
| (Empty) |
1 | |
2 import time, urllib | |
3 from twisted.python import log | |
4 from twisted.web import html | |
5 from twisted.web.util import Redirect | |
6 from twisted.web.error import NoResource | |
7 | |
8 from buildbot.status.web.base import HtmlResource, abbreviate_age, \ | |
9 OneLineMixin, path_to_slave, path_to_build | |
10 from buildbot import version, util | |
11 | |
12 # /buildslaves/$slavename | |
13 class OneBuildSlaveResource(HtmlResource, OneLineMixin): | |
14 addSlash = False | |
15 def __init__(self, slavename): | |
16 HtmlResource.__init__(self) | |
17 self.slavename = slavename | |
18 | |
19 def getTitle(self, req): | |
20 return "Buildbot: %s" % html.escape(self.slavename) | |
21 | |
22 def getChild(self, path, req): | |
23 s = self.getStatus(req) | |
24 slave = s.getSlave(self.slavename) | |
25 if path == "shutdown" and self.getControl(req): | |
26 slave.setGraceful(True) | |
27 return Redirect(path_to_slave(req, slave)) | |
28 | |
29 def build_line(self, build, req): | |
30 buildnum = build.getNumber() | |
31 buildurl = path_to_build(req, build) | |
32 data = '<a href="%(builderurl)s">%(builder_name)s</a>' % self.get_line_v
alues(req, build) | |
33 data += ' <a href="%s">#%d</a> ' % (buildurl, buildnum) | |
34 | |
35 when = build.getETA() | |
36 if when is not None: | |
37 when_time = time.strftime("%H:%M:%S", | |
38 time.localtime(time.time() + when)) | |
39 data += "ETA %ds (%s) " % (when, when_time) | |
40 step = build.getCurrentStep() | |
41 if step: | |
42 data += "[%s]" % step.getName() | |
43 else: | |
44 data += "[waiting for Lock]" | |
45 # TODO: is this necessarily the case? | |
46 | |
47 builder_control = self.getControl(req) | |
48 if builder_control is not None: | |
49 stopURL = path_to_build(req, build) + '/stop' | |
50 data += ''' | |
51 <form action="%s" class="command stopbuild" style="display:inline" method="post"
> | |
52 <input type="submit" value="Stop Build" /> | |
53 </form>''' % stopURL | |
54 return data | |
55 | |
56 def body(self, req): | |
57 s = self.getStatus(req) | |
58 slave = s.getSlave(self.slavename) | |
59 my_builders = [] | |
60 for bname in s.getBuilderNames(): | |
61 b = s.getBuilder(bname) | |
62 for bs in b.getSlaves(): | |
63 slavename = bs.getName() | |
64 if bs.getName() == self.slavename: | |
65 my_builders.append(b) | |
66 | |
67 # Current builds | |
68 current_builds = [] | |
69 for b in my_builders: | |
70 for cb in b.getCurrentBuilds(): | |
71 if cb.getSlavename() == self.slavename: | |
72 current_builds.append(cb) | |
73 | |
74 data = [] | |
75 | |
76 projectName = s.getProjectName() | |
77 | |
78 data.append("<a href=\"%s\">%s</a>\n" % (self.path_to_root(req), project
Name)) | |
79 | |
80 data.append("<h1>Build Slave: %s</h1>\n" % html.escape(self.slavename)) | |
81 | |
82 access_uri = slave.getAccessURI() | |
83 if access_uri: | |
84 data.append("<a href=\"%s\">Click to Access Slave</a>" % html.escape
(access_uri)) | |
85 | |
86 shutdown_url = req.childLink("shutdown") | |
87 | |
88 if not slave.isConnected(): | |
89 data.append("<h2>NOT CONNECTED</h2>\n") | |
90 elif self.getControl(req): | |
91 if not slave.getGraceful(): | |
92 data.append('''<form method="POST" action="%s"> | |
93 <input type="submit" value="Gracefully Shutdown"> | |
94 </form>''' % shutdown_url) | |
95 else: | |
96 data.append("Gracefully shutting down...\n") | |
97 | |
98 if current_builds: | |
99 data.append("<h2>Currently building:</h2>\n") | |
100 data.append("<ul>\n") | |
101 thisURL = "../../../" + path_to_slave(req, slave) | |
102 for build in current_builds: | |
103 data.append("<li>%s</li>\n" % self.build_line(build, req)) | |
104 data.append("</ul>\n") | |
105 | |
106 else: | |
107 data.append("<h2>no current builds</h2>\n") | |
108 | |
109 # Recent builds | |
110 data.append("<h2>Recent builds:</h2>\n") | |
111 data.append("<ul>\n") | |
112 n = 0 | |
113 try: | |
114 max_builds = int(req.args.get('numbuilds')[0]) | |
115 except: | |
116 max_builds = 10 | |
117 for build in s.generateFinishedBuilds(builders=[b.getName() for b in my_
builders]): | |
118 if build.getSlavename() == self.slavename: | |
119 n += 1 | |
120 data.append("<li>%s</li>\n" % self.make_line(req, build, True)) | |
121 if n > max_builds: | |
122 break | |
123 data.append("</ul>\n") | |
124 | |
125 data.append(self.footer(s, req)) | |
126 return "".join(data) | |
127 | |
128 # /buildslaves | |
129 class BuildSlavesResource(HtmlResource): | |
130 title = "BuildSlaves" | |
131 addSlash = True | |
132 | |
133 def body(self, req): | |
134 s = self.getStatus(req) | |
135 data = "" | |
136 data += "<h1>Build Slaves</h1>\n" | |
137 | |
138 used_by_builder = {} | |
139 for bname in s.getBuilderNames(): | |
140 b = s.getBuilder(bname) | |
141 for bs in b.getSlaves(): | |
142 slavename = bs.getName() | |
143 if slavename not in used_by_builder: | |
144 used_by_builder[slavename] = [] | |
145 used_by_builder[slavename].append(bname) | |
146 | |
147 data += "<ol>\n" | |
148 for name in util.naturalSort(s.getSlaveNames()): | |
149 slave = s.getSlave(name) | |
150 slave_status = s.botmaster.slaves[name].slave_status | |
151 isBusy = len(slave_status.getRunningBuilds()) | |
152 data += " <li><a href=\"%s\">%s</a>:\n" % (req.childLink(urllib.quot
e(name,'')), name) | |
153 data += " <ul>\n" | |
154 version = slave.getVersion() | |
155 data += "<li>Running Buildbot version: %s" % version | |
156 builder_links = ['<a href="%s">%s</a>' | |
157 % (req.childLink("../builders/%s" % bname),bname) | |
158 for bname in used_by_builder.get(name, [])] | |
159 if builder_links: | |
160 data += (" <li>Used by Builders: %s</li>\n" % | |
161 ", ".join(builder_links)) | |
162 else: | |
163 data += " <li>Not used by any Builders</li>\n" | |
164 if slave.isConnected(): | |
165 data += " <li>Slave is currently connected</li>\n" | |
166 admin = slave.getAdmin() | |
167 if admin: | |
168 # munge it to avoid feeding the spambot harvesters | |
169 admin = admin.replace("@", " -at- ") | |
170 data += " <li>Admin: %s</li>\n" % admin | |
171 last = slave.lastMessageReceived() | |
172 if last: | |
173 lt = time.strftime("%Y-%b-%d %H:%M:%S", | |
174 time.localtime(last)) | |
175 age = abbreviate_age(time.time() - last) | |
176 data += " <li>Last heard from: %s " % age | |
177 data += '<font size="-1">(%s)</font>' % lt | |
178 data += "</li>\n" | |
179 if isBusy: | |
180 data += "<li>Slave is currently building.</li>" | |
181 else: | |
182 data += "<li>Slave is idle.</li>" | |
183 else: | |
184 data += " <li><b>Slave is NOT currently connected</b></li>\n" | |
185 | |
186 data += " </ul>\n" | |
187 data += " </li>\n" | |
188 data += "\n" | |
189 | |
190 data += "</ol>\n" | |
191 | |
192 return data | |
193 | |
194 def getChild(self, path, req): | |
195 try: | |
196 slave = self.getStatus(req).getSlave(path) | |
197 return OneBuildSlaveResource(path) | |
198 except KeyError: | |
199 return NoResource("No such slave '%s'" % html.escape(path)) | |
OLD | NEW |