diff options
author | Richard Purdie <richard@openedhand.com> | 2006-07-21 10:10:31 +0000 |
---|---|---|
committer | Richard Purdie <richard@openedhand.com> | 2006-07-21 10:10:31 +0000 |
commit | b2f192faabe412adce79534e22efe9fb69ee40e2 (patch) | |
tree | 7076c49d4286f8a1733650bd8fbc7161af200d57 /meta/classes/tinderclient.bbclass | |
parent | 2cf0eadf9f730027833af802d7e6c90b44248f80 (diff) | |
download | poky-b2f192faabe412adce79534e22efe9fb69ee40e2.tar.gz |
Rename /openembedded/ -> /meta/
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@530 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'meta/classes/tinderclient.bbclass')
-rw-r--r-- | meta/classes/tinderclient.bbclass | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/meta/classes/tinderclient.bbclass b/meta/classes/tinderclient.bbclass new file mode 100644 index 0000000000..6e10d0f34b --- /dev/null +++ b/meta/classes/tinderclient.bbclass | |||
@@ -0,0 +1,332 @@ | |||
1 | def tinder_http_post(server, selector, content_type, body): | ||
2 | import httplib | ||
3 | # now post it | ||
4 | for i in range(0,5): | ||
5 | try: | ||
6 | h = httplib.HTTP(server) | ||
7 | h.putrequest('POST', selector) | ||
8 | h.putheader('content-type', content_type) | ||
9 | h.putheader('content-length', str(len(body))) | ||
10 | h.endheaders() | ||
11 | h.send(body) | ||
12 | errcode, errmsg, headers = h.getreply() | ||
13 | #print errcode, errmsg, headers | ||
14 | return (errcode,errmsg, headers, h.file) | ||
15 | except: | ||
16 | # try again | ||
17 | pass | ||
18 | |||
19 | def tinder_form_data(bound, dict, log): | ||
20 | output = [] | ||
21 | #br | ||
22 | # for each key in the dictionary | ||
23 | for name in dict: | ||
24 | output.append( "--" + bound ) | ||
25 | output.append( 'Content-Disposition: form-data; name="%s"' % name ) | ||
26 | output.append( "" ) | ||
27 | output.append( dict[name] ) | ||
28 | if log: | ||
29 | output.append( "--" + bound ) | ||
30 | output.append( 'Content-Disposition: form-data; name="log"; filename="log.txt"' ) | ||
31 | output.append( '' ) | ||
32 | output.append( log ) | ||
33 | output.append( '--' + bound + '--' ) | ||
34 | output.append( '' ) | ||
35 | |||
36 | return "\r\n".join(output) | ||
37 | |||
38 | def tinder_time_string(): | ||
39 | """ | ||
40 | Return the time as GMT | ||
41 | """ | ||
42 | return "" | ||
43 | |||
44 | def tinder_format_http_post(d,status,log): | ||
45 | """ | ||
46 | Format the Tinderbox HTTP post with the data needed | ||
47 | for the tinderbox to be happy. | ||
48 | """ | ||
49 | |||
50 | from bb import data, build | ||
51 | import os,random | ||
52 | |||
53 | # the variables we will need to send on this form post | ||
54 | variables = { | ||
55 | "tree" : data.getVar('TINDER_TREE', d, True), | ||
56 | "machine_name" : data.getVar('TINDER_MACHINE', d, True), | ||
57 | "os" : os.uname()[0], | ||
58 | "os_version" : os.uname()[2], | ||
59 | "compiler" : "gcc", | ||
60 | "clobber" : data.getVar('TINDER_CLOBBER', d, True) | ||
61 | } | ||
62 | |||
63 | # optionally add the status | ||
64 | if status: | ||
65 | variables["status"] = str(status) | ||
66 | |||
67 | # try to load the machine id | ||
68 | # we only need on build_status.pl but sending it | ||
69 | # always does not hurt | ||
70 | try: | ||
71 | f = file(data.getVar('TMPDIR',d,True)+'/tinder-machine.id', 'r') | ||
72 | id = f.read() | ||
73 | variables['machine_id'] = id | ||
74 | except: | ||
75 | pass | ||
76 | |||
77 | # the boundary we will need | ||
78 | boundary = "----------------------------------%d" % int(random.random()*1000000000000) | ||
79 | |||
80 | # now format the body | ||
81 | body = tinder_form_data( boundary, variables, log ) | ||
82 | |||
83 | return ("multipart/form-data; boundary=%s" % boundary),body | ||
84 | |||
85 | |||
86 | def tinder_build_start(d): | ||
87 | """ | ||
88 | Inform the tinderbox that a build is starting. We do this | ||
89 | by posting our name and tree to the build_start.pl script | ||
90 | on the server. | ||
91 | """ | ||
92 | from bb import data | ||
93 | |||
94 | # get the body and type | ||
95 | content_type, body = tinder_format_http_post(d,None,None) | ||
96 | server = data.getVar('TINDER_HOST', d, True ) | ||
97 | url = data.getVar('TINDER_URL', d, True ) | ||
98 | |||
99 | selector = url + "/xml/build_start.pl" | ||
100 | |||
101 | #print "selector %s and url %s" % (selector, url) | ||
102 | |||
103 | # now post it | ||
104 | errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body) | ||
105 | #print errcode, errmsg, headers | ||
106 | report = h_file.read() | ||
107 | |||
108 | # now let us find the machine id that was assigned to us | ||
109 | search = "<machine id='" | ||
110 | report = report[report.find(search)+len(search):] | ||
111 | report = report[0:report.find("'")] | ||
112 | |||
113 | import bb | ||
114 | bb.note("Machine ID assigned by tinderbox: %s" % report ) | ||
115 | |||
116 | # now we will need to save the machine number | ||
117 | # we will override any previous numbers | ||
118 | f = file(data.getVar('TMPDIR', d, True)+"/tinder-machine.id", 'w') | ||
119 | f.write(report) | ||
120 | |||
121 | |||
122 | def tinder_send_http(d, status, log): | ||
123 | """ | ||
124 | Send this log as build status | ||
125 | """ | ||
126 | from bb import data | ||
127 | |||
128 | |||
129 | # get the body and type | ||
130 | content_type, body = tinder_format_http_post(d,status,log) | ||
131 | server = data.getVar('TINDER_HOST', d, True ) | ||
132 | url = data.getVar('TINDER_URL', d, True ) | ||
133 | |||
134 | selector = url + "/xml/build_status.pl" | ||
135 | |||
136 | # now post it | ||
137 | errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body) | ||
138 | #print errcode, errmsg, headers | ||
139 | #print h.file.read() | ||
140 | |||
141 | |||
142 | def tinder_print_info(d): | ||
143 | """ | ||
144 | Print the TinderBox Info | ||
145 | Including informations of the BaseSystem and the Tree | ||
146 | we use. | ||
147 | """ | ||
148 | |||
149 | from bb import data | ||
150 | import os | ||
151 | # get the local vars | ||
152 | |||
153 | time = tinder_time_string() | ||
154 | ops = os.uname()[0] | ||
155 | version = os.uname()[2] | ||
156 | url = data.getVar( 'TINDER_URL' , d, True ) | ||
157 | tree = data.getVar( 'TINDER_TREE', d, True ) | ||
158 | branch = data.getVar( 'TINDER_BRANCH', d, True ) | ||
159 | srcdate = data.getVar( 'SRCDATE', d, True ) | ||
160 | machine = data.getVar( 'MACHINE', d, True ) | ||
161 | distro = data.getVar( 'DISTRO', d, True ) | ||
162 | bbfiles = data.getVar( 'BBFILES', d, True ) | ||
163 | tarch = data.getVar( 'TARGET_ARCH', d, True ) | ||
164 | fpu = data.getVar( 'TARGET_FPU', d, True ) | ||
165 | oerev = data.getVar( 'OE_REVISION', d, True ) or "unknown" | ||
166 | |||
167 | # there is a bug with tipple quoted strings | ||
168 | # i will work around but will fix the original | ||
169 | # bug as well | ||
170 | output = [] | ||
171 | output.append("== Tinderbox Info" ) | ||
172 | output.append("Time: %(time)s" ) | ||
173 | output.append("OS: %(ops)s" ) | ||
174 | output.append("%(version)s" ) | ||
175 | output.append("Compiler: gcc" ) | ||
176 | output.append("Tinderbox Client: 0.1" ) | ||
177 | output.append("Tinderbox Client Last Modified: yesterday" ) | ||
178 | output.append("Tinderbox Protocol: 0.1" ) | ||
179 | output.append("URL: %(url)s" ) | ||
180 | output.append("Tree: %(tree)s" ) | ||
181 | output.append("Config:" ) | ||
182 | output.append("branch = '%(branch)s'" ) | ||
183 | output.append("TARGET_ARCH = '%(tarch)s'" ) | ||
184 | output.append("TARGET_FPU = '%(fpu)s'" ) | ||
185 | output.append("SRCDATE = '%(srcdate)s'" ) | ||
186 | output.append("MACHINE = '%(machine)s'" ) | ||
187 | output.append("DISTRO = '%(distro)s'" ) | ||
188 | output.append("BBFILES = '%(bbfiles)s'" ) | ||
189 | output.append("OEREV = '%(oerev)s'" ) | ||
190 | output.append("== End Tinderbox Client Info" ) | ||
191 | |||
192 | # now create the real output | ||
193 | return "\n".join(output) % vars() | ||
194 | |||
195 | |||
196 | def tinder_print_env(): | ||
197 | """ | ||
198 | Print the environment variables of this build | ||
199 | """ | ||
200 | from bb import data | ||
201 | import os | ||
202 | |||
203 | time_start = tinder_time_string() | ||
204 | time_end = tinder_time_string() | ||
205 | |||
206 | # build the environment | ||
207 | env = "" | ||
208 | for var in os.environ: | ||
209 | env += "%s=%s\n" % (var, os.environ[var]) | ||
210 | |||
211 | output = [] | ||
212 | output.append( "---> TINDERBOX RUNNING env %(time_start)s" ) | ||
213 | output.append( env ) | ||
214 | output.append( "<--- TINDERBOX FINISHED (SUCCESS) %(time_end)s" ) | ||
215 | |||
216 | return "\n".join(output) % vars() | ||
217 | |||
218 | def tinder_tinder_start(d, event): | ||
219 | """ | ||
220 | PRINT the configuration of this build | ||
221 | """ | ||
222 | |||
223 | time_start = tinder_time_string() | ||
224 | config = tinder_print_info(d) | ||
225 | #env = tinder_print_env() | ||
226 | time_end = tinder_time_string() | ||
227 | packages = " ".join( event.getPkgs() ) | ||
228 | |||
229 | output = [] | ||
230 | output.append( "---> TINDERBOX PRINTING CONFIGURATION %(time_start)s" ) | ||
231 | output.append( config ) | ||
232 | #output.append( env ) | ||
233 | output.append( "<--- TINDERBOX FINISHED PRINTING CONFIGURATION %(time_end)s" ) | ||
234 | output.append( "---> TINDERBOX BUILDING '%(packages)s'" ) | ||
235 | output.append( "<--- TINDERBOX STARTING BUILD NOW" ) | ||
236 | |||
237 | output.append( "" ) | ||
238 | |||
239 | return "\n".join(output) % vars() | ||
240 | |||
241 | def tinder_do_tinder_report(event): | ||
242 | """ | ||
243 | Report to the tinderbox: | ||
244 | On the BuildStart we will inform the box directly | ||
245 | On the other events we will write to the TINDER_LOG and | ||
246 | when the Task is finished we will send the report. | ||
247 | |||
248 | The above is not yet fully implemented. Currently we send | ||
249 | information immediately. The caching/queuing needs to be | ||
250 | implemented. Also sending more or less information is not | ||
251 | implemented yet. | ||
252 | """ | ||
253 | from bb.event import getName | ||
254 | from bb import data, mkdirhier, build | ||
255 | import os, glob | ||
256 | |||
257 | # variables | ||
258 | name = getName(event) | ||
259 | log = "" | ||
260 | status = 1 | ||
261 | #print asd | ||
262 | # Check what we need to do Build* shows we start or are done | ||
263 | if name == "BuildStarted": | ||
264 | tinder_build_start(event.data) | ||
265 | log = tinder_tinder_start(event.data,event) | ||
266 | |||
267 | try: | ||
268 | # truncate the tinder log file | ||
269 | f = file(data.getVar('TINDER_LOG', event.data, True), 'rw+') | ||
270 | f.truncate(0) | ||
271 | f.close() | ||
272 | except IOError: | ||
273 | pass | ||
274 | |||
275 | # Append the Task-Log (compile,configure...) to the log file | ||
276 | # we will send to the server | ||
277 | if name == "TaskSucceeded" or name == "TaskFailed": | ||
278 | log_file = glob.glob("%s/log.%s.*" % (data.getVar('T', event.data, True), event.task)) | ||
279 | |||
280 | if len(log_file) != 0: | ||
281 | to_file = data.getVar('TINDER_LOG', event.data, True) | ||
282 | log += "".join(open(log_file[0], 'r').readlines()) | ||
283 | |||
284 | # set the right 'HEADER'/Summary for the TinderBox | ||
285 | if name == "TaskStarted": | ||
286 | log += "---> TINDERBOX Task %s started\n" % event.task | ||
287 | elif name == "TaskSucceeded": | ||
288 | log += "<--- TINDERBOX Task %s done (SUCCESS)\n" % event.task | ||
289 | elif name == "TaskFailed": | ||
290 | log += "<--- TINDERBOX Task %s failed (FAILURE)\n" % event.task | ||
291 | elif name == "PkgStarted": | ||
292 | log += "---> TINDERBOX Package %s started\n" % data.getVar('P', event.data, True) | ||
293 | elif name == "PkgSucceeded": | ||
294 | log += "<--- TINDERBOX Package %s done (SUCCESS)\n" % data.getVar('P', event.data, True) | ||
295 | elif name == "PkgFailed": | ||
296 | build.exec_task('do_clean', event.data) | ||
297 | log += "<--- TINDERBOX Package %s failed (FAILURE)\n" % data.getVar('P', event.data, True) | ||
298 | status = 200 | ||
299 | elif name == "BuildCompleted": | ||
300 | log += "Build Completed\n" | ||
301 | status = 100 | ||
302 | elif name == "MultipleProviders": | ||
303 | log += "---> TINDERBOX Multiple Providers\n" | ||
304 | log += "multiple providers are available (%s);\n" % ", ".join(event.getCandidates()) | ||
305 | log += "consider defining PREFERRED_PROVIDER_%s\n" % event.getItem() | ||
306 | log += "is runtime: %d\n" % event.isRuntime() | ||
307 | log += "<--- TINDERBOX Multiple Providers\n" | ||
308 | elif name == "NoProvider": | ||
309 | log += "Error: No Provider for: %s\n" % event.getItem() | ||
310 | log += "Error:Was Runtime: %d\n" % event.isRuntime() | ||
311 | status = 200 | ||
312 | |||
313 | # now post the log | ||
314 | if len(log) == 0: | ||
315 | return | ||
316 | |||
317 | # for now we will use the http post method as it is the only one | ||
318 | log_post_method = tinder_send_http | ||
319 | log_post_method(event.data, status, log) | ||
320 | |||
321 | |||
322 | # we want to be an event handler | ||
323 | addhandler tinderclient_eventhandler | ||
324 | python tinderclient_eventhandler() { | ||
325 | from bb import note, error, data | ||
326 | from bb.event import NotHandled | ||
327 | do_tinder_report = data.getVar('TINDER_REPORT', e.data, True) | ||
328 | if do_tinder_report and do_tinder_report == "1": | ||
329 | tinder_do_tinder_report(e) | ||
330 | |||
331 | return NotHandled | ||
332 | } | ||