# To make use of this class, add to your local.conf:
#
# INHERIT += "oestats-client"
-# OESTATS_SERVER = "some.server.org:8000"
-# OESTATS_BUILDER = "some title"
+# OESTATS_SERVER = "some.server.org"
+# OESTATS_BUILDER = "some_nickname"
-def oestats_revision(dir):
- import re
- try:
- f = file("%s/_MTN/revision" % dir)
- m = re.search(r"old_revision \[(.*)\]", f.read())
- return m.group(1)
- except:
- return
+def oestats_setid(d, val):
+ import bb
+ f = file(bb.data.getVar('TMPDIR', d, True) + '/oestats.id', 'w')
+ f.write(val)
-def oestats_send(server, action, vars = {}):
- import httplib, urllib
+def oestats_getid(d):
+ import bb
+ f = file(bb.data.getVar('TMPDIR', d, True) + '/oestats.id', 'r')
+ return f.read()
+
+def oestats_send(d, server, action, vars = {}, files = {}):
+ import httplib
+ import bb
- params = urllib.urlencode(vars)
- headers = {"Content-type": "application/x-www-form-urlencoded",
- "Accept": "text/plain"}
- conn = httplib.HTTPConnection(server)
- conn.request("POST", action, params, headers)
+ # build body
+ output = []
+ bound = '----------ThIs_Is_tHe_bouNdaRY_$'
+ for key in vars:
+ assert vars[key]
+ output.append('--' + bound)
+ output.append('Content-Disposition: form-data; name="%s"' % key)
+ output.append('')
+ output.append(vars[key])
+ for key in files:
+ assert files[key]
+ output.append('--' + bound)
+ output.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, files[key]['filename']))
+ output.append('Content-Type: %s' % files[key]['content-type'])
+
+ output.append('')
+ output.append(files[key]['content'])
+ output.append('--' + bound + '--')
+ output.append('')
+ body = "\r\n".join(output)
+
+ # build headers
+ headers = {
+ "User-agent": "oestats-client/0.5",
+ "Content-type": "multipart/form-data; boundary=%s" % bound,
+ "Content-length": str(len(body))}
+
+ # send request
+ proxy = bb.data.getVar('HTTP_PROXY', d, True )
+ if (proxy):
+ if (proxy.endswith('/')):
+ proxy = proxy[:-1]
+ if (proxy.startswith('http://')):
+ proxy = proxy[7:]
+ conn = httplib.HTTPConnection(proxy)
+ action = "http://%s%s" %(server, action)
+ else:
+ conn = httplib.HTTPConnection(server)
+ conn.request("POST", action, body, headers)
response = conn.getresponse()
+ data = response.read()
conn.close()
- return response
+ return data
def oestats_start(server, builder, d):
import bb
import os.path
-
- # collect information about revisions
- path_bb = bb.data.getVar('BBPATH', d, 1)
- for p in (path_bb or "").split(':'):
- revision = oestats_revision(p)
- if revision:
- break
+ import re
# send report
- response = oestats_send(server, "/builds/start/", {
- 'builder': builder,
- 'revision': revision,
- 'machine': bb.data.getVar( 'MACHINE', d, True ),
- 'distro': bb.data.getVar( 'DISTRO', d, True ),
- })
- id = response.read()
+ id = ""
+ try:
+ data = oestats_send(d, server, "/builds/", {
+ 'builder': builder,
+ 'build_arch': bb.data.getVar('BUILD_ARCH', d, True),
+ 'metadata_branch': bb.data.getVar('METADATA_BRANCH', d, True),
+ 'metadata_revision': bb.data.getVar('METADATA_REVISION', d, True),
+ 'machine': bb.data.getVar('MACHINE', d, True),
+ 'distro': bb.data.getVar('DISTRO', d, True),
+ })
+ if re.match("^\d+$", data): id=data
+ except:
+ pass
# save the build id
- bb.note("Stats id: %s" % id)
- f = file(bb.data.getVar('TMPDIR', d, True)+"/oestats.id", 'w')
- f.write(id)
+ if id:
+ bb.note("oestats: build %s" % id)
+ else:
+ bb.note("oestats: error starting build, disabling stats")
+ oestats_setid(d, id)
-def oestats_stop(server, d, status):
+def oestats_stop(server, d, failures):
import bb
# retrieve build id
- f = file(bb.data.getVar('TMPDIR',d,True)+"/oestats.id", 'r')
- id = f.read()
+ id = oestats_getid(d)
+ if not id: return
# send report
- response = oestats_send(server, "/builds/stop/%s/" % id, {
- 'status': status,
- })
+ if failures > 0:
+ status = "Failed"
+ else:
+ status = "Succeeded"
+
+ try:
+ response = oestats_send(d, server, "/builds/%s/" % id, {
+ 'status': status,
+ })
+ if status == 'Failed':
+ bb.note("oestats: build failed, see http://%s%s" % (server,response))
+ except:
+ bb.note("oestats: error stopping build")
def oestats_task(server, d, task, status):
import bb
+ import glob
+ import os.path
+ import time
# retrieve build id
- f = file(bb.data.getVar('TMPDIR',d,True)+"/oestats.id", 'r')
- id = f.read()
+ id = oestats_getid(d)
+ if not id: return
- # send report
- response = oestats_send(server, "/builds/task/%s/" % id, {
+ # calculate build time
+ try:
+ elapsed = time.time() - float(bb.data.getVar('OESTATS_STAMP', d, True))
+ except:
+ elapsed = 0
+
+ # prepare files
+ files = {}
+ if status == 'Failed':
+ logs = glob.glob("%s/log.%s.*" % (bb.data.getVar('T', d, True), task))
+ if len(logs) > 0:
+ log = logs[0]
+ files['log'] = {
+ 'filename': 'log.txt',
+ 'content': file(log).read(),
+ 'content-type': 'text/plain'}
+ if task == 'do_package':
+ qalog = "%s/log.qa_package" % bb.data.getVar('T', d, True)
+ if os.path.exists(qalog):
+ files['qalog'] = {
+ 'filename': 'qalog.txt',
+ 'content': file(qalog).read(),
+ 'content-type': 'text/plain'}
+
+ # prepare report
+ vars = {
+ 'build': id,
'package': bb.data.getVar('PN', d, True),
'version': bb.data.getVar('PV', d, True),
'revision': bb.data.getVar('PR', d, True),
+ 'depends': bb.data.getVar('DEPENDS', d, True),
'task': task,
'status': status,
- })
+ 'time': str(elapsed)}
+ bug_number = bb.data.getVar('OESTATS_BUG_NUMBER', d, True)
+ bug_tracker = bb.data.getVar('OESTATS_BUG_TRACKER', d, True)
+ if bug_number and bug_tracker:
+ vars['bug_number'] = bug_number
+ vars['bug_tracker'] = bug_tracker
+
+ # send report
+ try:
+ response = oestats_send(d, server, "/tasks/", vars, files)
+ if status == 'Failed':
+ bb.note("oestats: task failed, see http://%s%s" % (server, response))
+ except:
+ bb.note("oestats: error sending task, disabling stats")
+ oestats_setid(d, "")
addhandler oestats_eventhandler
python oestats_eventhandler () {
from bb.event import getName
import bb
+ import time
if e.data is None or getName(e) == "MsgNote":
return NotHandled
if getName(e) == 'BuildStarted':
oestats_start(server, builder, e.data)
elif getName(e) == 'BuildCompleted':
- oestats_stop(server, e.data, 'Completed')
+ oestats_stop(server, e.data, e.getFailures())
+ elif getName(e) == 'TaskStarted':
+ bb.data.setVar('OESTATS_STAMP', repr(time.time()), e.data)
elif getName(e) == 'TaskSucceeded':
oestats_task(server, e.data, e.task, 'Succeeded')
elif getName(e) == 'TaskFailed':