#!/usr/bin/env python """ Installation Wizard launching script. This script is the part of the SALOME installation procedure. Author : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com) Created : Thu Dec 18 12:01:00 2002 Copyright : 2002-2006 CEA """ __version__ = "1.0.1" # --- avoid "deprecation" warnings --- # import warnings warnings.filterwarnings("ignore", "", DeprecationWarning) # --- imports --- # import xmllib import sys, os, string, re import types import random # --- global variables --- # opt_parser = None root_path = None # --- XML tags definition --- # __TAG__SOURCES__ = "install sources" __TAG__BINARIES__ = "install binaries" __TAG__NATIVE__ = "use native" __TAG__PREINSTALL__ = "not install" #------------------------------------------------------------------# # # # COMMAND LINE ARGUMENTS PARSER # # # #------------------------------------------------------------------# #=================================================================== # class OptBaseError : base parse error #=================================================================== class OptBaseError(Exception): """ Base option parsing exception class """ def __init__(self, msg): self.msg = msg def __str__ (self): return self.msg #=================================================================== # class OptError : bad option error #=================================================================== class OptError(OptBaseError): """ Bad option exception class """ def __init__ (self, msg, option): self.msg = msg self.option = option def __str__ (self): if self.option: opt_prs = "" if self.option.short_opt and self.option.long_opt: opt_prs = "%s/%s"%(self.option.short_opt,self.option.long_opt) elif self.option.short_opt: opt_prs = "%s"%(self.option.short_opt) elif self.option.long_opt: opt_prs = "%s"%(self.option.long_opt) return "option %s: %s"%(opt_prs, self.msg) return self.msg #=================================================================== # class ArgError : bad option argument error #=================================================================== class ArgError(OptBaseError): """ Bad argument exception class """ pass #=================================================================== # class ValError : bad command line parameter error #=================================================================== class ValError(OptBaseError): """ Bad parameter exception class """ pass #=================================================================== # class ArgOption : command line option #=================================================================== class ArgOption: """ Option class """ attrs = ["short_opt", "long_opt", "dest", "action", "type", "default", "metavar", "help"] actions = ["store", "store_true", "store_false"] types = ["string", "int", "float", "bool"] def __init__(self, *args, **kwargs): # set defaults for attr in self.attrs: setattr(self, attr, None) # parse arguments for i in range(len(args)): if i > len(self.attrs)-1: msg = "Wrong number of parameters is given (maximum is %d)" % len(self.attrs) raise OptBaseError(msg) setattr(self, self.attrs[i], args[i]) for arg in kwargs: if arg not in self.attrs: msg = "Invalid argument: %s" % arg raise OptBaseError(msg) setattr(self, arg, kwargs[arg]) # check short option key if self.short_opt and \ not re.match("^-[a-zA-Z]$",self.short_opt): msg = "invalid short option key; " msg += "should be of the form -x (x is letter)" raise OptError(msg, self) # check long option key if self.long_opt and \ not re.match("^--[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*$",self.long_opt): msg = "invalid long option key; " msg += "should be of the form --word[[-word]...] " msg += "(word is letters and digits sequence)" raise OptError(msg, self) # check that at least one option key is defined if not self.short_opt and not self.long_opt: msg = "invalid option; neither short nor long option key is defined" raise OptError(msg, self) # destination if not self.dest and self.long_opt: self.dest = self.long_opt[2:].replace('-','_') if not self.dest and self.short_opt: self.dest = self.short_opt[1:] # action if not self.action: self.action = "store" if self.action not in self.actions: msg = "invalid action: %s" % self.action raise OptError(msg, self) # type if not self.type: if self.action in ["store_true","store_false"]: self.type = "bool" else: self.type = "string" if self.type not in self.types: msg = "invalid type: %s" % self.type raise OptError(msg, self) if self.action in ["store_true","store_false"] and self.type != "bool": msg = "invalid type: %s : should be 'bool' or None" % self.type raise OptError(msg, self) # default if self.default: try: if self.type == "string": self.default = str(self.default) if self.type == "int": self.default = int(self.default) if self.type == "float": self.default = float(self.default) if self.type == "bool": self.default = boolean(self.default) except : msg = "invalid default value type: should be %s" % self.type raise OptError(msg, self) pass # metavar if not self.metavar: self.metavar = self.dest.upper() # help if not self.help: self.help = "" pass def to_string(self): """ Returns string representation of the option """ opts = [] opt = self.short_opt if opt and self.action == "store" and self.metavar: opt += " %s" % self.metavar if opt: opts.append(opt) opt = self.long_opt if opt and self.action == "store" and self.metavar: opt += "=%s" % self.metavar if opt: opts.append(opt) return (", ").join(opts) #=================================================================== # class Values : resulting option values #=================================================================== class Values: """ Values class """ def __init__(self): pass #=================================================================== # class ArgParser : command line arguments parser #=================================================================== class ArgParser: """ Arguments parser class """ def __init__(self): self.options = [] pass def add_option(self, *args, **kwargs): """Register an option""" o = ArgOption(*args, **kwargs) self._check_option(o) self.options.append(o) pass def parse_args(self, args = None): """Parse an arguments""" if not args: args = sys.argv[1:] values = Values() for o in self.options: if o.default: setattr(values, o.dest, o.default) elif not hasattr(values,o.dest): setattr(values, o.dest, None) try: (values, args) = self._process_args(values, args) except (ArgError, ValError), e: self._error(e.msg) return (values, args) def print_usage(self): """Print usage""" print "usage: %s [options]" % os.path.basename(sys.argv[0]) pass def print_help(self): """Print help""" self.print_usage() print "" olen = 0 _maxwidth, _indent = 79, 2 if len(self.options): for option in self.options: if olen < len(option.to_string()): olen = len(option.to_string()) print "options:" for option in self.options: strings = [] for hs in option.help.split("\n"): s = "" for w in hs.split(): if len("%s %s" % (s,w)) > _maxwidth: strings.append(s.strip()); s = "" s = "%s %s" % (s,w) if s.strip(): strings.append(s.strip()) if not strings: strings[:0] = [""] print "%s%s%s" % (option.to_string(), " "*(_indent+olen-len(option.to_string())), strings[0]) for i in range(1, len(strings)): print "%s%s" % (" "*(olen+_indent), strings[i]) pass def _check_option(self, option): o = self._get_option(option.short_opt) if not o: o = self._get_option(option.long_opt) if o: msg = "option conflicts with previously defined option(s)" raise OptError(msg, option) pass def _get_option(self, opt_key): if opt_key: for o in self.options: if opt_key in [o.short_opt, o.long_opt]: return o return None def _error(self, msg): self.print_usage() sys.exit("\n%s: error: %s\n" % (os.path.basename(sys.argv[0]), msg)) pass def _check_value(self, option, value): o = self._get_option(option) try: if o.type == "string": return str(value) if o.type == "int": return int(value) if o.type == "float": return float(value) if o.type == "bool": return boolean(value) except: msg = "invalid value type for option %s: %s; " % (option, value) msg += "should be %s" % o.type raise ValError(msg) raise OptBaseError("unknown error") def _process_args(self, values, args): res_args = [] cur_opt = None rargs = [] for index in range(len(args)): a = args[index] if cur_opt and cur_opt[1].action == "store": setattr(values, cur_opt[1].dest, self._check_value(cur_opt[0], a)) cur_opt = None continue if a == "-": rargs = args[index+1:] break elif re.match("^-[a-zA-Z].*", a): for i in range(1,len(a)): if cur_opt and cur_opt[1].action == "store": setattr(values, cur_opt[1].dest, self._check_value(cur_opt[0], a[i:])) cur_opt = None break o = self._get_option("-%s"%a[i]) if not o: raise ArgError("no such option: -%s"%a[i]) if o.action == "store_true": setattr(values, o.dest, True) elif o.action == "store_false": setattr(values, o.dest, False) else: cur_opt = ("-%s"%a[i], o) pass elif re.match("^--[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*", a): oname = ("%s="%a).split("=")[0] ovalue = ("%s="%a).split("=")[1] o = self._get_option(oname) if not o: raise ArgError("no such option: %s" % oname) if o.action == "store_true": if ovalue: raise ValError("option %s does not take a value" % oname) setattr(values, o.dest, True) elif o.action == "store_false": if ovalue: raise ValError("option %s does not take a value" % oname) setattr(values, o.dest, False) else: if ovalue: setattr(values, o.dest, self._check_value(oname, ovalue)) else: cur_opt = (oname, o) pass elif a.startswith("-"): raise ArgError("bad formatted option: %s" % a) else: rargs = args[index:] break if cur_opt and cur_opt[1].action == "store": raise ValError("option %s requires value" % cur_opt[0]) return (values, rargs) #------------------------------------------------------------------# # # # XML CONFIGURATION FILES PARSER # # # #------------------------------------------------------------------# #=================================================================== # class Config : general configuration options : version, OS, etc... #=================================================================== class Config : """ General configuration file options: - Install Wizard window caption - SALOME platform version - Copyright and libcense info - Target Linux OS version """ def __init__(self, theVersion = None, theCaption = None, theCopyright = None, theLicense = None, theOS = None): self.version = strip(theVersion) self.caption = strip(theCaption) self.copyright = strip(theCopyright) self.license = strip(theLicense) self.os = strip(theOS) #=================================================================== # class Path : default target, temporary directories options #=================================================================== class Path : """ Path options: - default target directory - default temporary directory """ def __init__(self, theTargetdir = None, theTmpdir = None): self.targetdir = strip(theTargetdir) self.tmpdir = strip(theTmpdir) #============================================================== # class Product : pre-requisite product options #============================================================== class Product : """ Product options: - name, version - supported installation modes and the default one - dependencies - required disk space - installation script - etc... """ def __init__(self, theName, theVersion = None, theInstall = None, theSupportred = None, theDependencies = None, theInstalldiskspace = None, theTemporarydiskspace = None, theScript = None, thePickUpEnvironment = None): self.name = strip(theName) self.version = strip(theVersion) self.install = strip(theInstall) self.supported = strip(theSupportred) self.dependencies = strip(theDependencies) self.installdiskspace = strip(theInstalldiskspace) self.temporarydiskspace = strip(theTemporarydiskspace) self.script = strip(theScript) self.pickupEnv = strip(thePickUpEnvironment) #=================================================================== # class ConfigParser : XML files parser implementation #=================================================================== class ConfigParser(xmllib.XMLParser): """ XML configuration files parser """ def __init__(self): xmllib.XMLParser.__init__(self) self.products = [] self.currentdata = [] self.path = None self.config = None def handle_data(self, data): self.currentdata.append(data) def start_product(self, attrs): if not attrs.get('name', '').strip(): return if check_bool(attrs.get('disable', 'false')): return aProduct = Product(attrs.get('name'), attrs.get('version', None), attrs.get('install', None), attrs.get('supported', None), attrs.get('dependancies', None), attrs.get('installdiskspace', None), attrs.get('temporarydiskspace', None), attrs.get('script', None), attrs.get('pickupenv', None)) self.products.append(aProduct) pass def end_product(self): pass def start_config(self, attrs): self.config = Config(attrs.get('version', None), attrs.get('caption', None), attrs.get('copyright', None), attrs.get('license', None), attrs.get('os', None)) pass def end_config(self): pass def start_path (self, attrs): self.path = Path(attrs.get('targetdir', None), attrs.get('tempdir', None)) pass def end_path(self): pass def getProduct(self, prod): for product in self.products: if product.name == prod: return product return None #------------------------------------------------------------------# # # # SERVICE FUNCTIONS # # # #------------------------------------------------------------------# #============================================================== # message: prints diagnostic information #============================================================== def message(msg): """ Prints diagnostic information. """ if msg.strip(): print ">>>", msg pass #============================================================== # warning: prints warning #============================================================== def warning(msg): """ Prints warning. """ if msg.strip(): print "" print msg print "" pass #============================================================== # error_exit : prints (optionally) error string, then prints # help information and quits #============================================================== def error_exit(msg = "", print_help = True): """ Prints (optionally) error string, then prints help information and quits. """ # print error message if len(msg.strip()): print "" print msg print "" # print help information if print_help: global opt_parser if opt_parser: opt_parser.print_help() print "" # cleaning clean_all() # quit sys.exit(1); pass #============================================================== # boolean : Converts string to boolean value. #============================================================== def boolean(val): """ Converts string to boolean value if possible. Raises exception if wrong string is used. """ if isinstance(val, types.StringType): if val.strip().lower() in ["true", "yes", "ok"] : return True elif val.strip().lower() in ["false", "no", "cancel"] : return False else: raise TypeError("invalid boolean value") return bool(val) #================================================================= # check_bool : checks boolean value: yes/no, true/false, 1/0 #================================================================= def check_bool(val): """ Checks boolean value. """ try: return boolean(val) except: pass return False #============================================================== # clean_all : performs system cleaning before exiting #============================================================== def clean_all(): """ Performs system cleaning before exiting. """ global root_path remove_dir(root_path) pass #============================================================== # parse_parameters : parses command line arguments #============================================================== def parse_parameters(): """ Parses command line arguments. """ global opt_parser opt_parser = ArgParser() help_str = "Runs the Installation Wizard in the GUI mode [default].\n" opt_parser.add_option("-g", "--gui", action="store_true", dest="gui", default=True, help=help_str) help_str = "Runs the Installation Wizard in the TUI mode." opt_parser.add_option("-b", "--batch", action="store_false", dest="gui", help=help_str) help_str = "The configuration xml file.\n" help_str += "If this parameter is missing, then the program tries to define the " help_str += "Linux platform and use the corresponding xml file. For example, " help_str += "for Red Hat 8.0 config_RedHat_8.0.xml file is used in this case. " help_str += "If program fails to define target Linux platform or the corresponding " help_str += "xml file is not provided with the Installation Wizard, then default " help_str += "config.xml file is used." opt_parser.add_option("-f", "--file", action="store", dest="xmlfile", metavar="FILE", help=help_str) help_str = "The target directory the products to be installed to.\n" help_str += "When used this parameter overrides the default target directory " help_str += "defined in the configuration xml file." opt_parser.add_option("-d", "--target", action="store", dest="target_dir", metavar="DIR", help=help_str) help_str = "The directory to be used for temporary files.\n" help_str += "When used this parameter overrides the default temporary directory " help_str += "defined in the configuration xml file." opt_parser.add_option("-t", "--tmp", action="store", dest="tmp_dir", metavar="DIR", help=help_str) help_str = "Prints version information and quits." opt_parser.add_option("-v", "--version", action="store_true", help=help_str) help_str = "Prints this help and quits." opt_parser.add_option("-h", "--help", action="store_true", help=help_str) (options, args) = opt_parser.parse_args() if options.help: # print help info and quit print "\nSALOME Installation Wizard\n" opt_parser.print_help() print "" sys.exit(0) if options.version: # print version info and quit print "" cmd = "./bin/SALOME_InstallWizard --version" os.system(cmd) print "" sys.exit(0) return [options.xmlfile, options.target_dir, options.tmp_dir, options.gui] #================================================================= # strip : removes spaces at the beginning and at the end of the # if it is of string type #================================================================= def strip(param): """ Removes spaces at the beginning and at the end of the given parameter. """ if type(param) == types.StringType: return param.strip() return param #================================================================= # get_dependencies : extract products dependencies #================================================================= def get_dependencies(prods): """ Gets full list of pre-requisite products. """ list = [] for product in prods: deps = product.dependencies.split(",") for dep in deps: if dep and not dep in list: list.append( dep ) if product and not product in list: list.append( product.name ) return " ".join( list ) #============================================================== # create_dir : creates a directory with (optional) permissions, # returns the part of path that existed before # directory creation; exits with error if access # is denied #============================================================== def create_dir(directory, access = 0777): """ Creates a directory with (optional) permissions, returns the part of path that existed before directory creation; exits with error if access is denied. """ dirs = string.split(directory, "/") existing = ""; dir = "" root = "" for subdir in dirs: if len(subdir) == 0: continue dir = "%s/%s"%(dir, subdir) if os.path.exists(dir): existing = dir else: try: os.mkdir(dir, access) except: error_exit("Can't create directory: %s.\nAccess is denied."%directory) if dir == "%s/%s"%(existing, subdir): root = dir return root #============================================================== # substituteVars : performes environment variables substistution # the given string; if varibale is not defined # it is substituted by the empty string #============================================================== def substituteVars(str): """ Performes environment variables substistution. """ str = os.path.expanduser(str) str = os.path.expandvars(str) return str #================================================================ # get_program_path : gets program's directory path # (and performs 'cd' command there) #================================================================ def get_program_path(): """ Returns the program directory path (and make this directory current). """ path = os.path.dirname(sys.argv[0]) if path: os.chdir(path) return os.getcwd() #================================================================ # check_dir : checks directory existence #================================================================ def check_dir(dir): """ Checks directory existence. """ if (os.path.islink(dir)): realpath = os.path.realpath(dir) if not os.path.exists(realpath): msg = "Invalid link %s.\nThe directory %s a link points to does not exist. Stopped..."%(dir,realpath) error_exit(msg, False) else: if not os.path.exists(dir): msg = "Directory %s does not exist. Stopped..."%dir error_exit(msg, False) pass #=============================================================== # check_disk_space : checks the disk space; # quits if there is no enough disk space #=============================================================== def check_disk_space(products, scripts_dir, target_dir, tmp_dir): """ Checks if there is enough disk space to install products. Quits with error if there is no enough disk space. """ install_space = 0 temporary_space = 0 for product in products: if product.install in [__TAG__NATIVE__, __TAG__PREINSTALL__]: continue spaces = string.split(product.installdiskspace, ',') prod_space = spaces[0] if (len(spaces) > 1 ) and (product.install == __TAG__SOURCES__): prod_space = spaces[1] install_space = install_space + string.atoi(prod_space) if product.install == __TAG__SOURCES__: temporary_space = max(temporary_space, string.atoi(product.temporarydiskspace)) res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", target_dir, install_space)) if res: msg = "There is no enough space to install the products. Stopped..." error_exit(msg, False) res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", tmp_dir, temporary_space)) if res: msg = "There is no enough space for temporary directory. Stopped..." error_exit(msg, False) pass #=============================================================== # remove_dir : removes temporary directory #=============================================================== def remove_dir(path): """ Removes temporary directory. """ if path and os.path.exists(path): os.system("rm -rf " + path) pass #============================================================== # has_binaries : returns True if some product is installed from # binaries #=============================================================== def has_binaries(products): """ Returns True if some product is installed in 'binaries' mode. """ for product in products: if product.install == __TAG__BINARIES__: return True return False #============================================================== # has_sources : returns True if some product is installed from # sources #=============================================================== def has_sources(products): """ Returns True if some product is installed in 'sources' mode. """ for product in products: if product.install == __TAG__SOURCES__: return True return False #============================================================== # get_tmp_dir : gets temporary directory name #=============================================================== def get_tmp_dir(dir): """ Gets temporary directory path. """ max_attempts = 100 dir_prefix="INSTALLWORK" range_bottom = 0; range_top = 999999 for i in xrange(max_attempts): tmp_dir = "%s/%s%d"%(dir, dir_prefix, random.randint(range_bottom,range_top)) if not os.path.exists( tmp_dir ): return tmp_dir return "%s/%s%d"%(dir, dir_prefix, random.randint(range_bottom,range_top)) #------------------------------------------------------------------# # # # EXECUTION STARTS HERE # # # #------------------------------------------------------------------# if __name__ == "__main__": # get program dir cur_dir = get_program_path() # parse command line [xml_file, target_dir, tmp_dir, is_gui] = parse_parameters() # define xml file to be used if (xml_file is None): plt_name = "" plt_ver = "" plt_bit = "" xml_file_name = "config.xml" if os.path.exists("/etc/redhat-release"): # - Red Hat Linux 8.0 # - Red Hat Linux 9 # - Mandrake Linux 10.1 # - Scientific Linux 3.0.5 # - Mandriva 2006.0 32bit/64bit data = open("/etc/redhat-release").readline() res = re.search(r'(.*)[L|l]inux.*release\s+([\d.]*)', data) if res: plt_name = "".join(res.group(1).split()) plt_ver = res.group(2) if re.search(r'x86_64', data): plt_bit = "_64" elif os.path.exists("/etc/debian_version"): # - Debian 3.1 plt_name = "Debian" plt_ver = open("/etc/debian_version").readline().strip() elif os.path.exists("/etc/mandriva-release"): # - Mandriva 2006 (an additional check if above check fails) data = open("/etc/mandriva-release").readline() res = re.search(r'(.*)[L|l]inux.*release\s+([\d.]*)', data) if res: plt_name = "".join(res.group(1).split()) plt_ver = res.group(2) if re.search(r'x86_64', data): plt_bit = "_64" pass _xml_file_name = "config_%s_%s%s.xml"%(plt_name, plt_ver, plt_bit) if plt_name and plt_ver and os.path.exists("%s/%s"%(cur_dir, _xml_file_name)): xml_file_name = _xml_file_name else: msg = "Not supported Linux platform!\n" msg += "Trying to use default configuration file!" warning(msg) xml_file = "%s/%s"%(cur_dir, xml_file_name) if not xml_file or not os.path.exists(xml_file): msg = "Configuration file %s is not found!"%xml_file error_exit(msg) if not os.access(xml_file, os.R_OK): msg = "There is no read access for %s file!"%xml_file error_exit(msg) #---- GUI ---------------- if is_gui : env = os.environ if not env.has_key("PATH") : env["PATH"] = "" if not env.has_key("LD_LIBRARY_PATH") : env["LD_LIBRARY_PATH"] = "" env["LD_LIBRARY_PATH"] = ".:" + env["LD_LIBRARY_PATH"] env["PATH"] = ".:" + env["PATH"] cmd = "./bin/SALOME_InstallWizard --file %s"%xml_file if target_dir is not None: cmd += " --target %s"%target_dir if tmp_dir is not None: cmd += " --tmp %s"%tmp_dir cmd += "&" sys.exit(os.system(cmd)) #----- TUI --------------------- # parse XML file ----------- message("Parsing XML configuration file: %s"%xml_file) filehandle = open(xml_file) data = filehandle.read() filehandle.close() parser = ConfigParser() parser.feed(data) parser.close() # actions map what_to_do = { __TAG__SOURCES__ : "install_source", __TAG__BINARIES__ : "install_binary", __TAG__NATIVE__ : "try_native", __TAG__PREINSTALL__ : "try_preinstalled"} # source directory map bin_dir = "" if parser.config.os: bin_dir += "/%s"%parser.config.os subdir = { __TAG__SOURCES__ : "SOURCES", __TAG__BINARIES__ : "BINARIES" + bin_dir, __TAG__NATIVE__ : "", __TAG__PREINSTALL__ : ""} # check scripts directory ----------- scripts_dir = "%s/%s"%(cur_dir, "config_files") check_dir(scripts_dir) # check products archives directories ----------- has_bin = has_binaries(parser.products) has_src = has_sources(parser.products) source_dir = "%s/%s"%(cur_dir, "Products") if has_src or has_bin: check_dir(source_dir) if has_src: check_dir("%s/%s"%(source_dir,subdir[__TAG__SOURCES__])) if has_bin: check_dir("%s/%s"%(source_dir,subdir[__TAG__BINARIES__])) # check/create target dir ----------- if target_dir is None: target_dir = parser.path.targetdir target_dir = substituteVars(target_dir) message("Creating target directory: " + target_dir) create_dir(target_dir, 0755) if not os.path.exists(target_dir): error_exit("Invalid target directory: " + target_dir) if not os.access(target_dir, os.W_OK) : error_exit("There is no write permissions for the directory: " + target_dir) # check/create temporary dir ----------- if tmp_dir is None: tmp_dir = parser.path.tmpdir if not tmp_dir: tmp_dir = "/tmp" tmp_dir = substituteVars(tmp_dir) tmp_dir = get_tmp_dir(tmp_dir) message("Creating temporary directory: " + tmp_dir) root_path = create_dir(tmp_dir, 0755) if not os.path.exists(tmp_dir): error_exit("Invalid temporary directory: " + tmp_dir) if not os.access(tmp_dir, os.W_OK) : error_exit("There is no write permissions for the directory: " + tmp_dir) # check available disk space ----------- message("Checking available disk space") check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir) # change current directory ----------- os.chdir(scripts_dir) # get dependencies list ----------- list_of_dep = get_dependencies(parser.products) # starting ----------- message("Starting ...") # install products ----------- for product in parser.products: message("... processing %s ..."%product.name) cmd = '%s/%s %s %s %s/%s %s "%s" %s'%(scripts_dir, product.script, what_to_do[product.install], tmp_dir, source_dir, subdir[product.install], target_dir, list_of_dep, product.name) res = os.system(cmd) # pickup environment ----------- message("Creating environment files") for product in parser.products : if check_bool(product.pickupEnv): cmd = '%s/%s pickup_env %s %s/%s %s "%s" %s'%(scripts_dir, product.script, tmp_dir, source_dir, subdir[product.install], target_dir, list_of_dep, product.name) res = os.system(cmd) # clean temporary directory ----------- message("Cleaning temporary directory") clean_all() # finishing ----------- message("Finished!") pass