Salome HOME
Initial version
authoradmin <salome-admin@opencascade.com>
Wed, 10 Mar 2004 13:20:02 +0000 (13:20 +0000)
committeradmin <salome-admin@opencascade.com>
Wed, 10 Mar 2004 13:20:02 +0000 (13:20 +0000)
runInstall [new file with mode: 0755]

diff --git a/runInstall b/runInstall
new file mode 100755 (executable)
index 0000000..c854b82
--- /dev/null
@@ -0,0 +1,559 @@
+#!/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)