#!/usr/bin/python -OO # Maintained in full by: # Andrew Gaffney # Chris Gianelloni # $Id$ import os, sys, getopt # This assumes that our modules are in a sub-dir named "modules" in the # directory that the main catalyst binary is in __selfpath__ = os.path.abspath(os.path.dirname(__file__)) sys.path.append(__selfpath__ + "/modules") import catalyst from catalyst.output import * from catalyst.error import * from catalyst.hash import hash_map __maintainer__="Chris Gianelloni " __version__="2.99" conf_values = {} config = catalyst.config.config() def usage(): print "Usage catalyst [options] [-C variable=value...] [ -s identifier]" print " -a --clear-autoresume clear autoresume flags" print " -c --config use specified configuration file" print " -C --cli catalyst commandline (MUST BE LAST OPTION)" print " -d --debug enable debugging" print " -f --file read specfile" print " -F --fetchonly fetch files only" print " -h --help print this help message" print " -p --purge clear tmp dirs,package cache and autoresume flags" print " -P --purgeonly clear tmp dirs,package cache and autoresume flags and exit" print " -s --snapshot generate a release snapshot" print " -V --version display version information" print " -v --verbose verbose output" 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 release snapshot:" print "catalyst -s 20071121" print print "Using the specfile option (-f, --file) to build a stage target:" print "catalyst -f stage1-specfile.spec" def show_version(): msg("Catalyst, version " + __version__) msg("Copyright 2003-2008 Gentoo Foundation") msg("Copyright 2008 various authors") msg("Distributed under the GNU General Public License version 2.1") def parse_config(): # search a couple of different areas for the main config file myconf = {} confdefaults = { "storedir": "/var/tmp/catalyst", "sharedir": "/usr/share/catalyst", "distdir": "/usr/portage/distfiles", "portdir": "/usr/portage", "options": "", "snapshot_cache": "/var/tmp/catalyst/snapshot_cache", "hash_function": "crc32" } # first, try the one passed (presumably from the cmdline) if "config_file" in conf_values: if os.path.exists(conf_values["config_file"]): msg("Using command line specified Catalyst configuration file, " + conf_values["config_file"]) else: die("specified configuration file " + conf_values["config_file"] + " does not exist") # next, try the default location elif os.path.exists("/etc/catalyst/catalyst.conf"): msg("Using default Catalyst configuration file, /etc/catalyst/catalyst.conf") conf_values["config_file"] = "/etc/catalyst/catalyst.conf" # can't find a config file (we are screwed), so bail out else: die("Could not find a suitable configuration file") # Load the default config values into myconf for x in confdefaults: msg("Setting " + x + " to default value '" + confdefaults[x] + "'") myconf[x] = confdefaults[x] # now, try and parse the config file "config_file" try: myconfig = catalyst.config.ConfigParser(conf_values["config_file"]) myconf.update(myconfig.get_values()) except: die("Unable to parse configuration file, " + conf_values["config_file"]) # now, load up the values into conf_values so that we can use them for x in confdefaults.keys(): if x in myconf: msg("Setting " + x + " to config file value '" + myconf[x] + "'") conf_values[x] = myconf[x] else: msg("Setting " + x + " to default value '" + confdefaults[x] + "'") conf_values[x] = confdefaults[x] options = ( ("autoresume", "AUTORESUME", "Autoresuming support enabled."), ("ccache", "CCACHE", "Compiler cache support enabled."), ("clear-autoresume", "CLEAR_AUTORESUME", "Cleaning autoresume flags support enabled"), # ("compress", "COMPRESS", "Compression enabled."), ("distcc", "DISTCC", "Distcc support enabled."), ("icecream", "ICECREAM", "Icecream compiler cluster support enabled."), ("kerncache", "KERNCACHE", "Kernel cache support enabled."), ("pkgcache", "PKGCACHE", "Package cache support enabled."), ("purge", "PURGE", "Purge support enabled."), ("seedcache", "SEEDCACHE", "Seed cache support enabled."), ("snapcache", "SNAPCACHE", "Snapshot cache support enabled."), # ("tarball", "TARBALL", "Tarball creation enabled.") ) split_options = conf_values["options"].split() # parse out the rest of the options from the config file for x in options: if x[0] in split_options: msg(x[2]) conf_values[x[1]] = "1" if "digests" in myconf: conf_values["digests"] = myconf["digests"] if "contents" in myconf: conf_values["contents"] = myconf["contents"] if "envscript" in myconf: msg("Envscript support enabled.") conf_values["ENVSCRIPT"] = myconf["envscript"] def verify_digest_and_hash_functions(): # Start checking that digests are valid now that the hash_map was imported from catalyst_support if "digests" in conf_values: for i in conf_values["digests"].split(): if not i in hash_map: msg() msg(i + " is not a valid digest entry") msg("Valid digest entries:") msg("\n".join(hash_map.keys())) msg() msg("Catalyst aborting....") sys.exit(2) if catalyst.util.find_binary(hash_map[i][1]) == None: msg() msg("digest=" + i) msg("\tThe " + hash_map[i][1] + \ " binary was not found. It needs to be in your system path") msg() msg("Catalyst aborting....") sys.exit(2) if "hash_function" in conf_values: if not conf_values["hash_function"] in hash_map: msg() msg(conf_values["hash_function"] + " is not a valid hash_function entry") msg("Valid hash_function entries:") msg("\n".join(hash_map.keys())) msg() msg("Catalyst aborting....") sys.exit(2) if catalyst.util.find_binary(hash_map[conf_values["hash_function"]][1]) == None: msg() msg("hash_function=" + conf_values["hash_function"]) msg("\tThe " + hash_map[conf_values["hash_function"]][1] + \ " binary was not found. It needs to be in your system path") msg() msg("Catalyst aborting....") sys.exit(2) def parse_commandline(): # parse out the command line arguments try: opts,args = getopt.getopt(sys.argv[1:], "apPhvdc:C:f:FVs:", ["purge", "purgeonly", "help", "version", "debug",\ "clear-autoresume", "config=", "cli=", "file=", "fetch", "verbose","snapshot="]) except getopt.GetoptError: usage() sys.exit(2) # defaults for commandline opts conf_values["command_line"] = [] # check preconditions if len(opts) == 0: warn("please specify one of either -f or -C\n") usage() sys.exit(2) run = False for o, a in opts: if o in ("-h", "--help"): usage() sys.exit(1) if o in ("-V", "--version"): show_version() sys.exit(1) if o in ("-d", "--debug"): conf_values["DEBUG"]="1" conf_values["VERBOSE"]="1" if o in ("-c", "--config"): conf_values["config_file"] = a if o in ("-C", "--cli"): run = True x = sys.argv.index(o) + 1 while x < len(sys.argv): conf_values["command_line"].append(sys.argv[x]) x = x + 1 if o in ("-f", "--file"): run = True conf_values["spec_file"] = a if o in ("-F", "--fetchonly"): conf_values["FETCH"] = "1" if o in ("-v", "--verbose"): conf_values["VERBOSE"] = "1" if o in ("-s", "--snapshot"): if len(sys.argv) < 3: warn("missing snapshot identifier") usage() sys.exit(2) else: run = True conf_values["command_line"].append("target=snapshot") conf_values["command_line"].append("version_stamp="+a) if o in ("-p", "--purge"): conf_values["PURGE"] = "1" if o in ("-P", "--purgeonly"): conf_values["PURGEONLY"] = "1" if o in ("-a", "--clear-autoresume"): conf_values["CLEAR_AUTORESUME"] = "1" if not run: warn("please specify one of either -f or -C") usage() sys.exit(2) if __name__ == "__main__": show_version() if os.getuid() != 0: # catalyst cannot be run as a normal user due to chroots, mounts, etc die("This script requires root privileges to operate", 2) parse_commandline() parse_config() verify_digest_and_hash_functions() targetmap = catalyst.target.build_target_map() spec = catalyst.config.Spec() if "spec_file" in conf_values: specparser = catalyst.config.SpecParser(conf_values["spec_file"]) spec_values = specparser.get_values() spec.parse_values(spec_values) if "command_line" in conf_values: try: cmdline = catalyst.config.ConfigParser() cmdline.parse_lines(conf_values["command_line"]) cmdline_values = cmdline.get_values() spec.parse_values(cmdline_values) except CatalystError: die("Could not parse commandline, exiting.") config.set_spec(spec) config.set_conf(conf_values) config.set_targetmap(targetmap) # everything is setup, so the build is a go try: catalyst.target.build_targets() except CatalystError: msg() msg("Catalyst aborting....") sys.exit(2) except KeyboardInterrupt: msg() msg("Catalyst build aborted due to user interrupt ( Ctrl-C )") msg() msg("Catalyst aborting....") sys.exit(2) except LockInUse: msg("Catalyst aborting....") sys.exit(2) except: msg("Catalyst aborting....") raise sys.exit(2) #except KeyError: # print "\nproblem with command line or spec file ( Key Error )" # print "Key: "+str(sys.exc_value)+" was not found" # print "Catalyst aborting...." # sys.exit(2) #except UnboundLocalError: # print # print "UnboundLocalError: "+str(sys.exc_value)+" was not found" # raise # print # print "Catalyst aborting...." # sys.exit(2)