Salome HOME
To introduce a new possibility - installation of binaries of the prerequisites into...
[tools/install.git] / runInstall
index f5cf6d6032b76982715330b8977bd8add87b727d..1a0df58c0be116cc636e30b299968c7dce6ced5d 100755 (executable)
@@ -6,7 +6,7 @@ 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
+Copyright : 2002-2007 CEA
 
 """
 
@@ -18,7 +18,7 @@ warnings.filterwarnings("ignore", "", DeprecationWarning)
 
 # --- imports --- #
 import xmllib
-import sys, os, string, re
+import sys, os, re
 import types
 import random
 
@@ -31,6 +31,12 @@ __TAG__SOURCES__    = "install sources"
 __TAG__BINARIES__   = "install binaries"
 __TAG__NATIVE__     = "use native"
 __TAG__PREINSTALL__ = "not install"
+__TAG__BUILDSRC__   = "build sources"
+
+# --- product context definition --- #
+__CTX__SALOME__SRC__  = "salome sources"
+__CTX__SALOME__BIN__  = "salome binaries"
+__CTX__PREREQUISITE__ = "prerequisite"
 
 #------------------------------------------------------------------#
 #                                                                  #
@@ -355,42 +361,47 @@ class ArgParser:
 #------------------------------------------------------------------#
 
 #===================================================================
-# class Config : general configuration options : version, OS, etc...
+# class Config : general configuration options : version, target and
+#                temporary directories, etc...
 #===================================================================
 class Config :
     """
     General configuration file options:
     - Install Wizard window caption
     - SALOME platform version
-    - Copyright and libcense info
-    - Target Linux OS version
+    - Copyright and license info
+    - Default target and temporary directories
     """
     def __init__(self,
                  theVersion   = None,
                  theCaption   = None,
                  theCopyright = None,
                  theLicense   = None,
-                 theOS        = None):
+                 thePlatforms = None,
+                 theTargetdir = None,
+                 theTmpdir    = 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.platforms = strip(thePlatforms)
         self.targetdir = strip(theTargetdir)
         self.tmpdir    = strip(theTmpdir)
+
+## #===================================================================
+## # 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
@@ -399,6 +410,7 @@ class Product :
     """
     Product options:
     - name, version
+    - target Linux OS version
     - supported installation modes and the default one
     - dependencies
     - required disk space
@@ -407,6 +419,8 @@ class Product :
     """
     def __init__(self,
                  theName,
+                 theType               = None,
+                 theOS                 = None,
                  theVersion            = None,
                  theInstall            = None,
                  theSupportred         = None,
@@ -416,6 +430,8 @@ class Product :
                  theScript             = None,
                  thePickUpEnvironment  = None):
         self.name               = strip(theName)
+        self.type               = strip(theType)
+        self.os                 = strip(theOS)
         self.version            = strip(theVersion)
         self.install            = strip(theInstall)
         self.supported          = strip(theSupportred)
@@ -424,7 +440,35 @@ class Product :
         self.temporarydiskspace = strip(theTemporarydiskspace)
         self.script             = strip(theScript)
         self.pickupEnv          = strip(thePickUpEnvironment)
+        self.whattodo           = self.install
+        
+    def hasContext(self, ctx):
+        try:
+            return ctx in [ strip(s) for s in self.context.split(",") ]
+        except:
+            pass
+        return False
 
+    def setMode(self, mode):
+        if mode not in [__TAG__SOURCES__, __TAG__BINARIES__, __TAG__NATIVE__, __TAG__PREINSTALL__]:
+            return
+        try:
+            supported = [ strip(s) for s in self.supported.split(",") ]
+            if mode in supported or mode == __TAG__PREINSTALL__:
+                self.install = mode
+                self.whattodo = self.install
+            salbin = self.hasContext(__CTX__SALOME__BIN__)
+            salsrc = self.hasContext(__CTX__SALOME__SRC__)
+            if mode == __TAG__SOURCES__:
+                if salbin and not salsrc:
+                    self.install = __TAG__PREINSTALL__
+                    self.whattodo = self.install
+                elif salsrc:
+                    self.whattodo = __TAG__BUILDSRC__
+        except:
+            pass
+        return
+        
 #===================================================================
 # class ConfigParser : XML files parser implementation
 #===================================================================
@@ -432,20 +476,35 @@ class ConfigParser(xmllib.XMLParser):
     """
     XML configuration files parser
     """
-    def __init__(self):
+    def __init__(self, is_force_src=False):
         xmllib.XMLParser.__init__(self)
         self.products = []
         self.currentdata = []
-        self.path = None
+##         self.path = None
         self.config = None
+        self.is_force_src = is_force_src
         
     def handle_data(self, data):
         self.currentdata.append(data)
         
+    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('platforms', None),
+                             attrs.get('targetdir', None),
+                             attrs.get('tempdir',   None))
+        pass
+    
+    def end_config(self):
+        pass
+
     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('type',               None),
                            attrs.get('version',            None),
                            attrs.get('install',            None),
                            attrs.get('supported',          None),
@@ -454,30 +513,37 @@ class ConfigParser(xmllib.XMLParser):
                            attrs.get('temporarydiskspace', None),
                            attrs.get('script',             None),
                            attrs.get('pickupenv',          None))
+        if self.is_force_src:
+            aProduct.setMode(__TAG__SOURCES__)
         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))
+    def start_installation(self, attrs):
+##         anInstallation = Installation(attrs.get('os',                 None),
+##                                       attrs.get('type',               None),
+##                                       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))
         pass
     
-    def end_config(self):
+    def end_installation(self):
         pass
 
-    def start_path (self, attrs):
-        self.path = Path(attrs.get('targetdir', None),
-                         attrs.get('tempdir',   None))
-        pass
+##     def start_path (self, attrs):
+##         self.path = Path(attrs.get('targetdir', None),
+##                          attrs.get('tempdir',   None))
+##         pass
         
-    def end_path(self):
-        pass
+##     def end_path(self):
+##         pass
 
     def getProduct(self, prod):
         for product in self.products:
@@ -485,6 +551,12 @@ class ConfigParser(xmllib.XMLParser):
                 return product
         return None
 
+    def getInstallation(self, os):
+        for product in self.products:
+            if product.name == prod:
+                return product
+        return None
+
 #------------------------------------------------------------------#
 #                                                                  #
 #                         SERVICE FUNCTIONS                        #
@@ -596,7 +668,7 @@ def parse_parameters():
                           dest="gui",
                           default=True,
                           help=help_str)
-    help_str  = "Runs the Installation Wizard in the TUI mode."
+    help_str  = "Runs the Installation Wizard in the TUI mode (UNAVAILABLE NOW)."
     opt_parser.add_option("-b",
                           "--batch",
                           action="store_false",
@@ -606,9 +678,6 @@ def parse_parameters():
     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",
@@ -704,7 +773,7 @@ def create_dir(directory, access = 0777):
     directory creation; exits with error if access
     is denied.
     """
-    dirs = string.split(directory, "/")
+    dirs = directory.split("/")
     existing = "";
     dir = ""
     root = ""
@@ -771,7 +840,7 @@ def check_dir(dir):
 # 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):
+def check_disk_space(products, scripts_dir, target_dir, tmp_dir, is_force_src=False):
     """
     Checks if there is enough disk space to install products.
     Quits with error if there is no enough disk space.
@@ -781,13 +850,23 @@ def check_disk_space(products, scripts_dir, target_dir, tmp_dir):
     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)
+        prod_space = 0
+        try:
+            spaces = product.installdiskspace.split(',')
+            prod_space = int( spaces[0] )
+            if len( spaces ) > 1 and product.install == __TAG__SOURCES__ and not is_force_src:
+                prod_space = int( spaces[1] )
+        except:
+            pass
+        install_space = install_space + prod_space
         if product.install == __TAG__SOURCES__:
-            temporary_space = max(temporary_space, string.atoi(product.temporarydiskspace))
+            tmp_space = 0
+            try:
+                tmp_space = int( product.temporarydiskspace )
+            except:
+                pass
+            temporary_space = max( temporary_space, tmp_space )
+        pass
 
     res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", target_dir, install_space))
     if res:
@@ -852,69 +931,97 @@ def get_tmp_dir(dir):
         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"
+#==============================================================
+# get_current_platform : gets name, version and bit of 
+#                        the current user's Linux platform
+#===============================================================
+def get_current_platform():
+    """
+    Gets name, version and bit of
+    the current user's Linux platform.
+    """
+    plt_name = ""; plt_ver  = ""; plt_bit  = ""
+    if os.path.exists("/etc/issue"):
+        data = open("/etc/issue").readline()
+        res = re.search(r'(.*)[L|l]inux.*release\s+([\d.]*)', data)
+        if not res:
+            # Debian identification
+            res = re.search(r'(.*)GNU/Linux\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)
+            pass
+        pass
 
-        xml_file = "%s/%s"%(cur_dir, xml_file_name)
+    return plt_name, plt_ver, plt_bit
 
-    if not xml_file or not os.path.exists(xml_file):
+#==============================================================
+# check_xml_file : checks XML file existence and readability
+#===============================================================
+def check_xml_file(xml_file):
+    """
+    Checks XML file existence and readability.
+    """
+    if not os.path.isfile(xml_file):
         msg = "Configuration file %s is not found!"%xml_file
-        error_exit(msg)
+        error_exit(msg, False)
 
     if not os.access(xml_file, os.R_OK):
         msg = "There is no read access for %s file!"%xml_file
-        error_exit(msg)
+        error_exit(msg, False)
+    pass
+
+#==============================================================
+# get_supported_plts : gets map of supported Linux platforms and
+#                      corresponding configuration files
+#===============================================================
+def get_supported_platforms(xml_file=None):
+    """
+    Gets map of supported Linux platforms and
+    corresponding configuration files.
+    """
+    platforms_map = {}
+    xml_file_list = list()
+    if xml_file:
+        xml_file_list = [ xml_file ]
+    else:
+        entry_list = os.listdir(get_program_path())
+        for entry in entry_list:
+            if re.search(r'(.*).xml', entry):
+                xml_file_list.append(os.path.abspath(entry))
+    for an_xml_file in xml_file_list: # XML files parsing
+        check_xml_file(an_xml_file)
+        filehandle = open(an_xml_file)
+        data = filehandle.read()
+        filehandle.close()
+        parser = ConfigParser()
+        parser.feed(data)
+        parser.close()
+        if parser.config.platforms is not None:
+            for plt in parser.config.platforms.split(","):
+                if not plt or plt in platforms_map.keys(): continue
+##                 print "plt = %s, xml = %s"%(strip(plt), an_xml_file)
+                platforms_map[strip(plt)] = an_xml_file
+    return platforms_map
+
+#------------------------------------------------------------------#
+#                                                                  #
+#                    EXECUTION STARTS HERE                         #
+#                                                                  #
+#------------------------------------------------------------------#
+
+if __name__ == "__main__":
+    # parse command line
+    [xml_file, target_dir, tmp_dir, is_gui] = parse_parameters()
+    if xml_file:   xml_file   = os.path.abspath(xml_file)
+    if target_dir: target_dir = os.path.abspath(target_dir)
+    if tmp_dir:    tmp_dir    = os.path.abspath(tmp_dir)
+    # get program dir
+    cur_dir = get_program_path()
 
     #---- GUI ----------------
 
@@ -925,10 +1032,12 @@ if __name__ == "__main__":
         if not env.has_key("LD_LIBRARY_PATH") :
             env["LD_LIBRARY_PATH"] = ""
 
-        env["LD_LIBRARY_PATH"] =  ".:" + env["LD_LIBRARY_PATH"]
+        env["LD_LIBRARY_PATH"] =  "./bin/lib:" + ".:" + env["LD_LIBRARY_PATH"]
         env["PATH"] = ".:" + env["PATH"]
 
-        cmd = "./bin/SALOME_InstallWizard --file %s"%xml_file
+        cmd = "./bin/SALOME_InstallWizard"
+        if xml_file is not None:
+            cmd += " --file %s"%xml_file
         if target_dir is not None:
             cmd += " --target %s"%target_dir
         if tmp_dir is not None:
@@ -938,12 +1047,37 @@ if __name__ == "__main__":
 
     #-----  TUI ---------------------
 
+    msg = "Sorry, batch mode is unavailable in current version of SALOME Install Wizard!\n"
+    msg += "Use GUI mode to install SALOME, please."
+    error_exit(msg)
+    
+    # get program dir
+    cur_dir = get_program_path()
+
+    # get current Linux platform
+    plt_name = ""; plt_ver  = ""; plt_bit  = ""
+    plt_name, plt_ver, plt_bit = get_current_platform()
+    full_plt_name = plt_name + plt_ver + plt_bit
+    print "full_plt_name = %s" % full_plt_name
+    
+    # get supported Linux platforms
+    supported_plts_map = get_supported_platforms(xml_file)
+    # check: whether the current platform is supported
+    if supported_plts_map.has_key(full_plt_name):
+        # define xml file to be used
+        xml_file = supported_plts_map.get(full_plt_name, "")
+        print "set xml_file = %s" % os.path.basename(xml_file)
+        pass
+    else:
+        msg  = "Not supported Linux platform!\n"
+        warning(msg)
+
     # parse XML file -----------
     message("Parsing XML configuration file: %s"%xml_file)
     filehandle = open(xml_file)
     data = filehandle.read()
     filehandle.close()
-    parser = ConfigParser()
+    parser = ConfigParser(is_force_src)
     parser.feed(data)
     parser.close()
 
@@ -951,7 +1085,8 @@ if __name__ == "__main__":
     what_to_do = { __TAG__SOURCES__    : "install_source",
                    __TAG__BINARIES__   : "install_binary",
                    __TAG__NATIVE__     : "try_native",
-                   __TAG__PREINSTALL__ : "try_preinstalled"}
+                   __TAG__PREINSTALL__ : "try_preinstalled",
+                   __TAG__BUILDSRC__   : "install_source_and_build"}
     # source directory map
     bin_dir = ""
     if parser.config.os:
@@ -1012,7 +1147,7 @@ if __name__ == "__main__":
         
     # check available disk space -----------
     message("Checking available disk space")
-    check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir)
+    check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir, is_force_src)
 
     # change current directory -----------
     os.chdir(scripts_dir)
@@ -1028,7 +1163,7 @@ if __name__ == "__main__":
         message("... processing %s ..."%product.name)
         cmd = '%s/%s %s %s %s/%s %s "%s" %s'%(scripts_dir,
                                               product.script,
-                                              what_to_do[product.install],
+                                              what_to_do[product.whattodo],
                                               tmp_dir,
                                               source_dir,
                                               subdir[product.install],