--- /dev/null
+#!/usr/bin/env python
+
+import xmllib
+import sys, os, string, re
+
+#==============================================================
+# get_help_info
+#==============================================================
+def get_help_info() :
+ str = "\nSALOME Professional Installation Wizard\n\n"
+ str = str + "\tUsage : \n\tInstall [-g|b] [-f <xml-file>] [-t <target-dir>] [-tmp <tmp-dir>]\n"
+ str = str + "\n"
+ str = str + " -g Runs the Installation Wizard in the GUI mode.\n"
+ str = str + " In this case only <xmlfile> is taken into account \n"
+ str = str + " from the parameters list. This key is default.\n"
+ str = str + "\n"
+ str = str + " -b Runs the Installation Wizard in the batch mode.\n"
+ str = str + " All the found parameters are taken in to account.\n"
+ str = str + "\n"
+ str = str + " -f <xml-file> The configuration file to be parsed by the Installation Wizard.\n"
+ str = str + " If this parameter is missed then the script tries to define\n"
+ str = str + " the Red Hat version and use the corresponding xml. For example,\n"
+ str = str + " for Red Hat 8.0 config_RedHat8_0.xml file is supposed to be used\n"
+ str = str + " by default. If the appropriate xml file is not found, the config.xml\n"
+ str = str + " is used by default.\n"
+ str = str + "\n"
+ str = str + " -t <target-dir> The target directory the products to be installed to.\n"
+ str = str + " This parameter overloads the target directory described in the\n"
+ str = str + " configuration file.\n"
+ str = str + "\n"
+ str = str + " -tmp <tmp-dir> The directory which should be used for the temporary files.\n"
+ str = str + " This parameter overloads the temporary directory described in the\n"
+ str = str + " configuration file.\n"
+ str = str + "\n"
+ str = str + " -h Prints help information.\n"
+ return str
+
+#==============================================================
+# error_exit
+#==============================================================
+def error_exit (str = ""):
+ import sys
+ if len(str): res = "\n" + str + "\n"
+ else : res = ""
+ print res + \
+ get_help_info()
+ sys.exit(1);
+
+
+#==============================================================
+# Cheks whether the passed parameter is a key.
+#==============================================================
+def is_key ( val ):
+ import re
+ if val is not None :
+ return re.match(r'^-[a-zA-Z]', val)
+ return 0
+
+#==============================================================
+# From the list of parameters extracts value following 'key'
+#==============================================================
+def extract_parameter ( key, args ) :
+ import sys
+ length = len(args);
+ if ( length == 0 ) : return None
+
+ found = 0;
+
+ for i in range(0, length-1):
+ if args[i] == key :
+ if ( is_key ( args[i+1]) ) :
+ print " No value after key ", key
+ sys.exit(1);
+
+ value = args[i+1]
+ if ( i < length - 2 and is_key ( args[i+2] ) == 0 ) : #control that only one value follows key
+ #(not a list). In this case params are correct.
+ print "Too much values after key ", key
+ sys.exit(1);
+
+ found = 1; break;
+
+ if (found) :
+ return value
+
+ return None
+
+
+#===============================================================
+# Extracts list of values following specified 'key' from 'args[]'
+#===============================================================
+def extract_list (key, args) :
+
+ lenght = len(args)
+ if ( args is None or lenght == 0 ):
+ error_exit()
+
+ list=[]
+ found = 0
+
+ for i in range(0, length) :
+ if args[i] == key :
+ if (is_key ( args[i+1])) :
+ error_exit();
+
+ for i in range (i+1, lenght):
+ if is_key(args[i]) : break
+ list.append(args[i])
+ found =1; break
+
+ return list; #empty list is returned if no values after key
+
+
+#==============================================================
+# Method find the $key in the list and return 1 if success
+# and 0 otherwise.
+#==============================================================
+def find_key (key, argv) :
+
+ if (not is_key(key)) : return 0
+
+ for simbol in argv :
+ if simbol == key:
+ return 1
+ return 0
+
+#==============================================================
+# Parse the list of parameters
+#==============================================================
+def parse_parameters (args) :
+
+ if find_key('-h', args) :
+ print get_help_info();
+ import sys
+ sys.exit(0)
+
+ xmlfile = extract_parameter("-f", args)
+ target_dir = extract_parameter("-t", args)
+ tmp_dir = extract_parameter("-tmp", args)
+ if find_key('-b', args):
+ is_gui = 0
+ else : is_gui = 1
+ return [xmlfile, target_dir, tmp_dir, is_gui]
+
+
+#=================================================================
+# The first algorithm to create the dependencies list by their level
+#=================================================================
+def get_next_level(list, products):
+
+ import re
+ result = []
+ expr = "(" + list[0].name
+ for i in range(1, len(list)):
+ expr = expr + "|"+ list[i].name
+
+ expr = expr + ")$"
+ #expr=re.compile(expr)
+
+ for product in products:
+ deps = re.sub(r'\s+', "", product.dependencies)
+ if re.search(expr, deps):
+ result.append(product)
+
+ return result
+
+
+def create_levels(prods):
+ import copy
+
+ products = copy.deepcopy(prods)
+
+ result = {}
+ import re
+ #1. find the products with empty lists of dependencies
+ list = []
+ for product in products:
+ if len(re.sub(r'\s', "", product.dependencies)) == 0 :
+ list.append(product)
+
+ if len(list) == 0 :
+ raise RuntimeError, "Products that depend on nothing are not found"
+
+ # remove the first level products from the common list of products
+ for product in list :
+ products.remove(product)
+
+ ind = 0;
+ result[0] = list
+
+ while (len(products)) :
+ res = get_next_level(list, products)
+ if len(res) == 0 :
+ raise RuntimeError, "Empty list of products is found"
+
+ for product in res :
+ products.remove(product)
+
+ ind = ind +1
+ result[ind] = res
+ list = res
+
+ str = ""
+ for i in result.keys():
+ for product in result[i]:
+ str = str + product.name + " "
+
+ return str;
+
+#=================================================================
+# The second algorithm
+#=================================================================
+def get_dependencies_set(prods) :
+ import copy
+ import re
+
+ products = copy.deepcopy(prods)
+ deps = ""
+ list = []
+
+ while (len(products)) :
+
+ tmplist = []
+ #find the products with empty list of dependencies
+ for product in products:
+ product.dependencies = re.sub(r'\s+$', "", product.dependencies)
+ product.dependencies = re.sub(r'^\s+', "", product.dependencies)
+
+ if len(product.dependencies) == 0 :
+ tmplist.append(product);
+ deps = deps + " " + product.name
+
+ list.append(tmplist)
+
+ #remove the products names from other products dependencies
+ for item in tmplist:
+ products.remove(item)
+
+ regexpr1 = "((^|,(\s+)?)"+item.name+"$|^"+item.name+"(\s+)?,(\s+)?)"
+ regexpr2 = ",(\s+)?"+item.name+"(\s+)?,(\s+)?"
+
+ for product in products:
+ product.dependencies = re.sub(r'\s+$', "", product.dependencies)
+ product.dependencies = re.sub(r'^\s+', "", product.dependencies)
+
+ product.dependencies = re.sub(regexpr1, "", product.dependencies)
+ product.dependencies = re.sub(regexpr2, ",", product.dependencies)
+
+ return deps
+
+#==============================================================
+# Creates dir, returns the part of path that existed early.
+# Access may be defined.
+#==============================================================
+def create_dir (directory, access = 0777):
+ import string, os
+ dirs = string.split(directory, "/")
+ existing = ""; dir = ""
+ root = ""
+ for item in dirs:
+ if len(item) == 0: continue
+ dir = dir + "/"+item
+ if os.path.exists(dir):
+ existing = dir
+ else:
+ os.mkdir(dir, access )
+ #root= existing + "/"+item
+ if dir == existing + "/"+item :
+ root = dir
+ #else : root = existing
+
+ return root
+
+#==============================================================
+# class Product
+#==============================================================
+
+class Product :
+ def __init__(self, theName,
+ theVersion = None,
+ theInstall = None,
+ theSupportred = None,
+ theDisable = None,
+ theDependencies = None,
+ theInstalldiskspace = None,
+ theTemporarydiskspace = None,
+ theScript = None):
+
+
+ self.name = theName
+ self.version = theVersion
+ self.install = theInstall
+ self.supported = theSupportred
+ self.disable = theDisable
+ self.dependencies = theDependencies
+ self.installdiskspace = theInstalldiskspace
+ self.temporarydiskspace = theTemporarydiskspace
+ self.script = theScript
+
+#===================================================================
+# class Config
+#===================================================================
+class Config :
+ def __init__(self, theVersion='', theCaption='', theCopyright='', theLicense='', theOS=''):
+ self.version = theVersion
+ self.caption = theCaption
+ self.copyright = theCopyright
+ self.license = theLicense
+ self.os = theOS
+
+
+#===================================================================
+# class Path
+#===================================================================
+class Path :
+ def __init__(self, theTargetdir=".", theTmpdir="."):
+ self.targetdir = theTargetdir
+ self.tmpdir = theTmpdir
+
+
+#===================================================================
+# class ConfigParser
+#===================================================================
+class ConfigParser(xmllib.XMLParser):
+ 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):
+ aProduct = Product(attrs['name'],
+ attrs['version'],
+ attrs['install'],
+ attrs['supported'],
+ attrs['disable'],
+ attrs['dependancies'],
+ attrs['installdiskspace'],
+ attrs['temporarydiskspace'],
+ attrs['script'])
+
+ self.products.append(aProduct)
+
+ def end_product(self):
+ pass
+
+ def start_config(self, attrs):
+ self.config = Config(attrs['version'],
+ attrs['caption'],
+ attrs['copyright'],
+ attrs['license'],
+ attrs['os'])
+ def end_config(self):
+ pass
+
+ def start_path (self, attrs):
+ self.path = Path(attrs['targetdir'],
+ attrs['tempdir'])
+ print self.path.tmpdir
+
+ def end_path(self):
+ pass
+
+#================================================================
+# get the path using file name
+#================================================================
+def get_current_path(file_name):
+ path = "."; where = string.rfind(file_name,'/');
+ if (where != -1):
+ path = (file_name)[: where]
+ os.chdir(path);
+ path = os.getcwd() + "/"
+ return path
+
+#================================================================
+# checks dir existing
+#================================================================
+def check_dir(dir):
+ if (os.path.islink(dir)) :
+ native_dir = os.readlink(dir)
+ if not os.path.exists(native_dir) :
+ print "Bad link " + native_dir + " to directory " + native_dir + ". The last does not exist."
+ return 0 # problem
+ else :
+ if not os.path.exists(dir):
+ print "Directory " + dir + " does not exist"
+ return 0
+ return 1
+
+#===============================================================
+# Checks the disk space. Exit from interpreter if there is no
+# enough disk space.
+#===============================================================
+def check_disk_space(products, script_dir, target_dir, tmp_dir):
+ import re, string, os
+ install_space = 0
+ temporary_space = 0
+ for product in products :
+ product.install = re.sub(r'^\s+', "", product.install)
+ product.install = re.sub(r'\s+$', "", product.install)
+
+ if product.disable == "true" or product.install == "use native":
+ continue
+ spaces = string.split( product.installdiskspace,',')
+ prod_space = spaces[0]
+ if (len(spaces) == 2 ) and (product.install == "install binaries") :
+ prod_space = spaces[1]
+ install_space = install_space + string.atoi(prod_space)
+ temporary_space = temporary_space + string.atoi(product.temporarydiskspace)
+ res = os.system(scripts_dir + "checkSize.sh" + " " + target_dir + " " + str(install_space))
+ if res:
+ print "There is no enough space to install the products."
+ return 0
+
+ res = os.system(scripts_dir + "checkSize.sh" + " " + tmp_dir + " " + str(temporary_space))
+ if res:
+ print "There is no enough space for tmp directory."
+ return 0
+
+ return 1
+
+
+#================================================================
+# main
+#================================================================
+
+if __name__ == "__main__":
+
+ cur_dir = get_current_path(sys.argv[0])
+
+ [xml_file, target_dir, tmp_dir, is_gui] = parse_parameters(sys.argv)
+
+ # define xml file -----------------
+ if (xml_file is None) :
+ xml_file_name = "config.xml"
+ if os.path.exists("/proc/version"):
+ data = open("/proc/version").readline()
+ res = re.search(r'Red\s+Hat\s+\w+(\s+)?(\d[.]\d)', data)
+ if res is not None:
+ num = re.sub("[.]", "_", (res.groups())[1])
+ filename = "config_RedHat" + num+ ".xml"
+ if (os.path.exists(cur_dir + filename)):
+ xml_file_name = filename
+
+ xml_file = cur_dir + xml_file_name
+ if xml_file is None or not os.path.exists(xml_file):
+ error_exit("No xml file is found try to run with options -f <xmlfile>")
+
+ if not os.access(xml_file, os.R_OK):
+ print "There is no acceess to read "+ xml_file
+ sys.exit(1)
+
+ #---- 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"]
+
+ sys.exit(os.system("cd " + cur_dir + "; ./bin/SALOMEPRO_InstallWizard " + xml_file +"&"))
+
+
+
+ #----- TUI ---------------------
+
+ #print xml_file, target_dir, tmp_dir, is_gui
+
+ filehandle = open(xml_file)
+ data = filehandle.read()
+ filehandle.close()
+ parser = ConfigParser()
+ parser.feed(data)
+ parser.close()
+
+ # definitions :
+ # map
+ what_to_do = { "install sources":"install_source",
+ "install binaries":"install_binary",
+ "use native":"try_native"}
+ # define tmp dir -----------
+ if tmp_dir is None:
+ tmp_dir = parser.path.tmpdir
+ root_path = ""
+ if not os.path.exists(tmp_dir):
+ print "Creating " + tmp_dir; root_path = create_dir(tmp_dir) ;
+ import random
+ tmp_dir = tmp_dir + "/INSTALLWORK" + str(random.randint(10000,100000))
+ create_dir(tmp_dir,0755)
+ if not os.path.exists(tmp_dir):
+ error_exit("There is no tmp directory " + tmp_dir + ". Use -tmp key to set directory or correct xml file\n\n")
+
+ if not os.access(tmp_dir, os.W_OK) :
+ str = "We have no write permissions for directory " + tmp_dir + ". Use -tmp key to set directory or correct xml file"
+ error_exit(str)
+
+ # define target dir --------
+ if target_dir is None:
+ target_dir = parser.path.targetdir
+
+ if not os.path.exists(target_dir):
+ print "Creating " + target_dir; create_dir(target_dir, 0755)
+ if not os.path.exists(target_dir):
+ error_exit("There is no target directory " + target_dir + ". Use -t key to set directory or correct xml file\n\n")
+
+ if not os.access(target_dir, os.W_OK) :
+ str = "We have no write permissions for directory " + target_dir + ". Use -t key to set directory or correct xml file"
+ error_exit(str)
+
+
+ # define products dir ------------
+ source_dir = cur_dir + "Products" ;
+ if not check_dir(source_dir):
+ if len(root_path) and os.path.exists(root_path):
+ os.system("rm -r -f "+ root_path)
+ sys.exit(1)
+
+ subdir = {"install sources" : "SOURCES",
+ "install binaries" : "BINARIES/"+parser.config.os,
+ "use native": ""}
+
+
+ # define scripts dir ------------
+ scripts_dir = cur_dir + "config_files/"
+ if not check_dir(scripts_dir):
+ if len(root_path) and os.path.exists(root_path):
+ os.system("rm -r -f "+ root_path)
+ sys.exit(1)
+ os.chdir(scripts_dir)
+
+ list_of_dep = create_levels(parser.products)
+ #list_of_dep = get_dependencies_set(parser.products)
+
+ if check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir) :
+
+ for product in parser.products :
+
+ if product.disable == "true": continue
+
+ cmd = 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)
+ if res : break;
+
+ if len(root_path) and os.path.exists(root_path):
+ os.system("rm -r -f "+ root_path)