From: Daniel Robbins Date: Tue, 28 Oct 2003 17:09:29 +0000 (+0000) Subject: code restructure -- things are getting better and better X-Git-Tag: CATALYST_1_0_1~210 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=dc1d1570963eb59a257a4c4387bb7a1960e792dc;p=catalyst.git code restructure -- things are getting better and better git-svn-id: svn+ssh://svn.gentoo.org/var/svnroot/catalyst/trunk@30 d1e1f19c-881f-0410-ab34-b69fee027534 --- diff --git a/ChangeLog b/ChangeLog index eb9ba583..70b61d8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,10 @@ # ChangeLog for gentoo/src/catalyst # Copyright 2002-2003 Gentoo Technologies, Inc.; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo/src/catalyst/ChangeLog,v 1.7 2003/10/28 14:00:56 drobbins Exp $ - +# $Header: /var/cvsroot/gentoo/src/catalyst/ChangeLog,v 1.8 2003/10/28 17:09:28 drobbins Exp $ + + 28 Oct 2003; Daniel Robbins : Significant rework of code + structure. Everything is falling nicely into place. + 28 Oct 2003; Daniel Robbins : Exception handling fully- integrated into current prototype code. diff --git a/arch/x86.py b/arch/x86.py index 538d6e03..dc4512e4 100644 --- a/arch/x86.py +++ b/arch/x86.py @@ -13,6 +13,7 @@ class generic_x86(builder.generic): def __init__(self,myspec): builder.generic.__init__(self,myspec) self.settings["mainarch"]="x86" + self.settings["CHROOT"]="chroot" class arch_x86(generic_x86): "builder class for generic x86 (486+)" @@ -20,15 +21,66 @@ class arch_x86(generic_x86): generic_x86.__init__(self,myspec) self.settings["CFLAGS"]="-O2 -mcpu=i686 -fomit-frame-pointer" +class arch_i386(generic_x86): + def __init__(self,myspec): + generic_x86.__init__(self,myspec) + self.settings["CFLAGS"]="-O2 -march=i386 -fomit-frame-pointer" + self.settings["CHOST"]="i386-pc-linux-gnu" + +class arch_i486(generic_x86): + def __init__(self,myspec): + generic_x86.__init__(self,myspec) + self.settings["CFLAGS"]="-O2 -march=i486 -fomit-frame-pointer" + self.settings["CHOST"]="i486-pc-linux-gnu" + +class arch_i586(generic_x86): + def __init__(self,myspec): + generic_x86.__init__(self,myspec) + self.settings["CFLAGS"]="-O2 -march=i586 -fomit-frame-pointer" + self.settings["CHOST"]="i586-pc-linux-gnu" + +class arch_pentium_mmx(arch_i586): + def __init__(self,myspec): + arch_i586.__init__(self,myspec) + self.settings["HOSTUSE"]=["mmx"] + +class arch_i686(generic_x86): + def __init__(self,myspec): + generic_x86.__init__(self,myspec) + self.settings["CFLAGS"]="-O2 -march=i686 -fomit-frame-pointer" + self.settings["CHOST"]="i686-pc-linux-gnu" + +class arch_athlon(generic_x86): + def __init__(self,myspec): + generic_x86.__init__(self,myspec) + self.settings["CFLAGS"]="-O2 -march=athlon -fomit-frame-pointer" + self.settings["CHOST"]="i686-pc-linux-gnu" + self.settings["HOSTUSE"]=["mmx","3dnow"] + +class arch_athlon_xp(generic_x86): + #this handles XP and MP processors + def __init__(self,myspec): + generic_x86.__init__(self,myspec) + self.settings["CFLAGS"]="-O2 -march=athlon-xp -fomit-frame-pointer" + self.settings["CHOST"]="i686-pc-linux-gnu" + self.settings["HOSTUSE"]=["mmx","3dnow"] + class arch_pentium4(generic_x86): - "builder class for Pentium 4" def __init__(self,myspec): generic_x86.__init__(self,myspec) self.settings["CFLAGS"]="-O2 -march=pentium4 -fomit-frame-pointer -finline-functions -finline-limit=800" self.settings["CHOST"]="i686-pc-linux-gnu" self.settings["HOSTUSE"]=["mmx","sse"] +class arch_pentium3(generic_x86): + def __init__(self,myspec): + generic_x86.__init__(self,myspec) + self.settings["CFLAGS"]="-O2 -march=pentium3 -fomit-frame-pointer -finline-functions -finline-limit=800" + self.settings["CHOST"]="i686-pc-linux-gnu" + self.settings["HOSTUSE"]=["mmx","sse"] + def register(foo): "Inform main catalyst program of the contents of this plugin." - foo.update({"pentium4":arch_pentium4,"x86":arch_x86}) + foo.update({"pentium4":arch_pentium4,"x86":arch_x86,"i386":arch_i386,"i486":arch_i486,"i586":arch_i586,"i686":arch_i686,"athlon":arch_athlon, + "athlon-xp":arch_athlon_xp,"athlon-mp":arch_athlon_xp,"pentium3":arch_pentium3,"pentium-mmx":arch_pentium_mmx}) diff --git a/catalyst b/catalyst index f313c22c..b00f1c96 100755 --- a/catalyst +++ b/catalyst @@ -13,22 +13,6 @@ def usage(): if len(sys.argv)==1 or sys.argv[1] in ["-h","--help"]: usage() sys.exit(1) - -def arg_parse(mydict, myvalids): - "very wimpy argument parsing, just for the prototype" - for x in sys.argv[1:]: - foo=string.split(x,"=") - if len(foo)!=2: - die("Invalid arg syntax: "+x) - else: - if foo[0] not in myvalids: - die("Invalid arg name: "+foo[0]) - mydict[foo[0]]=foo[1] - -def spec_dump(myspec): - for x in myspec.keys(): - print x+": "+repr(myspec[x]) - """ Overview of catalyst operation ============================== @@ -46,10 +30,6 @@ Overview of catalyst operation be a standard python dictionary. This spec dictionary contains all relevant build-related information. -* The spec object is passed to the appropriate subarch builder constructor. - The subarch builder constructor updates the spec object with variables - relevant to the sub-arch (pentium4, g3, etc.) - * The spec object is passed to the appropriate target constructor. The target constructor updates the spec object to contain data relevant to the particular target (stage1, stage3, grp, etc.) @@ -78,41 +58,6 @@ Overview of catalyst operation #map current machine information from uname() to the mainarch we are running #under -machinemap={ "i386" : "x86", - "i486" : "x86", - "i586" : "x86", - "i686" : "x86", - "x86_64" : "amd64" - } - -# map the mainarch we are running under to the mainarches we support for -# building stages and LiveCDs. (for example, on amd64, we can build stages for -# x86 or amd64. - -targetmap={ "x86" : ["x86"], - "amd64" : ["x86","amd64"] - } - -mymachine=os.uname()[4] -if not machinemap.has_key(mymachine): - die("Unknown machine type: "+mymachine) -hostarch=machinemap[mymachine] -print "Host architecture:",hostarch -print "Supported architectures for targets:",string.join(targetmap[hostarch]) -print "Loading plugins:", -archmap={} -subarchmap={} -for x in targetmap[hostarch]: - fh=open("arch/"+x+".py") - #this next line loads the plugin as a module and assigns it to archmap[x] - archmap[x]=imp.load_module(x,fh,"arch/"+x+".py",(".py","r",imp.PY_SOURCE)) - #this next line registers all the subarches supported in the plugin - archmap[x].register(subarchmap) - fh.close() - print x, -print -print "Available subarches:",string.join(subarchmap.keys()) - import targets targetmap={} targets.register(targetmap) @@ -123,32 +68,7 @@ if os.getuid()!=0: #non-root callers can't go any further than here. die("This script requires root privileges to operate.") -#the spec begins! -validspec=["version_stamp","target","subarch","rel_type","rel_version","snapshot","source_subpath"] myspec={} - -""" -local variables from spec: - -version_stamp 20031016 user (from spec) -target stage3 user (from spec) -subarch pentium4 user (from spec) -rel_type default user (from spec) (was BUILDTYPE) -rel_version 1.4 user (from spec) (was MAINVERSION) -snapshot 20031016 user (from spec) -source_subpath default-x86-1.4/stage2-pentium4-20031016 user (from spec) -""" - -arg_parse(myspec,validspec) -#need to verify that we have all required args here. Leaving this out for the prototype. -if myspec["subarch"] not in subarchmap.keys(): - die("Sub-arch "+myspec["subarch"]+" not available.") - -#call builder constructor: -mybuilder=subarchmap[myspec["subarch"]](myspec) -if myspec["target"] not in targetmap.keys(): - die("Target "+myspec["target"]+" not available.") - #these would come from /etc/catalyst.conf: myspec["storedir"]="/var/tmp/catalyst" myspec["sharedir"]="/usr/share/catalyst" @@ -156,14 +76,17 @@ myspec["sharedir"]="/usr/share/catalyst" myspec["distdir"]="/usr/portage/distfiles" myspec["portdir"]="/usr/portage" -#call target constructor: -mytarget=targetmap[myspec["target"]](myspec) -print -spec_dump(myspec) +#all the main program needs to do is figure out the target. The rest of the args go to the +#target constructor -mytarget.run() +#call target constructor, pass our "myspec" settings as well as cmdline arguments for parsing -#to test this program, type: +addlargs={} +arg_parse(myspec,addlargs) +if not targetmap.has_key(myspec["target"]): + raise CatalystError,"Target \""+myspec["target"]+"\" not available." +mytarget=targetmap[myspec["target"]](myspec,addlargs) +mytarget.run() # ./catalyst subarch=pentium4 version_stamp=20031016 target=stage3 rel_type=default rel_version=1.4 snapshot=20031016 source_subpath=default-x86-1.4/stage2-pentium4-20031016 diff --git a/modules/catalyst_support.py b/modules/catalyst_support.py index 1ff8aa8b..afc559d2 100644 --- a/modules/catalyst_support.py +++ b/modules/catalyst_support.py @@ -1,4 +1,6 @@ -import sys +import sys,string + +config_file_values=["storedir","sharedir","distdir","portdir"] class CatalystError(Exception): def __init__(self, message): @@ -12,4 +14,35 @@ def die(msg=None): def warn(msg): print "catalyst: "+msg +def arg_parse(mydict,remaining={}): + global config_file_values + for x in sys.argv[1:]: + foo=string.split(x,"=") + if len(foo)!=2: + raise CatalystError, "Invalid arg syntax: "+x + remaining[foo[0]]=foo[1] + if not remaining.has_key("target"): + raise CatalystError, "Required value \"target\" not specified." + mydict["target"]=remaining["target"] + for x in config_file_values: + if not mydict.has_key(x): + raise CatalystError, "Required config file value \""+x+"\" not found." + + +def addl_arg_parse(myspec,addlargs,requiredspec,validspec): + "helper function to help targets parse additional arguments" + global config_file_values + for x in addlargs.keys(): + if x not in validspec and x not in config_file_values: + raise CatalystError, "Argument \""+x+"\" not recognized." + else: + myspec[x]=addlargs[x] + for x in requiredspec: + if not myspec.has_key(x): + raise CatalystError, "Required argument \""+x+"\" not specified." + +def spec_dump(myspec): + for x in myspec.keys(): + print x+": "+repr(myspec[x]) + diff --git a/modules/targets.py b/modules/targets.py index 97451d6e..934622af 100644 --- a/modules/targets.py +++ b/modules/targets.py @@ -1,17 +1,63 @@ -import os,stat +import os,stat,string,imp from catalyst_support import * class generic_target: - def __init__(self,myspec): + def __init__(self,myspec,addlargs): + addl_arg_parse(myspec,addlargs,self.required_values,self.valid_values) self.settings=myspec pass class generic_stage_target(generic_target): - def __init__(self,myspec): - generic_target.__init__(self,myspec) - #we'd want to make sure we have all the settings we need here + def __init__(self,myspec,addlargs): + + self.required_values=["version_stamp","target","subarch","rel_type","rel_version","snapshot","source_subpath"] + self.valid_values=self.required_values + generic_target.__init__(self,addlargs,myspec) + + #ensure we have all required user-supplied settings before proceeding + for x in requiredspec: + if not self.settings.has_key(x): + raise CatalystError, "Required value \""+x+"\" not specified." + + # map the mainarch we are running under to the mainarches we support for + # building stages and LiveCDs. (for example, on amd64, we can build stages for + # x86 or amd64. + + targetmap={ "x86" : ["x86"], + "amd64" : ["x86","amd64"] + } + + machinemap={ "i386" : "x86", + "i486" : "x86", + "i586" : "x86", + "i686" : "x86", + "x86_64" : "amd64" + } + + + mymachine=os.uname()[4] + if not machinemap.has_key(mymachine): + raise CatalystError, "Unknown machine type "+mymachine + self.settings["hostarch"]=machinemap[mymachine] + print "Host architecture:",self.settings["hostarch"] + print "Supported architectures for targets:",string.join(targetmap[self.settings["hostarch"]]) + print "Loading all valid plugins for this machine:", + self.archmap={} + self.subarchmap={} + for x in targetmap[self.settings["hostarch"]]: + fh=open("arch/"+x+".py") + #this next line loads the plugin as a module and assigns it to archmap[x] + self.archmap[x]=imp.load_module(x,fh,"arch/"+x+".py",(".py","r",imp.PY_SOURCE)) + #this next line registers all the subarches supported in the plugin + self.archmap[x].register(self.subarchmap) + fh.close() + print x, + print + print "Available subarches:",string.join(self.subarchmap.keys()) + #call arch constructor, pass our settings + self.arch=self.subarchmap[self.settings["subarch"]](self.settings) self.settings["target_subpath"]=self.settings["rel_type"]+"-"+self.settings["mainarch"]+"-"+self.settings["rel_version"] self.settings["target_subpath"]+="/"+self.settings["target"]+"-"+self.settings["subarch"]+"-"+self.settings["version_stamp"] st=self.settings["storedir"] @@ -51,15 +97,24 @@ class generic_stage_target(generic_target): retval=os.system("tar xjpf "+self.settings["source_path"]+" -C "+self.settings["chroot_path"]) if retval!=0: raise CatalystError,"Error unpacking tarball" - for x in [[self.settings["portdir"],"/usr/portage"],[self.settings["distdir"],"/usr/portage/distfiles"], + retval=os.system("tar xjpf "+self.settings["snapshot_path"]+" -C "+self.settings["chroot_path"]+"/usr") + if retval!=0: + raise CatalystError,"Error unpacking snapshot" + for x in [[self.settings["distdir"],"/usr/portage/distfiles"], ["/proc","/proc"],["/dev","/dev"]]: - retval=os.system("mount --bind "+x[0]+" "+x[1]) - if not retval: + if not os.path.exists(self.settings["chroot_path"]+x[1]): + os.makedirs(self.settings["chroot_path"]+x[1]) + + retval=os.system("mount --bind "+x[0]+" "+self.settings["chroot_path"]+x[1]) + if retval!=0: self.unbind() raise CatalystError,"Couldn't bind mount "+x[0] def unbind(self): - pass + for x in ["/usr/portage/distfiles","/proc","/dev"]: + retval=os.system("umount "+self.settings["chroot_path"]+x) + if retval!=0: + warning("Couldn't umount bind mount: "+self.settings["chroot_path"]+x) def setup(self): #setup will leave everything in unbound state if there is a failure @@ -75,19 +130,28 @@ class generic_stage_target(generic_target): self.unbind() class snapshot_target(generic_target): - def __init__(self): + def __init__(self,myspec,addlargs): + self.valid_values=["version_stamp","target"] + self.required_values=self.valid_values + generic_target.__init__(myspec,addlargs) + + self.settings=myspec + if not self.settings.has_key("version_stamp"): + raise CatalystError, "Required value \"version_stamp\" not specified." self.settings["target_subpath"]="portage-"+self.settings["version_stamp"] st=self.settings["storedir"] self.settings["snapshot_path"]=st+"/snapshots/"+self.settings["target_subpath"]+".tar.bz2" self.settings["tmp_path"]=st+"/tmp/"+self.settings["target_subpath"] def setup(self): - #nothing to do here - pass + x=self.settings["storedir"]+"/snapshots" + if not os.path.exists(x): + os.makedirs(x) def run(self): - print "Creating Portage tree snapshot "+snapversion+" from "+portdir+"..." - mytmp=self.settings["tmp_path"]+"/"+self.settings["target_subpath"] + self.setup() + print "Creating Portage tree snapshot "+self.settings["version_stamp"]+" from "+self.settings["portdir"]+"..." + mytmp=self.settings["tmp_path"] if os.path.exists(mytmp): retval=os.system("rm -rf "+mytmp) if retval != 0: @@ -97,7 +161,7 @@ class snapshot_target(generic_target): if retval != 0: raise CatalystError,"Snapshot failure" print "Compressing Portage snapshot tarball..." - retval=os.system("( cd "+mytmp+"; tar cjf "+self.settings["snapshot_path"]+"/portage-"+self.settings["snapversion"]+".tar.bz2 portage )") + retval=os.system("tar cjf "+self.settings["snapshot_path"]+" -C "+mytmp+" portage") if retval != 0: raise CatalystError,"Snapshot creation failure" self.cleanup() @@ -111,29 +175,24 @@ class snapshot_target(generic_target): raise CatalystError,"Snapshot cleanup failure" class stage1_target(generic_stage_target): - def __init__(self,spec): - generic_stage_target.__init__(self,spec) - pass + def __init__(self,spec,addlargs): + generic_stage_target.__init__(self,spec,addlargs) class stage2_target(generic_stage_target): - def __init__(self,spec): - generic_stage_target.__init__(self,spec) - pass + def __init__(self,spec,addlargs): + generic_stage_target.__init__(self,spec,addlargs) class stage3_target(generic_stage_target): - def __init__(self,spec): - generic_stage_target.__init__(self,spec) - pass + def __init__(self,spec,addlargs): + generic_stage_target.__init__(self,spec,addlargs) class grp_target(generic_stage_target): - def __init__(self,spec): - generic_target.__init__(self,spec) - pass + def __init__(self,spec,addlargs): + generic_stage_target.__init__(self,spec,addlargs) class livecd_target(generic_stage_target): - def __init__(self): - generic_target.__init__(self) - pass + def __init__(self,spec,addlargs): + generic_target.__init__(self,spec,addlargs) def register(foo): foo.update({"stage1":stage1_target,"stage2":stage2_target,"stage3":stage3_target,