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)
19 def tinder_form_data(bound, dict, log):
22 # for each key in the dictionary
24 output.append( "--" + bound )
25 output.append( 'Content-Disposition: form-data; name="%s"' % name )
27 output.append( dict[name] )
29 output.append( "--" + bound )
30 output.append( 'Content-Disposition: form-data; name="log"; filename="log.txt"' )
33 output.append( '--' + bound + '--' )
36 return "\r\n".join(output)
38 def tinder_time_string():
40 Return the time as GMT
44 def tinder_format_http_post(d,status,log):
46 Format the Tinderbox HTTP post with the data needed
47 for the tinderbox to be happy.
50 from bb import data, build
53 # the variables we will need to send on this form post
55 "tree" : data.getVar('TINDER_TREE', d, True),
56 "machine_name" : data.getVar('TINDER_MACHINE', d, True),
58 "os_version" : os.uname()[2],
60 "clobber" : data.getVar('TINDER_CLOBBER', d, True)
63 # optionally add the status
65 variables["status"] = str(status)
67 # try to load the machine id
68 # we only need on build_status.pl but sending it
69 # always does not hurt
71 f = file(data.getVar('TMPDIR',d,True)+'/tinder-machine.id', 'r')
73 variables['machine_id'] = id
77 # the boundary we will need
78 boundary = "----------------------------------%d" % int(random.random()*1000000000000)
81 body = tinder_form_data( boundary, variables, log )
83 return ("multipart/form-data; boundary=%s" % boundary),body
86 def tinder_build_start(d):
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
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 )
99 selector = url + "/xml/build_start.pl"
101 #print "selector %s and url %s" % (selector, url)
104 errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body)
105 #print errcode, errmsg, headers
106 report = h_file.read()
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("'")]
114 bb.note("Machine ID assigned by tinderbox: %s" % report )
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')
122 def tinder_send_http(d, status, log):
124 Send this log as build status
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 )
134 selector = url + "/xml/build_status.pl"
137 errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body)
138 #print errcode, errmsg, headers
142 def tinder_print_info(d):
144 Print the TinderBox Info
145 Including informations of the BaseSystem and the Tree
153 time = tinder_time_string()
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"
167 # there is a bug with tipple quoted strings
168 # i will work around but will fix the original
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" )
192 # now create the real output
193 return "\n".join(output) % vars()
196 def tinder_print_env():
198 Print the environment variables of this build
203 time_start = tinder_time_string()
204 time_end = tinder_time_string()
206 # build the environment
208 for var in os.environ:
209 env += "%s=%s\n" % (var, os.environ[var])
212 output.append( "---> TINDERBOX RUNNING env %(time_start)s" )
214 output.append( "<--- TINDERBOX FINISHED (SUCCESS) %(time_end)s" )
216 return "\n".join(output) % vars()
218 def tinder_tinder_start(d, event):
220 PRINT the configuration of this build
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() )
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" )
239 return "\n".join(output) % vars()
241 def tinder_do_tinder_report(event):
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.
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
253 from bb.event import getName
254 from bb import data, mkdirhier, build
258 name = getName(event)
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)
268 # truncate the tinder log file
269 f = file(data.getVar('TINDER_LOG', event.data, True), 'rw+')
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))
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())
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)
299 elif name == "BuildCompleted":
300 log += "Build Completed\n"
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()
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)
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)