merge of '518cab8ae2535562912ff7f5fdba8458448a0e18'
[vuplus_openembedded] / classes / oestats-client.bbclass
1 # Integration with the oestats build statistics server, see:
2 #
3 # http://opensource.bolloretelecom.eu/projects/oestats
4 #
5 # To make use of this class, add to your local.conf:
6 #
7 # INHERIT += "oestats-client"
8 # OESTATS_SERVER = "some.server.org:8000"
9 # OESTATS_BUILDER = "some_nickname"
10
11 def oestats_setid(d, val):
12         import bb
13         f = file(bb.data.getVar('TMPDIR', d, True) + '/oestats.id', 'w')
14         f.write(val)
15
16 def oestats_getid(d):
17         import bb
18         f = file(bb.data.getVar('TMPDIR', d, True) + '/oestats.id', 'r')
19         return f.read()
20         
21 def oestats_send(server, action, vars = {}, files = {}):
22         import httplib
23
24         # build body
25         output = []
26         bound = '----------ThIs_Is_tHe_bouNdaRY_$'
27         for key in vars:
28                 assert vars[key]
29                 output.append('--' + bound)
30                 output.append('Content-Disposition: form-data; name="%s"' % key)
31                 output.append('')
32                 output.append(vars[key])
33         for key in files:
34                 assert files[key]
35                 output.append('--' + bound)
36                 output.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, files[key]['filename']))
37                 output.append('Content-Type: %s' % files[key]['content-type'])
38                 
39                 output.append('')
40                 output.append(files[key]['content'])
41         output.append('--' + bound + '--')
42         output.append('')
43         body = "\r\n".join(output)
44
45         # build headers
46         headers = {
47                 "User-agent": "oestats-client/0.1",
48                 "Content-type": "multipart/form-data; boundary=%s" % bound,
49                 "Content-length": str(len(body))}
50
51         # send request
52         conn = httplib.HTTPConnection(server)
53         conn.request("POST", action, body, headers)
54         response = conn.getresponse()
55         data = response.read()
56         conn.close()
57         return data
58
59 def oestats_start(server, builder, d):
60         import bb
61         import os.path
62         import re
63
64         # send report
65         id = ""
66         try:
67                 data = oestats_send(server, "/builds/start/", {
68                         'builder': builder,
69                         'revision': bb.data.getVar('METADATA_REVISION', d, True),
70                         'machine': bb.data.getVar('MACHINE', d, True),
71                         'distro': bb.data.getVar('DISTRO', d, True),
72                 })
73                 if re.match("^\d+$", data): id=data
74         except:
75                 pass
76
77         # save the build id
78         if id:
79                 bb.note("oestats: build %s" % id)
80         else:
81                 bb.note("oestats: error starting build, disabling stats")
82         oestats_setid(d, id)
83
84 def oestats_stop(server, d, status):
85         import bb
86
87         # retrieve build id
88         id = oestats_getid(d)
89         if not id: return
90
91         # send report
92         try:
93                 response = oestats_send(server, "/builds/stop/%s/" % id, {
94                         'status': status,
95                 })
96         except:
97                 bb.note("oestats: error stopping build")
98
99 def oestats_task(server, d, task, status):
100         import bb
101         import glob
102         import time
103
104         # retrieve build id
105         id = oestats_getid(d)
106         if not id: return
107
108         # calculate build time
109         try:
110                 elapsed = time.time() - float(bb.data.getVar('OESTATS_STAMP', d, True))
111         except:
112                 elapsed = 0
113         
114         # send the log for failures
115         files = {}
116         if status == 'Failed':
117                 logs = glob.glob("%s/log.%s.*" % (bb.data.getVar('T', d, True), task))
118                 if len(logs) > 0:
119                         log = logs[0]
120                         bb.note("oestats: sending log file : %s" % log)
121                         files['log'] = {
122                                 'filename': 'log.txt',
123                                 'content': file(log).read(),
124                                 'content-type': 'text/plain'}
125         
126         # send report
127         try:
128                 response = oestats_send(server, "/builds/task/%s/" % id, {
129                         'package': bb.data.getVar('PN', d, True),
130                         'version': bb.data.getVar('PV', d, True),
131                         'revision': bb.data.getVar('PR', d, True),
132                         'task': task,
133                         'status': status,
134                         'time': str(elapsed),
135                 }, files)
136         except:
137                 bb.note("oestats: error sending task, disabling stats")
138                 oestats_setid(d, "")
139
140 addhandler oestats_eventhandler
141 python oestats_eventhandler () {
142         from bb.event import getName
143         import bb
144         import time
145
146         if e.data is None or getName(e) == "MsgNote":
147                 return NotHandled
148
149         server = bb.data.getVar('OESTATS_SERVER', e.data, True)
150         builder = bb.data.getVar('OESTATS_BUILDER', e.data, True)
151         if not server or not builder:
152                 return NotHandled
153
154         if getName(e) == 'BuildStarted':
155                 oestats_start(server, builder, e.data)
156         elif getName(e) == 'BuildCompleted':
157                 oestats_stop(server, e.data, 'Completed')
158         elif getName(e) == 'TaskStarted':
159                 bb.data.setVar('OESTATS_STAMP', repr(time.time()), e.data)
160         elif getName(e) == 'TaskSucceeded':
161                 oestats_task(server, e.data, e.task, 'Succeeded')
162         elif getName(e) == 'TaskFailed':
163                 oestats_task(server, e.data, e.task, 'Failed')
164
165         return NotHandled
166 }