code cleanup
[catalyst.git] / catalyst
index a209ffe294a2fb3b8bb9cadb31ddab1a64f61451..070d8a99c9b125f8f3a6a5e0bb89743164c04dc2 100755 (executable)
--- a/catalyst
+++ b/catalyst
 #!/usr/bin/python
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo/src/catalyst/catalyst,v 1.49 2004/10/06 16:00:09 zhen Exp $
 
-import os,sys,imp,string
+# Maintained in full by John Davis <zhen@gentoo.org>
 
-#This allows plugins (and this code) to import modules in the /modules dir
-sys.path.append(os.getcwd()+"/modules")
+import os,sys,imp,string,getopt
 
-from catalyst_support import *
+__maintainer__="John Davis <zhen@gentoo.org>"
+__version__="1.1.0"
+
+conf_values={}
 
 def usage():
-       print "usage: meep!"
+       print "Usage catalyst [options] [-C variable=value...] [ -s identifier]"
+       print " -h --help               print this help message"
+       print " -v --version            display version information"
+       print " -d --debug              enable debugging"
+       print " -c --config             use specified configuration file"
+       print " -C --cli                catalyst commandline (MUST BE LAST OPTION)"
+       print " -f --file               read specfile"
+       print " -V --verbose            verbose output"
+       print " -s --snapshot           generate a Portage snapshot"
+       print
+       print "Usage examples:"
+       print
+       print "Using the commandline option (-C, --cli) to build a Portage snapshot:"
+       print "catalyst -C target=snapshot version_stamp=my_date"
+       print
+       print "Using the snapshot option (-s, --snapshot) to build a Portage snapshot:"
+       print "catalyst -s 2004.3"
+       print
+       print "Using the specfile option (-f, --file) to build a stage target:"
+       print "catalyst -f stage1-specfile.spec"
 
-if len(sys.argv)==1 or sys.argv[1] in ["-h","--help"]:
-       usage()
-       sys.exit(1)
+def version():
+       print "Gentoo Catalyst, version "+__version__
+       print "Copyright 2003-2004 The Gentoo Foundation"
+       print "Distributed under the GNU General Public License version 2\n"
+       
+
+def parse_config(myconfig):
+       # search a couple of different areas for the main config file
+       myconf={}
+       config_file=""
+
+       confdefaults={ "storedir":"/var/tmp/catalyst",\
+               "sharedir":"/usr/share/catalyst","distdir":"/usr/portage/distfiles",\
+               "portdir":"/usr/portage","options":""}
+               
+       # first, try the one passed (presumably from the cmdline)
+       if myconfig:
+               if os.path.exists(myconfig):
+                       print "Using command line specified Catalyst configuration file, "+myconfig
+                       config_file=myconfig
+
+               else:
+                       print "!!! catalyst: Could not use specified configuration file "+\
+                               myconfig
+                       sys.exit(1)
+       
+       # next, try the default location
+       elif os.path.exists("/etc/catalyst/catalyst.conf"):
+               print "Using default Catalyst configuration file, /etc/catalyst/catalyst.conf"
+               config_file="/etc/catalyst/catalyst.conf"
+       
+       # can't find a config file (we are screwed), so bail out
+       else:
+               print "!!! catalyst: Could not find a suitable configuration file"
+               sys.exit(1)
 
-import targets
-targetmap={}
-targets.register(targetmap)
+       # now, try and parse the config file "config_file"
+       try:
+               execfile(config_file, myconf, myconf)
+       
+       except:
+               print "!!! catalyst: Unable to parse configuration file, "+myconfig
+               sys.exit(1)
+       
+       # now, load up the values into conf_values so that we can use them
+       for x in confdefaults.keys():
+               if myconf.has_key(x):
+                       print "Setting",x,"to config file value \""+myconf[x]+"\""
+                       conf_values[x]=myconf[x]
+               else:
+                       print "Setting",x,"to default value \""+confdefaults[x]+"\""
+                       conf_values[x]=confdefaults[x]
 
-print "Available targets:",string.join(targetmap.keys())
+       # parse out the rest of the options from the config file
+       if "ccache" in string.split(conf_values["options"]):
+               print "Compiler cache support enabled."
+               conf_values["CCACHE"]="1"
 
-if os.getuid()!=0:
-       #non-root callers can't go any further than here. 
-       die("This script requires root privileges to operate.") 
+       if "pkgcache" in string.split(conf_values["options"]):
+               print "Package cache support enabled."
+               conf_values["PKGCACHE"]="1"
+       
+       if "distcc" in string.split(conf_values["options"]):
+               print "Distcc support enabled."
+               conf_values["DISTCC"]="1"
 
-myspec={}
-#these would come from /etc/catalyst.conf:
-myspec["storedir"]="/var/tmp/catalyst"
-myspec["sharedir"]="/usr/share/catalyst"
-#these would come from there too?:
-myspec["distdir"]="/mnt/misc/distfiles"
-myspec["portdir"]="/usr/portage"
+       if "autoresume" in string.split(conf_values["options"]):
+               print "Autoresuming support enabled."
+               conf_values["AUTORESUME"]="1"
 
-#determine target, call target constructor and hand it the rest of the arguments
+       if myconf.has_key("envscript"):
+               print "Envscript support enabled."
+               conf_values["ENVSCRIPT"]=myconf["envscript"]
 
-try:
-       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)
+def import_modules():
+       # import catalyst's own modules (i.e. catalyst_support and the arch modules)
+       targetmap={}
        
-       #let's display our spec information in all its glory
-       print
-       spec_dump(myspec)
-       print
+       try:
+               for x in required_build_targets:
+                       try:
+                               fh=open(conf_values["sharedir"]+"/modules/"+x+".py")
+                               module=imp.load_module(x,fh,"modules/"+x+".py",(".py","r",imp.PY_SOURCE))
+                               fh.close()
+               
+                       except IOError:
+                               raise CatalystError,"Can't find "+x+".py plugin in "+\
+                                       conf_values.settings["sharedir"]+"/modules/"
+
+               for x in valid_build_targets:
+                       try:
+                               fh=open(conf_values["sharedir"]+"/modules/"+x+".py")
+                               module=imp.load_module(x,fh,"modules/"+x+".py",(".py","r",imp.PY_SOURCE))
+                               module.register(targetmap)
+                               fh.close()
+               
+                       except IOError:
+                               raise CatalystError,"Can't find "+x+".py plugin in "+\
+                                       conf_values.settings["sharedir"]+"/modules/"
+
+       except ImportError:
+               print "!!! catalyst: Python modules not found in "+\
+                       conf_values["sharedir"]+"/modules; exiting."
+               sys.exit(1)
+
+       return targetmap
+
+def do_spec(myspecfile):
+       try:
+               addlargs=read_spec(myspecfile)
+       except:
+               sys.exit(1)
+               
+       return addlargs
+
+def do_cli(cmdline):
+       try:
+               return arg_parse(cmdline)
+       
+       except CatalystError:
+               print "!!! catalyst: Could not parse commandline, exiting."
+               sys.exit(1)
+       
+def build_target(addlargs, targetmap):
+       try:
+               if not targetmap.has_key(addlargs["target"]):
+                       raise CatalystError,"Target \""+addlargs["target"]+"\" not available."
+               
+               mytarget=targetmap[addlargs["target"]](conf_values, addlargs)
+               mytarget.run()
+
+       except CatalystError:
+               sys.exit(1)
+       
+if __name__ == "__main__":
+       targetmap={}
+       
+       version()
+       if os.getuid() != 0:
+               # catalyst cannot be run as a normal user due to chroots, mounts, etc
+               print "!!! catalyst: This script requires root privileges to operate"
+               sys.exit(2)
+
+       # we need some options in order to work correctly
+       if len(sys.argv) < 2:
+               usage()
+               sys.exit(2)
+
+       # parse out the command line arguments
+       try:
+               opts,args = getopt.getopt(sys.argv[1:], "hvdc:C:f:Vs:", ["help", "version", "debug",\
+                       "config=", "cli=", "file=", "verbose","snapshot="])
+       
+       except getopt.GetoptError:
+               usage()
+               sys.exit(2)
+       
+       # defaults for commandline opts
+       debug=False
+       verbose=False
+       myconfig=""
+       myspecfile=""
+       mycmdline=[]
+       myopts=[]
+
+       # check preconditions
+       if len(opts) == 0:
+               print "!!! catalyst: please specify one of either -f or -C\n"
+               usage()
+               sys.exit(2)
+       
+       # check to see if -f and -C are used together
+       for i in opts:
+               myopts.append(i[0])
+               
+       if ('-f' in myopts or '--file' in myopts) and ('-C' in myopts or '--cli' in myopts):
+               print "!!! catalyst: please specify one of either -f or -C\n"
+               usage()
+               sys.exit(2)
+
+       for o, a in opts:
+               if o in ("-h", "--help"):
+                       usage()
+                       sys.exit(1)
+               
+               if o in ("-v", "--version"):
+                       print "Catalyst version "+__version__
+                       sys.exit(1)
+
+               if o in ("-d", "--debug"):
+                       if len(sys.argv) < 3:
+                               print "!!! catalyst: please specify one of either -f or -C\n"
+                               usage()
+                               sys.exit(2)
+                       else:
+                               conf_values["DEBUG"]="1"
+
+               if o in ("-c", "--config"):
+                       if len(sys.argv) < 3:
+                               print "!!! catalyst: please specify one of either -f or -C\n"
+                               usage()
+                               sys.exit(2)
+                       else:
+                               myconfig=a
+
+               if o in ("-C", "--cli"):
+                       x=sys.argv.index(o)+1
+                       while x < len(sys.argv):
+                               mycmdline.append(sys.argv[x])
+                               x=x+1
+                       
+               if o in ("-f", "--file"):
+                       myspecfile=a
+                       
+               if o in ("-V", "--verbose"):
+                       if len(sys.argv) < 3:
+                               print "!!! catalyst: please specify one of either -f or -C\n"
+                               usage()
+                               sys.exit(2)
+                       else:
+                               conf_values["VERBOSE"]="1"
+
+               if o in ("-s", "--snapshot"):
+                       if len(sys.argv) < 3:
+                               print "!!! catalyst: missing snapshot identifier\n"
+                               usage()
+                               sys.exit(2)
+                       else:
+                               mycmdline.append("target=snapshot")
+                               mycmdline.append("version_stamp="+a)
+       
+       # import configuration file and import our main module using those settings
+       parse_config(myconfig)
+       sys.path.append(conf_values["sharedir"]+"/modules")
+       from catalyst_support import *
+               
+       # import the rest of the catalyst modules
+       targetmap=import_modules()
+
+       if myspecfile:
+               addlargs=do_spec(myspecfile)
+       
+       if mycmdline:
+               addlargs=do_cli(mycmdline)
        
-       mytarget.run()
-except CatalystError:
-       sys.exit(1)
-# Examples:
-# ./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
-# ./catalyst target=snapshot version_stamp=20031028
+       # everything is setup, so the build is a go
+       try:
+               build_target(addlargs, targetmap)
+       except:
+               print "!!! catalyst: could not complete build"
+               sys.exit(2)