1 # Integration with the oestats build statistics server, see:
3 # http://opensource.bolloretelecom.eu/projects/oestats
5 # To make use of this class, add to your local.conf:
7 # INHERIT += "oestats-client"
8 # OESTATS_SERVER = "http://some.server.org"
9 # OESTATS_BUILDER = "some_nickname"
12 def oestats_setid(d, val):
15 f = open(os.path.join(bb.data.getVar('TMPDIR', d, True), 'oestats.id'), 'w')
20 f = file(bb.data.getVar('TMPDIR', d, True) + '/oestats.id', 'r')
25 exctype, value = sys.exc_info()[:2]
26 return "exception " + str(exctype) + ", value " + str(value)
28 def oestats_send(d, server, action, vars = {}, files = {}):
34 bound = '----------ThIs_Is_tHe_bouNdaRY_$'
36 output.append('--' + bound)
37 output.append('Content-Disposition: form-data; name="%s"' % key)
39 output.append(vars[key])
41 if not files[key]: continue
42 if not files[key]['content']: continue
43 output.append('--' + bound)
44 output.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, files[key]['filename']))
45 output.append('Content-Type: %s' % files[key]['content-type'])
48 output.append(files[key]['content'])
49 output.append('--' + bound + '--')
51 body = "\r\n".join(output)
55 "User-agent": "oestats-client/0.5",
56 "Content-type": "multipart/form-data; boundary=%s" % bound,
57 "Content-length": str(len(body))}
59 proxy = bb.data.getVar('HTTP_PROXY', d, True )
61 phl = urllib2.ProxyHandler({'http' : proxy})
62 opener = urllib2.build_opener(phl)
63 urllib2.install_opener(opener)
65 actionURL = "%s%s" %(server, action)
66 req = urllib2.Request(actionURL, body, headers);
67 response = urllib2.urlopen(req)
68 data = response.read()
72 def oestats_start(server, builder, d):
80 data = oestats_send(d, server, "/builds/", {
82 'build_arch': bb.data.getVar('BUILD_ARCH', d, True),
83 'metadata_branch': bb.data.getVar('METADATA_BRANCH', d, True),
84 'metadata_revision': bb.data.getVar('METADATA_REVISION', d, True),
85 'machine': bb.data.getVar('MACHINE', d, True),
86 'distro': bb.data.getVar('USERDISTRO', d, True),
88 if re.match("^\d+$", data): id=data
90 bb.warn("oestats: %s" % get_exc_info())
95 bb.note("oestats: build %s" % id)
97 bb.warn("oestats: error starting build, disabling stats")
100 def oestats_stop(server, d, failures):
104 id = oestats_getid(d)
114 response = oestats_send(d, server, "/builds/%s/" % id, {
117 if status == 'Failed':
118 bb.warn("oestats: build failed, see %s%s" % (server, response))
120 bb.warn("oestats: error stopping build (%s)" % get_exc_info())
122 def oestats_task(server, d, task, status):
129 id = oestats_getid(d)
132 # calculate build time
134 elapsed = time.time() - float(bb.data.getVar('OESTATS_STAMP', d, True))
140 if status == 'Failed':
141 logs = glob.glob("%s/log.%s.*" % (bb.data.getVar('T', d, True), task))
145 'filename': 'log.txt',
146 'content': file(log).read(),
147 'content-type': 'text/plain'}
148 if task == 'do_package':
149 qalog = "%s/log.qa_package" % bb.data.getVar('T', d, True)
150 if os.path.exists(qalog):
152 'filename': 'qalog.txt',
153 'content': file(qalog).read(),
154 'content-type': 'text/plain'}
159 'package': bb.data.getVar('PN', d, True),
160 'version': bb.data.getVar('PV', d, True),
161 'revision': bb.data.getVar('PR', d, True),
162 'depends': bb.data.getVar('DEPENDS', d, True),
165 'time': str(elapsed)}
166 bug_number = bb.data.getVar('OESTATS_BUG_NUMBER', d, True)
167 bug_tracker = bb.data.getVar('OESTATS_BUG_TRACKER', d, True)
168 if bug_number and bug_tracker:
169 vars['bug_number'] = bug_number
170 vars['bug_tracker'] = bug_tracker
173 # FIXME: resend on http/url error?
175 response = oestats_send(d, server, "/tasks/", vars, files)
176 if status == 'Failed':
177 bb.warn("oestats: task failed, see %s%s" % (server, response))
179 bb.warn("oestats: error sending task (%s), disabling stats" % get_exc_info())
182 addhandler oestats_eventhandler
183 python oestats_eventhandler () {
184 from bb.event import getName
188 if e.data is None or getName(e) == "MsgNote":
191 server = bb.data.getVar('OESTATS_SERVER', e.data, True)
192 builder = bb.data.getVar('OESTATS_BUILDER', e.data, True)
193 if not server or not builder:
196 if not server.startswith('http://') and not server.startswith('https://'):
197 server = "http://%s" %(server)
199 if getName(e) == 'BuildStarted':
200 oestats_start(server, builder, e.data)
201 elif getName(e) == 'BuildCompleted':
202 oestats_stop(server, e.data, e.getFailures())
203 elif getName(e) == 'TaskStarted':
204 bb.data.setVar('OESTATS_STAMP', repr(time.time()), e.data)
205 elif getName(e) == 'TaskSucceeded':
206 oestats_task(server, e.data, e.task, 'Succeeded')
207 elif getName(e) == 'TaskFailed':
208 oestats_task(server, e.data, e.task, 'Failed')