[cvs] / gkb / gkb.py  

cvs: gkb/gkb.py


1 : tmcnulty 1.1 #!/usr/bin/python
2 :     #
3 :     # GKB - GNU Kernel Builder
4 : tmcnulty 1.2 # Copyright (C) 2003-2004 Tobias McNulty, Mark Guertin
5 : tmcnulty 1.1 #
6 :     # This program is free software; you can redistribute it and/or modify
7 :     # it under the terms of the GNU General Public License as published by
8 :     # the Free Software Foundation; either version 2 of the License, or
9 :     # (at your option) any later version.
10 :     #
11 :     # This program is distributed in the hope that it will be useful,
12 :     # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 :     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 :     # GNU General Public License for more details.
15 :     #
16 :     # You should have received a copy of the GNU General Public License
17 :     # along with this program; if not, write to the Free Software
18 :     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 :     #
20 :     # Ported from PHP version Copyright (c) Tobias McNulty 2000-2003
21 :    
22 : tmcnulty 1.20 import sys, os, ConfigParser, popen2
23 : tmcnulty 1.1 import xml.parsers.expat
24 : tmcnulty 1.21 import md5, string
25 : tmcnulty 1.37 from getopt import getopt
26 : tmcnulty 1.1 from ftplib import FTP
27 :     from commands import getoutput
28 :     from shutil import copy, move
29 :     from string import split
30 :     from urllib2 import urlopen
31 :     from ClientForm import ParseResponse
32 :    
33 : tmcnulty 1.29
34 : tmcnulty 1.37 debug=1
35 : tmcnulty 1.22 clean=1
36 :     dont_build=0
37 : tmcnulty 1.1 verbose=1
38 :    
39 : tmcnulty 1.37 configfile='gkb-host.cfg'
40 :    
41 :     opts,args=getopt(sys.argv[1:],"gkb",["config="])
42 :     for opt, arg in opts:
43 :     if opt in ("-c","--config"):
44 :     configfile = arg
45 :    
46 : tmcnulty 1.1 # parse host-specific configuration information from gkb.cfg
47 :     config = ConfigParser.ConfigParser()
48 : tmcnulty 1.37 config.readfp(open(configfile))
49 : tmcnulty 1.1 buildroot=config.get("options","buildroot")
50 :     host=config.get("options","host")
51 :     passwd=config.get("options","passwd")
52 :    
53 :     # this one is passed verbatim before the make command. might be useful for alternate toolchains, etc
54 :     # example: premake="HOST=powerpc-unknown-linux-gnu"
55 :     premake=config.get("options","premake")
56 :     # make options, passed verbatim after make command
57 :     makeopts=config.get("options","makeopts")
58 :    
59 :     # parse manager-related configuration from gkb-manager.cfg
60 : tmcnulty 1.37 config.readfp(open('%s/gkb-manager.cfg' %buildroot))
61 : tmcnulty 1.1 msite=config.get('options','msite')
62 : tmcnulty 1.37 uploaddir=config.get('options','uploaddir')
63 : tmcnulty 1.1
64 :     # these values will likely stay fairly static across different builds
65 :     patchdir="%s/patches" % buildroot # full path to patch file dir
66 :     configdir="%s/configs" % buildroot # path to where configs are to be stored
67 :     logdir="%s/logs" % buildroot # the logs will go here
68 :     bindir="%s/bin" % buildroot # the directory that binaries built will be sent for pkging
69 :     workdir="%s/work" % buildroot # work directory, where builds take place
70 :    
71 :     # setup the global dicts to hold build data, imported from xml
72 :     mastertrees={}
73 :     builds={}
74 :    
75 : tmcnulty 1.7 class Error(Exception):
76 :     """Base class for exceptions in this module."""
77 :     pass
78 :    
79 :     class BuildError(Error):
80 :     """Exception raised for build-level errors.
81 :    
82 :     Attributes:
83 :     message -- explanation of the error
84 :     """
85 :    
86 :     def __init__(self, message):
87 :     self.message = message
88 :    
89 :     class FatalError(Error):
90 :     """Exception for fatal errors that prevent program continuation.
91 :    
92 :     Attributes:
93 :     message -- explanation of why the specific transition is not allowed
94 :     """
95 :    
96 : tmcnulty 1.12 def __init__(self, message):
97 : tmcnulty 1.7 self.message = message
98 :    
99 : tmcnulty 1.1 def printverbose(myoutput):
100 :     """Supporting method to output info to stdout if verbosity level is set"""
101 :     if verbose==1:
102 :     print myoutput
103 :    
104 : tmcnulty 1.28 def cleantext(text):
105 : tmcnulty 1.21 """clean a string of passwords, etc. to make it suitable for logging"""
106 :     result = string.replace(text,passwd,"XXXXXXXX")
107 :     return result
108 :    
109 : tmcnulty 1.16 def linkpipes(input, output):
110 : tmcnulty 1.21 """link two pipes together, writing all the data from input to output"""
111 : tmcnulty 1.16 data = input.read(2048)
112 :     while data:
113 :     output.write(data)
114 : tmcnulty 1.18 data = input.read(2048)
115 :    
116 : tmcnulty 1.22 def runcmd(cmd, kinfo=None, outfile=None, append=False, infile=None):
117 : tmcnulty 1.21 """run the specified command, with the optional input and output documents"""
118 : tmcnulty 1.28 log(" \_ running " + cleantext(cmd), kinfo)
119 : tmcnulty 1.16
120 : tmcnulty 1.20 p4obj = popen2.Popen4(cmd)
121 : tmcnulty 1.19
122 :     pin = p4obj.tochild
123 :     pouterr = p4obj.fromchild
124 : tmcnulty 1.16
125 :     if infile != None:
126 :     inobj = open(infile, "r")
127 :     linkpipes(inobj, pin)
128 :     inobj.close()
129 :    
130 :     if outfile != None:
131 :     if append:
132 :     mode = "a"
133 :     else:
134 :     mode = "w"
135 :    
136 :     outobj = open(outfile, mode)
137 : tmcnulty 1.18 linkpipes(pouterr,outobj)
138 : tmcnulty 1.16 outobj.close()
139 :    
140 : tmcnulty 1.19 err = p4obj.wait()
141 : tmcnulty 1.16
142 :     if err == None:
143 :     err = 0
144 : tmcnulty 1.17
145 : tmcnulty 1.25 log(" \_ exit code: %i" % err, kinfo)
146 : tmcnulty 1.21
147 : tmcnulty 1.14 return err
148 :    
149 : tmcnulty 1.37 def mail(to,subject,body):
150 :     """send a message to 'to' with subject 'subject' and body 'body'"""
151 :     log(" \_ running mail")
152 :    
153 :     p4obj = popen2.Popen4("mail -s \'%s\' %s" % (subject, to))
154 :    
155 :     pin = p4obj.tochild
156 :     pouterr = p4obj.fromchild
157 :    
158 :     pin.write(body)
159 :     pin.close()
160 :     err = p4obj.wait()
161 :    
162 :     if err == None:
163 :     err = 0
164 :    
165 :     log(" \_ exit code: %i" % err)
166 :    
167 :     return err
168 :    
169 : tmcnulty 1.1 def log(text,kinfo=0):
170 :     if kinfo:
171 :     printverbose(kinfo["name"] + " : " + text)
172 :     else:
173 :     printverbose("gkb : " + text)
174 :    
175 :     def verifydir(mydir,kinfo=0):
176 :     """Supporting method to verify a given exists, if not it will create it"""
177 :     log("verifying directory " + mydir,kinfo)
178 :     if not os.path.isdir(mydir):
179 : tmcnulty 1.25 log(" \_ %s doesn't exist, creating" % mydir,kinfo)
180 : tmcnulty 1.1 os.mkdir(mydir)
181 :     return mydir
182 :    
183 :     def chdir(mydir,kinfo):
184 :     verifydir(mydir,kinfo)
185 :     log("entering "+mydir,kinfo)
186 :     os.chdir(mydir)
187 :    
188 :     def verifyfile(myfile,kinfo):
189 :     """Supporting method to verify file exists, if not it will exit with error"""
190 :     if not os.path.isfile(myfile):
191 : tmcnulty 1.7 raise BuildError("cannot find file expected at %s, exiting" % myfile)
192 : tmcnulty 1.1 return myfile
193 :    
194 :     def md5sum(fileobj):
195 :     """calculates the md5sum for fileobj and returns it in hexadecimal"""
196 :     md = md5.new()
197 :     data = fileobj.read(8192)
198 :     while (data):
199 :     md.update(data)
200 :     data = fileobj.read(8192)
201 :    
202 :     digest = md.hexdigest()
203 :     return digest
204 :    
205 : tmcnulty 1.31 def krn_querymgr(command,kinfo,extra=""):
206 : tmcnulty 1.1 """queries the build host manager with a variety of commands, such as checkout, checkin, etc."""
207 :     version=krn_localversion(kinfo)
208 :     log("querying distribution site manager with command '%s' (kernel version=%s)" % (command,version),kinfo)
209 : tmcnulty 1.31 result=getoutput("wget --quiet --output-document=- \"%s/manager.php?cmd=%s&host=%s&pass=%s&build=%s&version=%s%s\"" % (msite,command,host,passwd,kinfo["name"],version,extra))
210 : tmcnulty 1.25 log(" \_ result: '"+result+"'",kinfo)
211 : tmcnulty 1.1 return result=="1"
212 :    
213 : tmcnulty 1.31 def krn_modulesenabled(kinfo):
214 :     """Checks the source to see if modules are enabled"""
215 : tmcnulty 1.32 output=getoutput("""awk -F '=' '/^CONFIG_MODULES/{v=$2} END { printf("%s\\n", v) }' """ + kinfo["workdir"] + """/.config | sed "s/ //g" """)
216 : tmcnulty 1.31 if (output=='y'):
217 : tmcnulty 1.32 result=1
218 : tmcnulty 1.31 else:
219 : tmcnulty 1.32 result=0
220 :    
221 : tmcnulty 1.31 return result
222 :    
223 : tmcnulty 1.1 def krn_localversion(kinfo):
224 :     """Checks the version of the local source tree specified in kinfo"""
225 :     version=getoutput("""awk -F '=' '/^VERSION/{v=$2} /^PATCHLEVEL/{p=$2} /^SUBLEVEL/{s=$2} /^EXTRAVERSION/{e=$2} END { printf("%s.%s.%s%s\\n", v, p, s, e) }' """ + kinfo["workdir"] + """/Makefile | sed "s/ //g" """)
226 :     return version
227 :    
228 :     def gkb_build(root,kinfo):
229 :     """performs actual kernel builds given root, kinfo (tuple containing relevant data) , premake and makeopts"""
230 :    
231 :     # make sure needed directoriess (for this build) exist, if not create them
232 :    
233 :     verifydir("%s/%s" % (logdir, kinfo["name"]),kinfo)
234 :     verifydir("%s/%s" % (patchdir, kinfo["name"]),kinfo)
235 :    
236 :     # sync the source to make sure we are up to date ...
237 : tmcnulty 1.25 log("fetching latest source",kinfo)
238 : tmcnulty 1.1 gkb_getsource(kinfo)
239 :    
240 : tmcnulty 1.10 # go into the work directory
241 : tmcnulty 1.27 #chdir(workdir, kinfo)
242 : tmcnulty 1.10
243 :     # archive the clean source for later uploading
244 : tmcnulty 1.27 #log("archiving source to " + kinfo["mastertree"] + ".tar.bz2", kinfo)
245 :     #runcmd("tar cjf " + kinfo["mastertree"] + ".tar.bz2 " + kinfo["mastertree"], kinfo)
246 : tmcnulty 1.10
247 :     # now we'll go into the tree's work dir
248 : tmcnulty 1.1 chdir(kinfo["workdir"],kinfo)
249 :    
250 :     # check for patches and apply if necessary
251 :     gkb_patch(kinfo)
252 :    
253 :     if kinfo["type"] == "kernel24":
254 :     krn_build24(kinfo)
255 :     elif kinfo["type"] == "kernel26":
256 :     krn_build24(kinfo) #run kernel24 for now, change later
257 :    
258 :     # Gerk comment:
259 :     # Do we need to change this with 24/26? we probably don't ... I'd rather see us define the list of make targets
260 :     # i.e. "dep","clean","vmlinux","modules","modules_install" or "clean","all","modules_install" for 2.6
261 :     # also of note, make all is not what we will always want with 2.6 kernels ... i.e. zImage.prep, zImage.chrp, etc
262 :     # also for backward compat they will continue to support calling things individual .. the makefile just does
263 :     # this for us with 'all'
264 :    
265 :    
266 :     def krn_build24(kinfo):
267 :     """build a kernel, version 2.4.x"""
268 :    
269 :     if krn_querymgr("checkout",kinfo):
270 : tmcnulty 1.7 try:
271 :     myversion=krn_localversion(kinfo)
272 :    
273 :     # fetch and cp the config file to work/.config
274 :     krn_config(kinfo)
275 :    
276 :     # **Note** : we set the preprocessing command to premake inline instead
277 :     # of globally as it is only needed in this target
278 :     if dont_build==0:
279 :     gkb_runmake("oldconfig",kinfo,premake+" /bin/cat %s/newlines | " % buildroot,makeopts)
280 :    
281 :     # give option to only repackage for testing purposes, comment out clean=1 at top of this file to use this feature
282 :     if (clean==1 and dont_build==0):
283 :     gkb_runmake("clean", kinfo, premake, makeopts)
284 :    
285 :     if dont_build==0:
286 :     gkb_runmake("dep", kinfo, premake, makeopts)
287 :     gkb_runmake(kinfo["binname"], kinfo, premake, makeopts)
288 :    
289 :     # We should check to see if binary built ok, if not bail out
290 :     mybindir=bindir+"/linux-"+kinfo["name"]+"-"+myversion
291 :     verifydir(mybindir,kinfo)
292 :     verifydir(mybindir+"/boot",kinfo)
293 :    
294 :     kbinloc=kinfo["workdir"]+"/"+kinfo["binpath"]+"/"+kinfo["binname"]
295 :     if verifyfile(kbinloc,kinfo):
296 :     # the binary exists, so let's cp it to bin...
297 :     copy(kbinloc,mybindir+"/boot/"+kinfo["binname"]+"-"+myversion)
298 : tmcnulty 1.35 copy("%s/System.map" % kinfo["workdir"],mybindir+"/boot/System.map-"+myversion)
299 : tmcnulty 1.7 else:
300 :     # the binary is not there, inform user and bail out with error
301 :     raise BuildError("%s is not present, assuming build failure and exiting. See log for details." % kbinloc)
302 : tmcnulty 1.31
303 :     if krn_modulesenabled(kinfo):
304 :     # now that we know he binary built, let's continue
305 :     if dont_build==0:
306 :     gkb_runmake("modules",kinfo, premake, makeopts)
307 :    
308 :     # **Note** : we prepend the INSTALL_MOD_PATH to the makeopts inline instead
309 :     # of globally as it is only needed in this target
310 :     gkb_runmake("modules_install", kinfo, premake, "INSTALL_MOD_PATH=%s %s" % (mybindir, makeopts))
311 :     else:
312 :     log("skipping make modules (disabled in .config)",kinfo)
313 :    
314 : tmcnulty 1.10 # compress and upload source archive
315 :     chdir(kinfo["workdir"]+"/..",kinfo)
316 :     archive_name = "src-%s.tar.bz2" % kinfo["mastertree"],
317 :    
318 :     # compress and upload kernel binary
319 : tmcnulty 1.7 chdir(bindir,kinfo)
320 :     archive_name = "linux-%s-%s.tar.bz2" % (kinfo["name"], myversion)
321 :    
322 :     log("compressing binary archive "+archive_name,kinfo)
323 :    
324 : tmcnulty 1.21 if runcmd("tar cjf "+archive_name+" "+os.path.basename(mybindir), kinfo):
325 : tmcnulty 1.7 raise BuildError("failed to `tar cjf %s`" % archive_name)
326 :    
327 : tmcnulty 1.21 runcmd("rm -rf %s" % mybindir, kinfo)
328 : tmcnulty 1.7
329 : tmcnulty 1.10 krn_upload(archive_name,"kernel",myversion,kinfo)
330 :     krn_querymgr("checkin",kinfo)
331 :    
332 : tmcnulty 1.36 # if os.fork() == 0:
333 :     # #in child
334 :     # try:
335 :     # # sync the source to make sure we are up to date ...
336 :     # log("re-fetching latest source",kinfo)
337 :     # gkb_getsource(kinfo)
338 :     #
339 :     # # go into the work directory
340 :     # chdir(workdir, kinfo)
341 :     #
342 :     # # archive the clean source for later uploading
343 :     # log("archiving source to " + kinfo["mastertree"] + ".tar.bz2", kinfo)
344 :     # runcmd("tar cjf " + kinfo["mastertree"] + ".tar.bz2 " + kinfo["mastertree"], kinfo)
345 :     #
346 :     # krn_upload(workdir + "/" + kinfo["mastertree"] + ".tar.bz2", "source", myversion, kinfo)
347 :     # finally:
348 :     # sys.exit(0)
349 :    
350 :     log("returning source directory to clean state",kinfo)
351 :     gkb_getsource(kinfo)
352 : tmcnulty 1.10
353 : tmcnulty 1.7 except BuildError, e:
354 :     log(e.message, kinfo)
355 : tmcnulty 1.31 krn_querymgr("checkin",kinfo,"&failed=%s" % krn_localversion(kinfo))
356 : tmcnulty 1.8 except:
357 : tmcnulty 1.31 krn_querymgr("checkin",kinfo,"&failed=%s" % krn_localversion(kinfo))
358 : tmcnulty 1.8 raise
359 :    
360 : tmcnulty 1.1 def krn_build26(kinfo):
361 :     """build a kernel, version 2.6"""
362 :    
363 :     # source get routines
364 :     def gkb_getsource(kinfo):
365 :     """method to perform source sync on demand, currenty only supports rsync, but others can be added"""
366 :    
367 :     method=mastertrees[kinfo["mastertree"]]["method"]
368 :    
369 :     if method == "rsync":
370 :     get_rsync(kinfo)
371 :     elif method == "wget":
372 :     get_wget(kinfo)
373 :     elif method == "vanilla":
374 :     get_vanilla(kinfo)
375 :    
376 :     def get_rsync(kinfo):
377 :     """sync the source using rsync"""
378 :     args=mastertrees[kinfo["mastertree"]]["args"]
379 :    
380 :     if clean==1:
381 :     syncoptions="rsync -azv --delete"
382 :     else:
383 :     syncoptions="rsync -azv"
384 :    
385 :     syncline=args+" "+kinfo["workdir"]
386 :    
387 : tmcnulty 1.23 #logging now in runcmd
388 :     #log("running rsync : %s %s" % (syncoptions, syncline),kinfo)
389 : tmcnulty 1.21 if runcmd("%s %s" % (syncoptions, syncline), kinfo, "%s/%s/rsync.log" % (logdir, kinfo["name"])):
390 : tmcnulty 1.7 raise BuildError("sync failed, tried %s. See log for details." % syncline)
391 : tmcnulty 1.1
392 :     def get_wget(kinfo):
393 :     #needs work
394 :     """sync the source using wget and a tar.bz2"""
395 :     args=mastertrees[kinfo["mastertree"]]["args"]
396 :    
397 :     log("fetching source archive " % args,kinfo)
398 :     mysourcefile="%s/%s.tar.bz2" % (kinfo["workdir"],kinfo["name"])
399 :    
400 : tmcnulty 1.21 if runcmd("wget --quiet --output-document=%s %s/configs/%s" % (myconfigfile,msite,kinfo["name"]), kinfo):
401 : tmcnulty 1.7 raise BuildError("unable to download configfile, aborting.")
402 : tmcnulty 1.1
403 :     log("decompressing source file",kinfo)
404 : tmcnulty 1.21 if runcmd("tar xjf " % (myconfigfile,msite,kinfo["name"]), kinfo):
405 : tmcnulty 1.7 raise BuildError("unable to decompress source file, aborting.")
406 : tmcnulty 1.1
407 :     def get_vanilla(kinfo):
408 :     args=mastertrees[kinfo["mastertree"]]["args"]
409 :    
410 :     log("fetching source archive %s" % args)
411 :     mysourcefile="%s/%s.tar.bz2" % (workdir,kinfo["name"])
412 :    
413 : tmcnulty 1.21 if runcmd("wget -c --output-document=%s %s" % (mysourcefile,args), kinfo):
414 : tmcnulty 1.7 raise BuildError("unable to download source file %s, aborting." % args)
415 : tmcnulty 1.1
416 :     log("decompressing source file %s" % mysourcefile,kinfo)
417 :    
418 :     #save the current working ectory
419 :     cwd=getoutput("pwd")
420 :    
421 :     chdir(workdir,kinfo)
422 :     pfd=os.popen("tar vxjf %s" % mysourcefile,"r")
423 :     trash=data=pfd.read(255)
424 :    
425 :     while trash:
426 :     trash=pfd.read(4096)
427 :    
428 :     if pfd.close():
429 : tmcnulty 1.7 raise BuildError("unable to decompress source file, aborting.")
430 : tmcnulty 1.1
431 :     fnames=split(data)
432 :     name=fnames[0]
433 :    
434 : tmcnulty 1.21 runcmd("rm -rf %s" % kinfo["workdir"], kinfo)
435 : tmcnulty 1.1 move(work + "/" + dirname, kinfo["workdir"])
436 :    
437 :     #restore the previous working ectory
438 :     chdir(cwd,kinfo)
439 :    
440 :     def gkb_patch(kinfo):
441 :     """method that applies patch found in kinfo config files for running kernel build"""
442 :     if kinfo["patches"]:
443 :     patches=split(kinfo["patches"],";")
444 :    
445 :     for patch in patches:
446 :     log("downloading patch %s" % patch,kinfo)
447 :    
448 :     #set a name for this patch file
449 :     mypatchfile="%s/%s/%s.patch" % (patchdir,kinfo["name"],patch)
450 :    
451 :     # download pathfile or bail
452 : tmcnulty 1.21 if runcmd("wget --quiet --output-document=%s %s/patches/%s/%s" % (mypatchfile,msite,kinfo["name"],patch), kinfo):
453 : tmcnulty 1.7 raise BuildError("unable to download patchfile %s, aborting." % patch)
454 : tmcnulty 1.1
455 :     # we have a patch file, apply it or bail
456 :     log("perfoming patch with %s" % patch,kinfo)
457 : tmcnulty 1.16
458 :     # former patchcommand was:
459 :     #patchcommand="patch -p1 < %s > %s/%s/patch-%s.log 2>&1" % (mypatchfile,logdir,kinfo["name"],patch)
460 :     #log("using %s from %s" % (patchcommand,kinfo["workdir"]),kinfo)
461 :    
462 : tmcnulty 1.1 chdir(kinfo["workdir"],kinfo)
463 : tmcnulty 1.21 if runcmd("patch -p1", kinfo, "%s/%s/patch-%s.log" % (logdir,kinfo["name"],patch), False, mypatchfile):
464 : tmcnulty 1.7 raise BuildError("patchfile %s failed, aborting. See patch log for details." % patch)
465 : tmcnulty 1.1 else:
466 :     log("no patchfiles, continuing",kinfo)
467 :    
468 :     def krn_config(kinfo):
469 :     """method to fetch and place config file for running kernel build"""
470 :    
471 : tmcnulty 1.34 if kinfo["configpath"]:
472 :     log("using config file %s" % kinfo["configpath"],kinfo)
473 :     myconfigfile="%s/%s" % (kinfo["workdir"],kinfo["configpath"])
474 :    
475 :     log("copying config file to %s/.config" % kinfo["workdir"],kinfo)
476 :     copy(verifyfile(myconfigfile,kinfo),"%s/.config" % kinfo["workdir"])
477 :    
478 : tmcnulty 1.36 elif kinfo["config"]:
479 : tmcnulty 1.1 log("fetching config file",kinfo)
480 :     myconfigfile="%s/%s.config" % (configdir,kinfo["name"])
481 :    
482 : tmcnulty 1.36 if runcmd("wget --quiet --output-document=%s %s/configs/%s/%s" % (myconfigfile,msite,kinfo["name"],kinfo["config"]), kinfo):
483 : tmcnulty 1.7 raise BuildError("unable to download configfile, aborting.")
484 : tmcnulty 1.1
485 :     log("copying config file to %s/.config" % kinfo["workdir"],kinfo)
486 :     copy(verifyfile(myconfigfile,kinfo),"%s/.config" % kinfo["workdir"])
487 :    
488 :     # Methods to support build()
489 :     def gkb_runmake(command, kinfo, premake, makeopts):
490 :     """Supporting method for build() ... a stub to run a make target and auto log it, given make target (command) and name (kernel name)"""
491 :     log("running make %s" % command,kinfo)
492 : tmcnulty 1.31
493 :     # check to see if we need to run a simple make
494 :     # for some reason 2.2 kernels can't handle premake, makeopts, etc.
495 :     localversion = krn_localversion(kinfo)
496 :    
497 :     if (string.find(localversion,"2.2") == 0):
498 :     if runcmd("%s make %s" % (premake,command), kinfo, "%s/%s/make-%s.log" % (logdir, kinfo["name"], command)):
499 :     raise BuildError("unable to run make %s, aborting." % command)
500 :     else:
501 :     if runcmd("%s make %s %s" % (premake, makeopts, command), kinfo, "%s/%s/make-%s.log" % (logdir, kinfo["name"], command)):
502 :     raise BuildError("unable to run make %s, aborting." % command)
503 : tmcnulty 1.1
504 :     def gkb_parsexml(name):
505 :     """parse the xml build file into mastertrees and builds"""
506 :     def start_element(name, attrs):
507 :     #print "In start_element: %s %s" % (name, attrs)
508 :     if name=="mastertree":
509 :     mastertrees[attrs["name"]]=attrs
510 :     elif name=="build":
511 :     builds[attrs["name"]]=attrs
512 :    
513 :     p = xml.parsers.expat.ParserCreate()
514 :     p.StartElementHandler = start_element
515 :     p.ParseFile(open(name))
516 : tmcnulty 1.3
517 : tmcnulty 1.10 def krn_upload(file, type, version, kinfo):
518 : tmcnulty 1.3 """upload the indicated file to the distribution site (kernel archives)"""
519 : tmcnulty 1.10
520 :     if type=="kernel":
521 :     log("uploading kernel version "+version+" to "+msite,kinfo)
522 :     elif type=="source":
523 :     log("uploading source "+kinfo["mastertree"]+" to "+msite,kinfo)
524 :     else:
525 :     raise BuildException, "invalid file upload type: " + type
526 :    
527 :     forms = ParseResponse(urlopen(msite+"/upload.html"))
528 : tmcnulty 1.3 form = forms[0]
529 :    
530 :     form["host"] = host
531 :     form["pass"] = passwd
532 : tmcnulty 1.10 form["type"] = type
533 :     form["tree"] = kinfo["mastertree"]
534 : tmcnulty 1.3 form["build"] = kinfo["name"]
535 :     form["version"] = version
536 :    
537 : tmcnulty 1.37 #form.add_file(open(file), "application/x-bzip2", os.path.basename(file))
538 :     runcmd("scp %s www.ppckernel.org:%s/%s/" % (os.path.basename(file),uploaddir,kinfo["name"]))
539 : tmcnulty 1.10
540 : tmcnulty 1.3 # form.click() returns a urllib2.Request object
541 :     # (see HTMLForm.click.__doc__ if you don't have urllib2)
542 : tmcnulty 1.10 response = urlopen(form.click("cmd"))
543 : tmcnulty 1.3
544 : tmcnulty 1.10 if debug:
545 :     print response.geturl()
546 :     print response.info() # headers
547 :     print response.read() # body
548 :    
549 : tmcnulty 1.30 log(" \_ response: " + response.read(),kinfo)
550 : tmcnulty 1.3
551 : tmcnulty 1.10 response.close()
552 :    
553 : tmcnulty 1.1 def main():
554 :     """ main program gets executed here """
555 :    
556 :     # get our working ectory
557 :     root=getoutput("pwd")
558 :    
559 :     today=getoutput("date +%D")
560 :     buildtime=getoutput("date +'%R:%S %Z'")
561 :    
562 : tmcnulty 1.25 print "GNU Kernel Builder started %s %s" % (today,buildtime)
563 : tmcnulty 1.1
564 :     # verify the existence important directories, and create if necessary
565 :     verifydir(logdir)
566 :     verifydir(configdir)
567 :     verifydir(patchdir)
568 :     verifydir(bindir)
569 :     verifydir("%s/work" % buildroot) # build dir, make sure it exists
570 :    
571 :     # download the build jobs from the master site
572 : tmcnulty 1.25 log("fetching build jobs from master site")
573 : tmcnulty 1.22 if runcmd("wget --quiet --output-document=gkb.xml \"%s/manager.php?cmd=getjobs&host=%s&pass=%s\"" % (msite,host,passwd)):
574 : tmcnulty 1.25 raise FatalError, "Unable to download build jobs from master site %s, aborting." % msite
575 : tmcnulty 1.1
576 :     # sets up 'mastertrees' and 'builds' dicts
577 :     gkb_parsexml('gkb.xml')
578 :    
579 :     for bdict in builds.values():
580 :     myworkdir="%s/%s" % (workdir,bdict["mastertree"])
581 :     bdict["workdir"]=myworkdir
582 :    
583 : tmcnulty 1.9 try:
584 :     # for now just call the build
585 :     gkb_build(root, bdict)
586 :     except BuildError, e:
587 :     log(e.message, bdict)
588 : tmcnulty 1.12 except KeyboardInterrupt, e:
589 :     log("Caught keyboard interrupt, exiting...")
590 :     break
591 : tmcnulty 1.13
592 : tmcnulty 1.1 endtime=getoutput("date +'%R:%S %Z'")
593 :    
594 :     print "GKB finished %s %s" % (today,endtime)
595 :    
596 :     # and finally, call the mainloop to execute
597 : tmcnulty 1.37 #mail("tmcnulty@ppckernel.org","test subject","test body")
598 : tmcnulty 1.1 main()

Tobias McNulty

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help