#!/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);
+"""
+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-2008 CEA
+
+"""
+
+__version__ = "1.1.5"
+
+# --- imports --- #
+import sys
+try:
+ import xml.sax, xml.dom.minidom
+ import os, re
+ import types
+ import random
+ import warnings
+except Exception, an_exc:
+ sys.exit("Error: %s! Please check the installed Python package." % str(an_exc))
+ pass
+
+# --- avoid "deprecation" warnings --- #
+warnings.filterwarnings("ignore", "", DeprecationWarning)
+
+# --- global variables --- #
+opt_parser = None
+root_path = None
+
+# --- actions definition --- #
+__BINARIES__ = "install_binary"
+__BUILDSRC__ = "install_source_and_build"
+__PREINSTALL__ = "try_preinstalled"
+
+# --- product type definition --- #
+__CTX__COMPONENT__ = "component"
+__CTX__PREREQUISITE__ = "prerequisite"
+
+#------------------------------------------------------------------#
+# #
+# 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
-#==============================================================
-# 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
+#===================================================================
+# 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 = "<unknown>"
+ 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
-#==============================================================
-# 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
+#===================================================================
+# 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
-#===============================================================
-# Extracts list of values following specified 'key' from 'args[]'
-#===============================================================
-def extract_list (key, args) :
+#===================================================================
+# 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 is not None:
+ 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
- lenght = len(args)
- if ( args is None or lenght == 0 ):
- error_exit()
+ 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
- list=[]
- found = 0
+ def add_option(self, *args, **kwargs):
+ """Register an option"""
+ o = ArgOption(*args, **kwargs)
+ self._check_option(o)
+ self.options.append(o)
+ pass
- 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
+ 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 is not None:
+ 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
-#==============================================================
-# Method find the $key in the list and return 1 if success
-# and 0 otherwise.
-#==============================================================
-def find_key (key, argv) :
+ 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
- if (not is_key(key)) : return 0
+ 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 #
+# #
+#------------------------------------------------------------------#
- for simbol in argv :
- if simbol == key:
- return 1
- return 0
+#===================================================================
+# 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 license info
+ - Default target and temporary directories
+ - List of optional libraries for Salome
+ """
+ def __init__(self,
+ theVersion = None,
+ theCaption = None,
+ theCopyright = None,
+ theLicense = None,
+ thePlatforms = None,
+ theTargetdir = None,
+ theTmpdir = None,
+ theOptLibs = None):
+ self.version = strip(theVersion)
+ self.caption = strip(theCaption)
+ self.copyright = strip(theCopyright)
+ self.license = strip(theLicense)
+ self.platforms = strip(thePlatforms)
+ self.targetdir = strip(theTargetdir)
+ self.tmpdir = strip(theTmpdir)
+ self.optlibs = strip(theOptLibs)
#==============================================================
-# Parse the list of parameters
+# class Product : pre-requisite product options
#==============================================================
-def parse_parameters (args) :
-
- if find_key('-h', args) :
- print get_help_info();
- import sys
- sys.exit(0)
+class Product :
+ """
+ Product options:
+ - name, version
+ - target Linux OS version
+ - dependencies
+ - required disk space
+ - installation script
+ - etc...
+ """
+ def __init__(self,
+ theName,
+ theType = None,
+ theOS = None,
+ theVersion = None,
+ theDependencies = None,
+ theWoGuiInstallation = None,
+ theInstalldiskspace = None,
+ theScript = None,
+ thePickUpEnvironment = None):
+ self.name = strip(theName)
+ self.type = strip(theType)
+ self.os = strip(theOS)
+ self.version = strip(theVersion)
+ self.dependencies = strip(theDependencies)
+ self.woguiinst = strip(theWoGuiInstallation)
+ self.installdiskspace = strip(theInstalldiskspace)
+ self.script = strip(theScript)
+ self.pickupEnv = strip(thePickUpEnvironment)
+ self.whattodo = __BINARIES__
- 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):
+ def setMode(self, mode):
+ if mode not in [__BINARIES__, __BUILDSRC__, __PREINSTALL__]:
+ return
+ self.whattodo = mode
+ return
+
+#===================================================================
+# class ConfigParser : XML files parser implementation
+#===================================================================
+class ConfigParser:
+ """
+ XML configuration files parser
+ """
+ def __init__(self, is_force_src=False, pltname=None):
+ self.docElem = None
+ self.products = []
+ self.full_prods_list = []
+ self.config = None
+ self.is_force_src = is_force_src
+ self.pltname = pltname
+ pass
+
+ def parse_config(self):
+ # Parse 'config' part of the XML file
+ configElem = self.docElem.getElementsByTagName('config')[0]
+
+ self.config = Config(configElem.getAttribute('version').strip(),
+ configElem.getAttribute('caption').strip(),
+ configElem.getAttribute('copyright').strip(),
+ configElem.getAttribute('license').strip(),
+ configElem.getAttribute('platforms').strip(),
+ configElem.getAttribute('targetdir').strip(),
+ configElem.getAttribute('tempdir').strip(),
+ configElem.getAttribute('optionallibs').strip())
+ if not self.pltname and self.config.platforms:
+ self.pltname = self.config.platforms.split(",")[0].strip()
+ pass
- import re
- result = []
- expr = "(" + list[0].name
- for i in range(1, len(list)):
- expr = expr + "|"+ list[i].name
+ def parse_dependencies(self):
+ # Parse 'dependencies' part of the XML file
+ depsMap = {}
+ depsElem = self.docElem.getElementsByTagName('dependencies')[0]
+ for prodElem in depsElem.getElementsByTagName('product'):
+ prodName = prodElem.getAttribute('name').strip()
+ if not prodName: continue
+ depsList = []
+ for depElem in prodElem.getElementsByTagName('dep'):
+ depsList.append(depElem.firstChild.data)
+ pass
+ depsMap[prodName] = depsList
+ pass
+ return depsMap
- 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)
+ def parse_product(self):
+ # Parse 'products' part of the XML file
+ depsMap = self.parse_dependencies()
+ prodsElem = self.docElem.getElementsByTagName('products')[0]
+ sal_prods_list = []; req_prods_list = []
+ modules_list = []; prereqs_list = []
+ for prodElem in prodsElem.getElementsByTagName('product'):
+ prodName = prodElem.getAttribute('name').strip()
+ if not prodName: continue
+ instElems = prodElem.getElementsByTagName('installation')
+ instElem = None
+ for node in instElems:
+ if not self.pltname or self.pltname == node.getAttribute('os').strip():
+ instElem = node
+ break
+ pass
+ if not instElem: continue
+ if check_bool(str(instElem.getAttribute('disable').strip())): continue
+ depsList = []
+ if prodName in depsMap: depsList = depsMap[prodName]
+ aProduct = Product(prodName,
+ prodElem.getAttribute('type').strip(),
+ instElem.getAttribute('os').strip(),
+ instElem.getAttribute('version').strip(),
+ depsList,
+ instElem.getAttribute('woguimode').strip(),
+ instElem.getAttribute('installdiskspace').strip(),
+ instElem.getAttribute('script').strip(),
+ instElem.getAttribute('pickupenv').strip())
+ if self.is_force_src:
+ aProduct.setMode(__BUILDSRC__)
+ pass
+ if prodElem.getAttribute('type').strip() == "component":
+ sal_prods_list.append(aProduct)
+ # fill an ordered modules list -----------
+ modules_list.append(prodName)
+ modules_list.append(prodName + "_src")
+ pass
+ else: #prerequisite
+ req_prods_list.append(aProduct)
+ # fill an ordered prerequisites list -----------
+ prereqs_list.append(prodName)
+ #AKL: prerequisite sources and temp files are removed, by default.
+ # So, there is no need to make sources environment
+ #if aProduct.whattodo == __BUILDSRC__: prereqs_list.append(prodName + "_src")
+ pass
+ pass
+ self.products.extend( req_prods_list )
+ self.products.extend( sal_prods_list )
+ if len(self.products) != 0:
+ gcc_product = Product("gcc",
+ __CTX__PREREQUISITE__,
+ self.products[0].os,
+ "",
+ [],
+ None,
+ "0,0,0",
+ "gcc-common.sh",
+ "")
+ gcc_product.setMode(__PREINSTALL__)
+ self.products.insert(0, gcc_product)
+ prereqs_list.insert(0, gcc_product.name)
+ pass
+ self.full_prods_list.extend( prereqs_list )
+ self.full_prods_list.extend( modules_list )
+ pass
- return result
+ def parse(self, xml_file):
+ filehandle = open(xml_file)
+ sax_parser = xml.sax.make_parser()
+ doc = xml.dom.minidom.parse(filehandle, sax_parser)
+ filehandle.close()
+ self.docElem = doc.documentElement
+ self.parse_config()
+ self.parse_product()
+ pass
-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)
+ def getProduct(self, prod):
+ for product in self.products:
+ if product.name == prod:
+ return product
+ return None
- 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)
+#------------------------------------------------------------------#
+# #
+# SERVICE FUNCTIONS #
+# #
+#------------------------------------------------------------------#
- ind = 0;
- result[0] = list
+#==============================================================
+# message: prints diagnostic information
+#==============================================================
+def message(msg):
+ """
+ Prints diagnostic information.
+ """
+ if msg.strip():
+ print ">>>", msg
+ pass
- while (len(products)) :
- res = get_next_level(list, products)
- if len(res) == 0 :
- raise RuntimeError, "Empty list of products is found"
+#==============================================================
+# warning: prints warning
+#==============================================================
+def warning(msg):
+ """
+ Prints warning.
+ """
+ if msg.strip():
+ print ""
+ print msg
+ print ""
+ pass
- for product in res :
- products.remove(product)
+#==============================================================
+# 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
- ind = ind +1
- result[ind] = res
- list = res
-
- str = ""
- for i in result.keys():
- for product in result[i]:
- str = str + product.name + " "
+#==============================================================
+# 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)
- return str;
-
#=================================================================
-# The second algorithm
+# check_bool : checks boolean value: yes/no, true/false, 1/0
#=================================================================
-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+)?"
+def check_bool(val):
+ """
+ Checks boolean value.
+ """
+ try:
+ return boolean(val)
+ except:
+ pass
+ return False
- for product in products:
- product.dependencies = re.sub(r'\s+$', "", product.dependencies)
- product.dependencies = re.sub(r'^\s+', "", product.dependencies)
+#==============================================================
+# clean_all : performs system cleaning before exiting
+#==============================================================
+def clean_all():
+ """
+ Performs system cleaning before exiting.
+ """
+ global root_path
+ remove_dir(root_path)
+ pass
- product.dependencies = re.sub(regexpr1, "", product.dependencies)
- product.dependencies = re.sub(regexpr2, ",", product.dependencies)
+#==============================================================
+# 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. "
+ opt_parser.add_option("-f",
+ "--file",
+ action="store",
+ dest="xmlfile",
+ metavar="FILE",
+ help=help_str)
+ help_str = "The platform specification.\n"
+ help_str += "This option can be used in conjunction with --file option in order"
+ help_str += "to specify Linux platform name when XML file contains installation"
+ help_str += "options for several platforms."
+ opt_parser.add_option("-p",
+ "--platform",
+ action="store",
+ dest="platform",
+ metavar="PLT",
+ 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 = "Force all products to be installed from sources \n"
+ help_str += "including SALOME modules.\n"
+ help_str += "If this option is used all the default installation modes are ignored."
+ opt_parser.add_option("-a",
+ "--all-from-sources",
+ action="store_true",
+ dest="force_sources",
+ default=False,
+ help=help_str)
+ help_str = "Install all SALOME binaries packages to one directory.\n"
+ help_str += "This option is ignored when --all-from-sources (-a) option is used."
+ opt_parser.add_option("-s",
+ "--single-directory",
+ action="store_true",
+ dest="single_dir",
+ default=False,
+ 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, options.force_sources, options.single_dir, options.platform]
- return deps
+#=================================================================
+# strip : removes spaces at the beginning and at the end of the
+# <param> 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 a list of installed and required products.
+ """
+ prods_list = []
+ for product in prods:
+ for dep in product.dependencies:
+ if dep and dep not in prods_list:
+ prods_list.append( dep )
+ dep_name = dep
+ if product.whattodo == __BUILDSRC__:
+ dep_name = dep + "_src"
+ if dep_name not in parser.full_prods_list:
+ msg = "Prerequisite '%s' is required for '%s' product,\n"%(dep, product.name)
+ msg += "but the first one is absent in the list of products to be installed!\n"
+ msg += "Please check your XML file."
+ warning(msg)
+
+ if product.name and product.name not in prods_list:
+ prods_list.append( product.name )
+
+ return " ".join( prods_list )
+
#==============================================================
-# Creates dir, returns the part of path that existed early.
-# Access may be defined.
+# 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):
- import string, os
- dirs = string.split(directory, "/")
- existing = ""; dir = ""
+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 = directory.split("/")
+ existing = "";
+ dir = ""
root = ""
- for item in dirs:
- if len(item) == 0: continue
- dir = dir + "/"+item
+ for subdir in dirs:
+ if len(subdir) == 0: continue
+ dir = "%s/%s"%(dir, subdir)
if os.path.exists(dir):
existing = dir
else:
- os.mkdir(dir, access )
- #root= existing + "/"+item
- if dir == existing + "/"+item :
+ 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
- #else : root = existing
-
return root
#==============================================================
-# class Product
+# substituteVars : performes environment variables substistution
+# the given string; if varibale is not defined
+# it is substituted by the empty string
#==============================================================
-
-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
+def substituteVars(str):
+ """
+ Performes environment variables substistution.
+ """
+ str = os.path.expanduser(str)
+ str = os.path.expandvars(str)
+ return str
#================================================================
-# get the path using file name
+# get_program_path : gets program's directory path
+# (and performs 'cd' command there)
#================================================================
-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
+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()
#================================================================
-# checks dir existing
+# check_dir : checks directory existence
#================================================================
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 :
+ """
+ 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):
- print "Directory " + dir + " does not exist"
- return 0
- return 1
+ msg = "Directory %s does not exist. Stopped..."%dir
+ error_exit(msg, False)
+ pass
#===============================================================
-# Checks the disk space. Exit from interpreter if there is no
-# enough disk space.
+# check_disk_space : checks the disk space;
+# quits if there is no enough disk space
#===============================================================
-def check_disk_space(products, script_dir, target_dir, tmp_dir):
- import re, string, os
+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.
+ """
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))
+ for product in products:
+ prod_space = 0
+ try:
+ spaces = product.installdiskspace.split(',')
+ prod_space = int( spaces[0] )
+ if product.whattodo == __BINARIES__:
+ prod_space = int( spaces[0] )
+ if product.type == __CTX__COMPONENT__:
+ prod_space += int( spaces[1] )
+ else:
+ if product.type == __CTX__PREREQUISITE__:
+ prod_space = int( spaces[0] )
+ else:
+ prod_space = int( spaces[2] )
+ except:
+ pass
+ install_space = install_space + prod_space
+ pass
+
+ res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", target_dir, install_space))
if res:
- print "There is no enough space for tmp directory."
- return 0
-
- return 1
+ msg = "There is no enough space to install the products. 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
-#================================================================
-# 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>")
+#==============================================================
+# 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.whattodo == __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.whattodo == __BUILDSRC__:
+ 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))
+
+#==============================================================
+# get_os_release : gets OS release; the OS name, version and
+# architecture
+# For example:
+# RedHat, 8.0; Mandriva, 2006.0, 64
+#===============================================================
+def get_os_release():
+ filename = "/etc/issue"
+ # ---
+ plt_name = "unknown"
+ plt_ver = ""
+ plt_arch = ""
+ if os.path.exists(filename):
+ # ---
+ f = open(filename)
+ lines = f.readlines()
+ f.close()
+ # ---
+ regvar = re.compile("(.*)\s+[^\s]*[R|r]elease[^\s]*\s+([\d.]*)")
+ regvar1 = re.compile("(.*)\s+[^\s]*[L|l][I|i][N|n][U|u][X|x][^\s]*(.*)\s+([\d.]*)\s+")
+ for l in lines:
+ res = re.search(regvar, l)
+ if not res:
+ res = re.search(regvar1, l)
+ if res:
+ plt_name = " ".join(" ".join(res.groups()[:len(res.groups())-1]).split())
+ # workaround for Mandrake and other platforms
+ plt_name = plt_name.replace("Linux", "").replace("linux", "").replace("LINUX", "").strip()
+ # workaround for SuSe
+ plt_name = plt_name.replace("Welcome to", "").strip()
+ # ---
+ plt_name = " ".join(plt_name.split())
+ plt_ver = res.group(len(res.groups()))
+ if re.search(r'x86_64', l):
+ plt_arch = "64bit"
+ pass
+ # workaround for Red Hat Enterprise
+ if not plt_arch:
+ try:
+ import platform
+ if platform.machine() == "x86_64":
+ plt_arch = "64bit"
+ pass
+ pass
+ except:
+ pass
+ pass
+ break
+ pass
+ pass
+
+ return plt_name, plt_ver, plt_arch
+
+#==============================================================
+# 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, False)
if not os.access(xml_file, os.R_OK):
- print "There is no acceess to read "+ xml_file
- sys.exit(1)
+ msg = "There is no read access for %s file!"%xml_file
+ 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 = {}
+ if xml_file:
+ xml_file_list = [xml_file]
+ pass
+ else:
+ xml_file_list = filter(lambda i: i.endswith(".xml"), os.listdir(get_program_path()))
+ while 'config.xml' in xml_file_list: xml_file_list.remove('config.xml')
+ if os.path.exists(os.path.join(get_program_path(), 'config.xml')):
+ xml_file_list.append('config.xml')
+ xml_file_list = [os.path.abspath(i) for i in xml_file_list]
+ pass
+ for an_xml_file in xml_file_list: # XML files parsing
+ check_xml_file(an_xml_file)
+ parser = ConfigParser()
+ parser.parse(an_xml_file)
+ if parser.config.platforms is not None:
+ for plt in parser.config.platforms.split(","):
+ if not plt or plt in platforms_map.keys(): continue
+ platforms_map[strip(plt)] = an_xml_file
+ pass
+ pass
+ pass
+ return platforms_map
+
+#==============================================================
+# Print menu with list of supported platform
+# and return user choice
+#===============================================================
+def select_platform(all_platforms):
+ platforms = all_platforms.keys()
+ platforms.sort()
+ pltname = None
+ while not pltname:
+ print "Please, select any platform from the list below."
+ print "--------------------------"
+ for idx in range(len(platforms)):
+ print " %2d. %s" % (idx+1, " ".join(platforms[idx].split("_")))
+ print " 0. Exit"
+ print "--------------------------"
+ print "Type your choice (%d-%d) and press <Enter>:" % (0, len(platforms)),
+ try:
+ idx = raw_input()
+ except:
+ sys.exit(1)
+ try:
+ idx = int(idx)
+ except:
+ warning("Invalid input!")
+ pass
+ if idx == 0: sys.exit(0)
+ if idx > 0 and idx <= len(platforms):
+ pltname = platforms[idx-1]
+ else:
+ warning("Invalid input!")
+ pass
+ return pltname, all_platforms[pltname]
+
+#==============================================================
+# Check existence of required libraries in system and
+# warn user if some ones are absent
+#===============================================================
+def check_not_found_libs(filepath, optlibs):
+ a_file = open(filepath, 'r')
+ nf_mand_libs = list()
+ nf_opt_libs = list()
+ pref_opt_libs = optlibs.split(",")
+ for line in a_file:
+ line = line.strip()
+ if not line:
+ continue
+ line = line.split(" ")[0]
+ if line in nf_mand_libs or line in nf_opt_libs:
+ continue
+ is_optional = False;
+ for opt_lib in pref_opt_libs:
+ if line.lower().startswith(opt_lib.lower().strip()):
+ is_optional = True
+ break
+ if is_optional:
+ nf_opt_libs.append(line)
+ else:
+ nf_mand_libs.append(line)
+ pass
+
+ msg = "=== WARNING: Some libraries are absent! ===\n"
+ if nf_mand_libs:
+ msg += "One or several MANDATORY libraries listed below are not found. SALOME may not work properly.\n\t"
+ msg += "\n\t".join(nf_mand_libs)
+ msg += "\n"
+ if nf_opt_libs:
+ msg += "One or several OPTIONAL libraries listed below are not found. This does not affect on the correct work of SALOME platform.\n\t"
+ msg += "\n\t".join(nf_opt_libs)
+ if nf_mand_libs or nf_opt_libs:
+ print msg
+ a_file.close()
+ pass
+
+#------------------------------------------------------------------#
+# #
+# EXECUTION STARTS HERE #
+# #
+#------------------------------------------------------------------#
+
+if __name__ == "__main__":
+ # parse command line
+ [xml_file, target_dir, tmp_dir, is_gui, is_force_src, is_single_dir, pltname] = 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 ----------------
+
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"] = "./bin/lib:" + ".:" + env["LD_LIBRARY_PATH"]
+ env["PATH"] = ".:" + env["PATH"]
+
+ cmd = "./bin/SALOME_InstallWizard"
+ if xml_file is not None:
+ cmd += " --file %s"%xml_file
+ if pltname is not None:
+ cmd += " --platform %s"%pltname
+ if target_dir is not None:
+ cmd += " --target %s"%target_dir
+ if tmp_dir is not None:
+ cmd += " --tmp %s"%tmp_dir
+ if is_force_src:
+ cmd += " --all-from-sources"
+ if is_single_dir:
+ cmd += " --single-directory"
+ cmd += "&"
+ sys.exit(os.system(cmd))
- env["LD_LIBRARY_PATH"] = ".:" + env["LD_LIBRARY_PATH"]
- env["PATH"] = ".:"+ env["PATH"]
+ #----- TUI ---------------------
+ #
+ # define xml file to be used
+ #
+ # get current Linux platform
+ plt_name, plt_ver, plt_arch = get_os_release()
+ data = []
+ for i in plt_name, plt_ver, plt_arch:
+ if i: data.append(i)
+ full_plt_name = " ".join(data)
+ # get all supported platforms
+ all_platforms = get_supported_platforms(xml_file)
+ if all_platforms:
+ if pltname:
+ # platform name is specified in the command line
+ if pltname in all_platforms:
+ # if specified platform is supported, choose the corresponding XML file for use
+ xml_file = all_platforms[pltname]
+ else:
+ # if specified platform is NOT supported, print warning message
+ # and prompt user to choose another platform
+ msg = "Specified platform is not supported: %s" % (pltname)
+ warning(msg)
+ pltname, xml_file = select_platform(all_platforms)
+ pass
+ pass
+ elif full_plt_name in all_platforms:
+ # if current platform is supported, choose the corresponding XML file for use
+ pltname = full_plt_name
+ xml_file = all_platforms[pltname]
+ else:
+ if xml_file and len(all_platforms) == 1:
+ # XML file is specified and contains only one platform definition
+ xml_file = all_platforms.values()[0]
+ pltname = all_platforms.keys()[0]
+ else:
+ # current Linux platform is not supported, print warning message
+ # and prompt user to choose platform from the list
+ warning("Not supported Linux platform: %s."%" ".join(data))
+ pltname, xml_file = select_platform(all_platforms)
+ pass
+ pass
+ else:
+ # current Linux platform is not supported, exit
+ if pltname:
+ msg = "Not supported Linux platform: %s."%pltname
+ else:
+ msg = "Not supported Linux platform: %s."%" ".join(data)
+ error_exit(msg, False)
+ pass
- sys.exit(os.system("cd " + cur_dir + "; ./bin/SALOMEPRO_InstallWizard " + xml_file +"&"))
-
-
+ # parse XML file -----------
+ message("Parsing XML configuration file: %s"%xml_file)
+ parser = ConfigParser(is_force_src, pltname)
+ parser.parse(xml_file)
- #----- TUI ---------------------
+ # source directory map
+ bin_dir = ""
+ if parser.config.platforms:
+ bin_dir += "/%s"%"_".join( parser.pltname.split() )
+ subdir = { __BINARIES__ : "BINARIES" + bin_dir,
+ __BUILDSRC__ : "SOURCES",
+ __PREINSTALL__ : ""}
- #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")
+ # check scripts directory -----------
+ scripts_dir = "%s/%s"%(cur_dir, "config_files")
+ check_dir(scripts_dir)
- 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 --------
+ # 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[__BUILDSRC__]))
+
+ if has_bin:
+ check_dir("%s/%s"%(source_dir,subdir[__BINARIES__]))
+
+ # check/create target dir -----------
if target_dir is None:
- target_dir = parser.path.targetdir
+ target_dir = parser.config.targetdir
+ target_dir = substituteVars(target_dir)
+
+ message("Creating target directory: " + target_dir)
+ create_dir(target_dir, 0755)
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")
+ error_exit("Invalid target directory: " + target_dir)
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)
-
+ error_exit("There is no write permissions for the directory: " + target_dir)
- # 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)
+ # check/create temporary dir -----------
+ if tmp_dir is None:
+ tmp_dir = parser.config.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)
- list_of_dep = create_levels(parser.products)
- #list_of_dep = get_dependencies_set(parser.products)
+ 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, is_force_src)
- if check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir) :
-
- for product in parser.products :
+ # change current directory -----------
+ os.chdir(scripts_dir)
- if product.disable == "true": continue
+ # get dependencies list -----------
+ list_of_dep = get_dependencies(parser.products)
+ products_string = " ".join(parser.full_prods_list)
- cmd = scripts_dir + product.script + " " + \
- what_to_do[product.install]+ " " + \
- tmp_dir + " " + \
- source_dir + "/" + subdir[product.install] + " " + \
- target_dir + " " + \
- '"' + list_of_dep + '"' + " " + \
- product.name
+ # don't remove sources and tmp files, by default -----------
+ rm_src_tmp = "FALSE"
+ # starting -----------
+ message("Starting ...")
+
+ # install products -----------
+ for product in parser.products:
+ # remove only prerequisites temporary files
+ if product.type == __CTX__PREREQUISITE__ or \
+ (product.type == __CTX__COMPONENT__ and product.whattodo == __BUILDSRC__):
+ rm_src_tmp = "TRUE"
+ message("... processing %s ..."%product.name)
+ cmd = '%s/%s %s %s %s/%s %s "%s" %s "%s" %s/%s %s %s/%s' % (
+ scripts_dir, product.script,
+ product.whattodo,
+ tmp_dir,
+ source_dir, subdir[product.whattodo],
+ target_dir,
+ products_string,
+ product.name,
+ products_string,
+ source_dir, subdir[__BUILDSRC__],
+ rm_src_tmp,
+ source_dir, subdir[__BINARIES__]
+ )
+ # install all modules with GUI
+ if product.woguiinst is not None and product.woguiinst != "":
+ cmd += ' TRUE'
+ # use single directory or not
+ if product.whattodo == __BINARIES__ and product.type == __CTX__COMPONENT__ and is_single_dir:
+ cmd += ' TRUE'
+ res = os.system(cmd)
+ rm_src_tmp = "FALSE"
+ pass
+
+ # 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 "%s" %s/%s %s %s/%s' % (
+ scripts_dir, product.script,
+ tmp_dir,
+ source_dir, subdir[product.whattodo],
+ target_dir,
+ products_string,
+ product.name,
+ products_string,
+ source_dir, subdir[__BUILDSRC__],
+ rm_src_tmp,
+ source_dir, subdir[__BINARIES__]
+ )
+ # install all modules with GUI
+ if product.woguiinst is not None and product.woguiinst != "":
+ cmd += ' TRUE'
+ # use single directory or not
+ if product.whattodo == __BINARIES__ and product.type == __CTX__COMPONENT__ and is_single_dir:
+ cmd += ' TRUE'
res = os.system(cmd)
- if res : break;
+ pass
+ pass
- if len(root_path) and os.path.exists(root_path):
- os.system("rm -r -f "+ root_path)
+ if not is_force_src:
+ if is_single_dir:
+ # modify *.la files, if --single-directory option was pointed -----------
+ message("Modifying of *.la files of SALOME modules...")
+ cmd = '%s/modifyLaFiles.sh modify_la_files %s' % (scripts_dir, target_dir)
+ res = os.system(cmd)
+ else:
+ # check that all required libraries are in system
+ message("Check existence of Fortran and other required libraries...")
+ cmd = '%s/checkFortran.sh find_libraries %s > %s/not_found_libs.txt' % (scripts_dir, target_dir, tmp_dir)
+ if os.system(cmd):
+ check_not_found_libs("%s/not_found_libs.txt" % (tmp_dir), parser.config.optlibs)
+
+ # clean temporary directory -----------
+ message("Cleaning temporary directory")
+ clean_all()
+
+ # finishing -----------
+ message("Finished!")
+ pass