code restructure -- things are getting better and better
authorDaniel Robbins <drobbins@gentoo.org>
Tue, 28 Oct 2003 17:09:29 +0000 (17:09 +0000)
committerDaniel Robbins <drobbins@gentoo.org>
Tue, 28 Oct 2003 17:09:29 +0000 (17:09 +0000)
git-svn-id: svn+ssh://svn.gentoo.org/var/svnroot/catalyst/trunk@30 d1e1f19c-881f-0410-ab34-b69fee027534

ChangeLog
arch/x86.py
catalyst
modules/catalyst_support.py
modules/targets.py

index eb9ba5836858d74d2e4eba1b0e78042cf6dd0640..70b61d8f1d6a7e5fc7a63091ec2695aa7d9f68ee 100644 (file)
--- 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 <drobbins@gentoo.org>: Significant rework of code
+  structure. Everything is falling nicely into place.
+  
   28 Oct 2003; Daniel Robbins <drobbins@gentoo.org>: Exception handling fully-
   integrated into current prototype code.
   
index 538d6e036d25ec3dbefb8a5cb1fd51f9ee9295dd..dc4512e45d6758c0d5b4e3a88e37736dd4348fbf 100644 (file)
@@ -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})
                
index f313c22c736ec2bb85927a13045fa08dc93becaa..b00f1c96cb3d78cdd89fa7847383545f1a312f0e 100755 (executable)
--- 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
 
index 1ff8aa8bed3fd11039cb629f2e87907ddc232b9f..afc559d27a3a782431c40e9d6ea6f62cf1afe568 100644 (file)
@@ -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])
+
 
index 97451d6e5a0d79986af2890ce1b5fd455c903656..934622af355b7a6d5937d285a687b1bac1b7dec2 100644 (file)
@@ -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,