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
14 addSlash = False
18
21
28
30 buildnum = build.getNumber()
31 buildurl = path_to_build(req, build)
32 data = '<a href="%(builderurl)s">%(builder_name)s</a>' % self.get_line_values(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
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
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), projectName))
79
80 data.append("<h1>Build Slave: %s</h1>\n" % self.slavename)
81
82 shutdown_url = req.childLink("shutdown")
83
84 if not slave.isConnected():
85 data.append("<h2>NOT CONNECTED</h2>\n")
86 elif self.getControl(req):
87 if not slave.getGraceful():
88 data.append('''<form method="POST" action="%s">
89 <input type="submit" value="Gracefully Shutdown">
90 </form>''' % shutdown_url)
91 else:
92 data.append("Gracefully shutting down...\n")
93
94 if current_builds:
95 data.append("<h2>Currently building:</h2>\n")
96 data.append("<ul>\n")
97 thisURL = "../../../" + path_to_slave(req, slave)
98 for build in current_builds:
99 data.append("<li>%s</li>\n" % self.build_line(build, req))
100 data.append("</ul>\n")
101
102 else:
103 data.append("<h2>no current builds</h2>\n")
104
105
106 data.append("<h2>Recent builds:</h2>\n")
107 data.append("<ul>\n")
108 n = 0
109 try:
110 max_builds = int(req.args.get('numbuilds')[0])
111 except:
112 max_builds = 10
113 for build in s.generateFinishedBuilds(builders=[b.getName() for b in my_builders]):
114 if build.getSlavename() == self.slavename:
115 n += 1
116 data.append("<li>%s</li>\n" % self.make_line(req, build, True))
117 if n > max_builds:
118 break
119 data.append("</ul>\n")
120
121 projectURL = s.getProjectURL()
122 projectName = s.getProjectName()
123 data.append('<hr /><div class="footer">\n')
124
125 welcomeurl = self.path_to_root(req) + "index.html"
126 data.append("[<a href=\"%s\">welcome</a>]\n" % welcomeurl)
127 data.append("<br />\n")
128
129 data.append('<a href="http://buildbot.sourceforge.net/">Buildbot</a>')
130 data.append("-%s " % version)
131 if projectName:
132 data.append("working for the ")
133 if projectURL:
134 data.append("<a href=\"%s\">%s</a> project." % (projectURL,
135 projectName))
136 else:
137 data.append("%s project." % projectName)
138 data.append("<br />\n")
139 data.append("Page built: " +
140 time.strftime("%a %d %b %Y %H:%M:%S",
141 time.localtime(util.now()))
142 + "\n")
143 data.append("</div>\n")
144
145 return "".join(data)
146
147
149 title = "BuildSlaves"
150 addSlash = True
151
152 - def body(self, req):
153 s = self.getStatus(req)
154 data = ""
155 data += "<h1>Build Slaves</h1>\n"
156
157 used_by_builder = {}
158 for bname in s.getBuilderNames():
159 b = s.getBuilder(bname)
160 for bs in b.getSlaves():
161 slavename = bs.getName()
162 if slavename not in used_by_builder:
163 used_by_builder[slavename] = []
164 used_by_builder[slavename].append(bname)
165
166 data += "<ol>\n"
167 for name in util.naturalSort(s.getSlaveNames()):
168 slave = s.getSlave(name)
169 slave_status = s.botmaster.slaves[name].slave_status
170 isBusy = len(slave_status.getRunningBuilds())
171 data += " <li><a href=\"%s\">%s</a>:\n" % (req.childLink(urllib.quote(name,'')), name)
172 data += " <ul>\n"
173 builder_links = ['<a href="%s">%s</a>'
174 % (req.childLink("../builders/%s" % bname),bname)
175 for bname in used_by_builder.get(name, [])]
176 if builder_links:
177 data += (" <li>Used by Builders: %s</li>\n" %
178 ", ".join(builder_links))
179 else:
180 data += " <li>Not used by any Builders</li>\n"
181 if slave.isConnected():
182 data += " <li>Slave is currently connected</li>\n"
183 admin = slave.getAdmin()
184 if admin:
185
186 admin = admin.replace("@", " -at- ")
187 data += " <li>Admin: %s</li>\n" % admin
188 last = slave.lastMessageReceived()
189 if last:
190 lt = time.strftime("%Y-%b-%d %H:%M:%S",
191 time.localtime(last))
192 age = abbreviate_age(time.time() - last)
193 data += " <li>Last heard from: %s " % age
194 data += '<font size="-1">(%s)</font>' % lt
195 data += "</li>\n"
196 if isBusy:
197 data += "<li>Slave is currently building.</li>"
198 else:
199 data += "<li>Slave is idle.</li>"
200 else:
201 data += " <li><b>Slave is NOT currently connected</b></li>\n"
202
203 data += " </ul>\n"
204 data += " </li>\n"
205 data += "\n"
206
207 data += "</ol>\n"
208
209 return data
210
217