1 def tinder_http_post(server, selector, content_type, body):
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)))
12 errcode, errmsg, headers = h.getreply()
13 #print errcode, errmsg, headers
14 return (errcode,errmsg, headers, h.file)
16 print "Error sending the report!"
21 return (-1, "unknown", "unknown", None)
23 def tinder_form_data(bound, dict, log):
25 # for each key in the dictionary
27 output.append( "--" + bound )
28 output.append( 'Content-Disposition: form-data; name="%s"' % name )
30 output.append( dict[name] )
32 output.append( "--" + bound )
33 output.append( 'Content-Disposition: form-data; name="log"; filename="log.txt"' )
36 output.append( '--' + bound + '--' )
39 return "\r\n".join(output)
41 def tinder_time_string():
43 Return the time as GMT
47 def tinder_format_http_post(d,status,log):
49 Format the Tinderbox HTTP post with the data needed
50 for the tinderbox to be happy.
53 from bb import data, build
56 # the variables we will need to send on this form post
58 "tree" : data.getVar('TINDER_TREE', d, True),
59 "machine_name" : data.getVar('TINDER_MACHINE', d, True),
61 "os_version" : os.uname()[2],
63 "clobber" : data.getVar('TINDER_CLOBBER', d, True)
66 # optionally add the status
68 variables["status"] = str(status)
70 # try to load the machine id
71 # we only need on build_status.pl but sending it
72 # always does not hurt
74 f = file(data.getVar('TMPDIR',d,True)+'/tinder-machine.id', 'r')
76 variables['machine_id'] = id
80 # the boundary we will need
81 boundary = "----------------------------------%d" % int(random.random()*1000000000000)
84 body = tinder_form_data( boundary, variables, log )
86 return ("multipart/form-data; boundary=%s" % boundary),body
89 def tinder_build_start(d):
91 Inform the tinderbox that a build is starting. We do this
92 by posting our name and tree to the build_start.pl script
97 # get the body and type
98 content_type, body = tinder_format_http_post(d,None,None)
99 server = data.getVar('TINDER_HOST', d, True )
100 url = data.getVar('TINDER_URL', d, True )
102 selector = url + "/xml/build_start.pl"
104 #print "selector %s and url %s" % (selector, url)
107 errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body)
108 #print errcode, errmsg, headers
109 report = h_file.read()
111 # now let us find the machine id that was assigned to us
112 search = "<machine id='"
113 report = report[report.find(search)+len(search):]
114 report = report[0:report.find("'")]
117 bb.note("Machine ID assigned by tinderbox: %s" % report )
119 # now we will need to save the machine number
120 # we will override any previous numbers
121 f = file(data.getVar('TMPDIR', d, True)+"/tinder-machine.id", 'w')
125 def tinder_send_http(d, status, _log):
127 Send this log as build status
132 # get the body and type
133 server = data.getVar('TINDER_HOST', d, True )
134 url = data.getVar('TINDER_URL', d, True )
136 selector = url + "/xml/build_status.pl"
138 # now post it - in chunks of 10.000 charachters
140 while len(new_log) > 0:
141 content_type, body = tinder_format_http_post(d,status,new_log[0:18000])
142 errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body)
143 #print errcode, errmsg, headers
145 new_log = new_log[18000:]
148 def tinder_print_info(d):
150 Print the TinderBox Info
151 Including informations of the BaseSystem and the Tree
159 time = tinder_time_string()
161 version = os.uname()[2]
162 url = data.getVar( 'TINDER_URL' , d, True )
163 tree = data.getVar( 'TINDER_TREE', d, True )
164 branch = data.getVar( 'TINDER_BRANCH', d, True )
165 srcdate = data.getVar( 'SRCDATE', d, True )
166 machine = data.getVar( 'MACHINE', d, True )
167 distro = data.getVar( 'DISTRO', d, True )
168 bbfiles = data.getVar( 'BBFILES', d, True )
169 tarch = data.getVar( 'TARGET_ARCH', d, True )
170 fpu = data.getVar( 'TARGET_FPU', d, True )
171 oerev = data.getVar( 'OE_REVISION', d, True ) or "unknown"
173 # there is a bug with tipple quoted strings
174 # i will work around but will fix the original
177 output.append("== Tinderbox Info" )
178 output.append("Time: %(time)s" )
179 output.append("OS: %(ops)s" )
180 output.append("%(version)s" )
181 output.append("Compiler: gcc" )
182 output.append("Tinderbox Client: 0.1" )
183 output.append("Tinderbox Client Last Modified: yesterday" )
184 output.append("Tinderbox Protocol: 0.1" )
185 output.append("URL: %(url)s" )
186 output.append("Tree: %(tree)s" )
187 output.append("Config:" )
188 output.append("branch = '%(branch)s'" )
189 output.append("TARGET_ARCH = '%(tarch)s'" )
190 output.append("TARGET_FPU = '%(fpu)s'" )
191 output.append("SRCDATE = '%(srcdate)s'" )
192 output.append("MACHINE = '%(machine)s'" )
193 output.append("DISTRO = '%(distro)s'" )
194 output.append("BBFILES = '%(bbfiles)s'" )
195 output.append("OEREV = '%(oerev)s'" )
196 output.append("== End Tinderbox Client Info" )
198 # now create the real output
199 return "\n".join(output) % vars()
202 def tinder_print_env():
204 Print the environment variables of this build
209 time_start = tinder_time_string()
210 time_end = tinder_time_string()
212 # build the environment
214 for var in os.environ:
215 env += "%s=%s\n" % (var, os.environ[var])
218 output.append( "---> TINDERBOX RUNNING env %(time_start)s" )
220 output.append( "<--- TINDERBOX FINISHED (SUCCESS) %(time_end)s" )
222 return "\n".join(output) % vars()
224 def tinder_tinder_start(d, event):
226 PRINT the configuration of this build
229 time_start = tinder_time_string()
230 config = tinder_print_info(d)
231 #env = tinder_print_env()
232 time_end = tinder_time_string()
233 packages = " ".join( event.getPkgs() )
236 output.append( "---> TINDERBOX PRINTING CONFIGURATION %(time_start)s" )
237 output.append( config )
238 #output.append( env )
239 output.append( "<--- TINDERBOX FINISHED PRINTING CONFIGURATION %(time_end)s" )
240 output.append( "---> TINDERBOX BUILDING '%(packages)s'" )
241 output.append( "<--- TINDERBOX STARTING BUILD NOW" )
245 return "\n".join(output) % vars()
247 def tinder_do_tinder_report(event):
249 Report to the tinderbox:
250 On the BuildStart we will inform the box directly
251 On the other events we will write to the TINDER_LOG and
252 when the Task is finished we will send the report.
254 The above is not yet fully implemented. Currently we send
255 information immediately. The caching/queuing needs to be
256 implemented. Also sending more or less information is not
259 from bb.event import getName
260 from bb import data, mkdirhier, build
264 name = getName(event)
268 # Check what we need to do Build* shows we start or are done
269 if name == "BuildStarted":
270 tinder_build_start(event.data)
271 log = tinder_tinder_start(event.data,event)
274 # truncate the tinder log file
275 f = file(data.getVar('TINDER_LOG', event.data, True), 'rw+')
281 # Append the Task-Log (compile,configure...) to the log file
282 # we will send to the server
283 if name == "TaskSucceeded" or name == "TaskFailed":
284 log_file = glob.glob("%s/log.%s.*" % (data.getVar('T', event.data, True), event.task))
286 if len(log_file) != 0:
287 to_file = data.getVar('TINDER_LOG', event.data, True)
288 log += "".join(open(log_file[0], 'r').readlines())
290 # set the right 'HEADER'/Summary for the TinderBox
291 if name == "TaskStarted":
292 log += "---> TINDERBOX Task %s started\n" % event.task
293 elif name == "TaskSucceeded":
294 log += "<--- TINDERBOX Task %s done (SUCCESS)\n" % event.task
295 elif name == "TaskFailed":
296 log += "<--- TINDERBOX Task %s failed (FAILURE)\n" % event.task
297 elif name == "PkgStarted":
298 log += "---> TINDERBOX Package %s started\n" % data.getVar('P', event.data, True)
299 elif name == "PkgSucceeded":
300 log += "<--- TINDERBOX Package %s done (SUCCESS)\n" % data.getVar('P', event.data, True)
301 elif name == "PkgFailed":
302 build.exec_task('do_clean', event.data)
303 log += "<--- TINDERBOX Package %s failed (FAILURE)\n" % data.getVar('P', event.data, True)
305 elif name == "BuildCompleted":
306 log += "Build Completed\n"
308 elif name == "MultipleProviders":
309 log += "---> TINDERBOX Multiple Providers\n"
310 log += "multiple providers are available (%s);\n" % ", ".join(event.getCandidates())
311 log += "consider defining PREFERRED_PROVIDER_%s\n" % event.getItem()
312 log += "is runtime: %d\n" % event.isRuntime()
313 log += "<--- TINDERBOX Multiple Providers\n"
314 elif name == "NoProvider":
315 log += "Error: No Provider for: %s\n" % event.getItem()
316 log += "Error:Was Runtime: %d\n" % event.isRuntime()
323 # for now we will use the http post method as it is the only one
324 log_post_method = tinder_send_http
325 log_post_method(event.data, status, log)
328 # we want to be an event handler
329 addhandler tinderclient_eventhandler
330 python tinderclient_eventhandler() {
331 from bb import note, error, data
332 from bb.event import NotHandled
333 do_tinder_report = data.getVar('TINDER_REPORT', e.data, True)
334 if do_tinder_report and do_tinder_report == "1":
335 tinder_do_tinder_report(e)