4 Installation Wizard launching script.
6 This script is the part of the SALOME installation procedure.
7 Author : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
8 Created : Thu Dec 18 12:01:00 2002
9 Copyright : 2002-2013 CEA
18 import xml.sax, xml.dom.minidom
23 except Exception, an_exc:
24 sys.exit("Error: %s! Please check the installed Python package." % str(an_exc))
27 # --- avoid "deprecation" warnings --- #
28 warnings.filterwarnings("ignore", "", DeprecationWarning)
30 # --- global variables --- #
34 # --- actions definition --- #
35 __BINARIES__ = "install_binary"
36 __BUILDSRC__ = "install_source_and_build"
37 __PREINSTALL__ = "try_preinstalled"
39 # --- product type definition --- #
40 __CTX__COMPONENT__ = "component"
41 __CTX__PREREQUISITE__ = "prerequisite"
43 #------------------------------------------------------------------#
45 # COMMAND LINE ARGUMENTS PARSER #
47 #------------------------------------------------------------------#
49 #===================================================================
50 # class OptBaseError : base parse error
51 #===================================================================
52 class OptBaseError(Exception):
54 Base option parsing exception class
56 def __init__(self, msg):
61 #===================================================================
62 # class OptError : bad option error
63 #===================================================================
64 class OptError(OptBaseError):
66 Bad option exception class
68 def __init__ (self, msg, option):
74 if self.option.short_opt and self.option.long_opt:
75 opt_prs = "%s/%s"%(self.option.short_opt,self.option.long_opt)
76 elif self.option.short_opt:
77 opt_prs = "%s"%(self.option.short_opt)
78 elif self.option.long_opt:
79 opt_prs = "%s"%(self.option.long_opt)
80 return "option %s: %s"%(opt_prs, self.msg)
83 #===================================================================
84 # class ArgError : bad option argument error
85 #===================================================================
86 class ArgError(OptBaseError):
88 Bad argument exception class
92 #===================================================================
93 # class ValError : bad command line parameter error
94 #===================================================================
95 class ValError(OptBaseError):
97 Bad parameter exception class
101 #===================================================================
102 # class ArgOption : command line option
103 #===================================================================
108 attrs = ["short_opt", "long_opt", "dest", "action", "type", "default", "metavar", "help"]
109 actions = ["store", "store_true", "store_false"]
110 types = ["string", "int", "float", "bool"]
111 def __init__(self, *args, **kwargs):
113 for attr in self.attrs: setattr(self, attr, None)
115 for i in range(len(args)):
116 if i > len(self.attrs)-1:
117 msg = "Wrong number of parameters is given (maximum is %d)" % len(self.attrs)
118 raise OptBaseError(msg)
119 setattr(self, self.attrs[i], args[i])
121 if arg not in self.attrs:
122 msg = "Invalid argument: %s" % arg
123 raise OptBaseError(msg)
124 setattr(self, arg, kwargs[arg])
125 # check short option key
126 if self.short_opt and \
127 not re.match("^-[a-zA-Z]$",self.short_opt):
128 msg = "invalid short option key; "
129 msg += "should be of the form -x (x is letter)"
130 raise OptError(msg, self)
131 # check long option key
132 if self.long_opt and \
133 not re.match("^--[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*$",self.long_opt):
134 msg = "invalid long option key; "
135 msg += "should be of the form --word[[-word]...] "
136 msg += "(word is letters and digits sequence)"
137 raise OptError(msg, self)
138 # check that at least one option key is defined
139 if not self.short_opt and not self.long_opt:
140 msg = "invalid option; neither short nor long option key is defined"
141 raise OptError(msg, self)
143 if not self.dest and self.long_opt:
144 self.dest = self.long_opt[2:].replace('-','_')
145 if not self.dest and self.short_opt:
146 self.dest = self.short_opt[1:]
149 self.action = "store"
150 if self.action not in self.actions:
151 msg = "invalid action: %s" % self.action
152 raise OptError(msg, self)
155 if self.action in ["store_true","store_false"]: self.type = "bool"
156 else: self.type = "string"
157 if self.type not in self.types:
158 msg = "invalid type: %s" % self.type
159 raise OptError(msg, self)
160 if self.action in ["store_true","store_false"] and self.type != "bool":
161 msg = "invalid type: %s : should be 'bool' or None" % self.type
162 raise OptError(msg, self)
164 if self.default is not None:
166 if self.type == "string": self.default = str(self.default)
167 if self.type == "int": self.default = int(self.default)
168 if self.type == "float": self.default = float(self.default)
169 if self.type == "bool": self.default = boolean(self.default)
171 msg = "invalid default value type: should be %s" % self.type
172 raise OptError(msg, self)
176 self.metavar = self.dest.upper()
184 Returns string representation of the option
188 if opt and self.action == "store" and self.metavar: opt += " %s" % self.metavar
189 if opt: opts.append(opt)
191 if opt and self.action == "store" and self.metavar: opt += "=%s" % self.metavar
192 if opt: opts.append(opt)
193 return (", ").join(opts)
195 #===================================================================
196 # class Values : resulting option values
197 #===================================================================
205 #===================================================================
206 # class ArgParser : command line arguments parser
207 #===================================================================
210 Arguments parser class
216 def add_option(self, *args, **kwargs):
217 """Register an option"""
218 o = ArgOption(*args, **kwargs)
219 self._check_option(o)
220 self.options.append(o)
223 def parse_args(self, args = None):
224 """Parse an arguments"""
225 if not args: args = sys.argv[1:]
227 for o in self.options:
228 if o.default is not None:
229 setattr(values, o.dest, o.default)
230 elif not hasattr(values,o.dest):
231 setattr(values, o.dest, None)
233 (values, args) = self._process_args(values, args)
234 except (ArgError, ValError), e:
237 return (values, args)
239 def print_usage(self):
241 print "usage: %s [options]" % os.path.basename(sys.argv[0])
244 def print_help(self):
249 _maxwidth, _indent = 79, 2
250 if len(self.options):
251 for option in self.options:
252 if olen < len(option.to_string()): olen = len(option.to_string())
254 for option in self.options:
256 for hs in option.help.split("\n"):
259 if len("%s %s" % (s,w)) > _maxwidth:
260 strings.append(s.strip()); s = ""
262 if s.strip(): strings.append(s.strip())
263 if not strings: strings[:0] = [""]
264 print "%s%s%s" % (option.to_string(), " "*(_indent+olen-len(option.to_string())), strings[0])
265 for i in range(1, len(strings)):
266 print "%s%s" % (" "*(olen+_indent), strings[i])
269 def _check_option(self, option):
270 o = self._get_option(option.short_opt)
271 if not o: o = self._get_option(option.long_opt)
273 msg = "option conflicts with previously defined option(s)"
274 raise OptError(msg, option)
277 def _get_option(self, opt_key):
279 for o in self.options:
280 if opt_key in [o.short_opt, o.long_opt]: return o
283 def _error(self, msg):
285 sys.exit("\n%s: error: %s\n" % (os.path.basename(sys.argv[0]), msg))
288 def _check_value(self, option, value):
289 o = self._get_option(option)
291 if o.type == "string": return str(value)
292 if o.type == "int": return int(value)
293 if o.type == "float": return float(value)
294 if o.type == "bool": return boolean(value)
296 msg = "invalid value type for option %s: %s; " % (option, value)
297 msg += "should be %s" % o.type
299 raise OptBaseError("unknown error")
301 def _process_args(self, values, args):
305 for index in range(len(args)):
307 if cur_opt and cur_opt[1].action == "store":
308 setattr(values, cur_opt[1].dest, self._check_value(cur_opt[0], a))
312 rargs = args[index+1:]
314 elif re.match("^-[a-zA-Z].*", a):
315 for i in range(1,len(a)):
316 if cur_opt and cur_opt[1].action == "store":
317 setattr(values, cur_opt[1].dest, self._check_value(cur_opt[0], a[i:]))
320 o = self._get_option("-%s"%a[i])
322 raise ArgError("no such option: -%s"%a[i])
323 if o.action == "store_true":
324 setattr(values, o.dest, True)
325 elif o.action == "store_false":
326 setattr(values, o.dest, False)
328 cur_opt = ("-%s"%a[i], o)
330 elif re.match("^--[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*", a):
331 oname = ("%s="%a).split("=")[0]
332 ovalue = ("%s="%a).split("=")[1]
333 o = self._get_option(oname)
335 raise ArgError("no such option: %s" % oname)
336 if o.action == "store_true":
338 raise ValError("option %s does not take a value" % oname)
339 setattr(values, o.dest, True)
340 elif o.action == "store_false":
342 raise ValError("option %s does not take a value" % oname)
343 setattr(values, o.dest, False)
346 setattr(values, o.dest, self._check_value(oname, ovalue))
350 elif a.startswith("-"):
351 raise ArgError("bad formatted option: %s" % a)
355 if cur_opt and cur_opt[1].action == "store":
356 raise ValError("option %s requires value" % cur_opt[0])
357 return (values, rargs)
359 #------------------------------------------------------------------#
361 # XML CONFIGURATION FILES PARSER #
363 #------------------------------------------------------------------#
365 #===================================================================
366 # class Config : general configuration options : version, target and
367 # temporary directories, etc...
368 #===================================================================
371 General configuration file options:
372 - Install Wizard window caption
373 - SALOME platform version
374 - Copyright and license info
375 - Default target and temporary directories
376 - List of optional libraries for Salome
387 self.version = strip(theVersion)
388 self.caption = strip(theCaption)
389 self.copyright = strip(theCopyright)
390 self.license = strip(theLicense)
391 self.platforms = strip(thePlatforms)
392 self.targetdir = strip(theTargetdir)
393 self.tmpdir = strip(theTmpdir)
394 self.optlibs = strip(theOptLibs)
396 #==============================================================
397 # class Product : pre-requisite product options
398 #==============================================================
403 - target Linux OS version
405 - required disk space
406 - installation script
414 theDependencies = None,
415 theWoGuiInstallation = None,
416 theInstalldiskspace = None,
418 thePickUpEnvironment = None):
419 self.name = strip(theName)
420 self.type = strip(theType)
421 self.os = strip(theOS)
422 self.version = strip(theVersion)
423 self.dependencies = strip(theDependencies)
424 self.woguiinst = strip(theWoGuiInstallation)
425 self.installdiskspace = strip(theInstalldiskspace)
426 self.script = strip(theScript)
427 self.pickupEnv = strip(thePickUpEnvironment)
428 self.whattodo = __BINARIES__
430 def setMode(self, mode):
431 if mode not in [__BINARIES__, __BUILDSRC__, __PREINSTALL__]:
436 #===================================================================
437 # class ConfigParser : XML files parser implementation
438 #===================================================================
441 XML configuration files parser
443 def __init__(self, is_force_src=False, pltname=None):
446 self.full_prods_list = []
448 self.is_force_src = is_force_src
449 self.pltname = pltname
452 def parse_config(self):
453 # Parse 'config' part of the XML file
454 configElem = self.docElem.getElementsByTagName('config')[0]
456 self.config = Config(configElem.getAttribute('version').strip(),
457 configElem.getAttribute('caption').strip(),
458 configElem.getAttribute('copyright').strip(),
459 configElem.getAttribute('license').strip(),
460 configElem.getAttribute('platforms').strip(),
461 configElem.getAttribute('targetdir').strip(),
462 configElem.getAttribute('tempdir').strip(),
463 configElem.getAttribute('optionallibs').strip())
464 if not self.pltname and self.config.platforms:
465 self.pltname = self.config.platforms.split(",")[0].strip()
468 def parse_dependencies(self):
469 # Parse 'dependencies' part of the XML file
471 depsElem = self.docElem.getElementsByTagName('dependencies')[0]
472 for prodElem in depsElem.getElementsByTagName('product'):
473 prodName = prodElem.getAttribute('name').strip()
474 if not prodName: continue
476 for depElem in prodElem.getElementsByTagName('dep'):
477 depsList.append(depElem.firstChild.data)
479 depsMap[prodName] = depsList
483 def parse_product(self):
484 # Parse 'products' part of the XML file
485 depsMap = self.parse_dependencies()
486 prodsElem = self.docElem.getElementsByTagName('products')[0]
487 sal_prods_list = []; req_prods_list = []
488 modules_list = []; prereqs_list = []
489 for prodElem in prodsElem.getElementsByTagName('product'):
490 prodName = prodElem.getAttribute('name').strip()
491 if not prodName: continue
492 instElems = prodElem.getElementsByTagName('installation')
494 for node in instElems:
495 if not self.pltname or self.pltname == node.getAttribute('os').strip():
499 if not instElem: continue
500 if check_bool(str(instElem.getAttribute('disable').strip())): continue
502 if prodName in depsMap: depsList = depsMap[prodName]
503 aProduct = Product(prodName,
504 prodElem.getAttribute('type').strip(),
505 instElem.getAttribute('os').strip(),
506 instElem.getAttribute('version').strip(),
508 instElem.getAttribute('woguimode').strip(),
509 instElem.getAttribute('installdiskspace').strip(),
510 instElem.getAttribute('script').strip(),
511 instElem.getAttribute('pickupenv').strip())
512 if self.is_force_src:
513 aProduct.setMode(__BUILDSRC__)
515 if prodElem.getAttribute('type').strip() == "component":
516 sal_prods_list.append(aProduct)
517 # fill an ordered modules list -----------
518 modules_list.append(prodName)
519 modules_list.append(prodName + "_src")
522 req_prods_list.append(aProduct)
523 # fill an ordered prerequisites list -----------
524 prereqs_list.append(prodName)
525 #AKL: prerequisite sources and temp files are removed, by default.
526 # So, there is no need to make sources environment
527 #if aProduct.whattodo == __BUILDSRC__: prereqs_list.append(prodName + "_src")
530 self.products.extend( req_prods_list )
531 self.products.extend( sal_prods_list )
532 if len(self.products) != 0:
533 gcc_product = Product("gcc",
534 __CTX__PREREQUISITE__,
542 gcc_product.setMode(__PREINSTALL__)
543 self.products.insert(0, gcc_product)
544 prereqs_list.insert(0, gcc_product.name)
546 self.full_prods_list.extend( prereqs_list )
547 self.full_prods_list.extend( modules_list )
550 def parse(self, xml_file):
551 filehandle = open(xml_file)
552 sax_parser = xml.sax.make_parser()
553 doc = xml.dom.minidom.parse(filehandle, sax_parser)
556 self.docElem = doc.documentElement
561 def getProduct(self, prod):
562 for product in self.products:
563 if product.name == prod:
568 #------------------------------------------------------------------#
570 # SERVICE FUNCTIONS #
572 #------------------------------------------------------------------#
574 #==============================================================
575 # message: prints diagnostic information
576 #==============================================================
579 Prints diagnostic information.
585 #==============================================================
586 # warning: prints warning
587 #==============================================================
598 #==============================================================
599 # error_exit : prints (optionally) error string, then prints
600 # help information and quits
601 #==============================================================
602 def error_exit(msg = "", print_help = True):
604 Prints (optionally) error string,
605 then prints help information and quits.
607 # print error message
612 # print help information
616 opt_parser.print_help()
624 #==============================================================
625 # boolean : Converts string to boolean value.
626 #==============================================================
629 Converts string to boolean value if possible.
630 Raises exception if wrong string is used.
632 if isinstance(val, types.StringType):
633 if val.strip().lower() in ["true", "yes", "ok"] : return True
634 elif val.strip().lower() in ["false", "no", "cancel"] : return False
635 else: raise TypeError("invalid boolean value")
638 #=================================================================
639 # check_bool : checks boolean value: yes/no, true/false, 1/0
640 #=================================================================
643 Checks boolean value.
651 #==============================================================
652 # clean_all : performs system cleaning before exiting
653 #==============================================================
656 Performs system cleaning before exiting.
659 remove_dir(root_path)
662 #==============================================================
663 # parse_parameters : parses command line arguments
664 #==============================================================
665 def parse_parameters():
667 Parses command line arguments.
670 opt_parser = ArgParser()
672 help_str = "Runs the Installation Wizard in the GUI mode [default].\n"
673 opt_parser.add_option("-g",
679 help_str = "Runs the Installation Wizard in the TUI mode."
680 opt_parser.add_option("-b",
682 action="store_false",
685 help_str = "The configuration xml file.\n"
686 help_str += "If this parameter is missing, then the program tries to define the "
687 help_str += "Linux platform and use the corresponding xml file. For example, "
688 help_str += "for Red Hat 8.0 config_RedHat_8.0.xml file is used in this case. "
689 opt_parser.add_option("-f",
695 help_str = "The platform specification.\n"
696 help_str += "This option can be used in conjunction with --file option in order"
697 help_str += "to specify Linux platform name when XML file contains installation"
698 help_str += "options for several platforms."
699 opt_parser.add_option("-p",
705 help_str = "The target directory the products to be installed to.\n"
706 help_str += "When used this parameter overrides the default target directory "
707 help_str += "defined in the configuration xml file."
708 opt_parser.add_option("-d",
714 help_str = "The directory to be used for temporary files.\n"
715 help_str += "When used this parameter overrides the default temporary directory "
716 help_str += "defined in the configuration xml file."
717 opt_parser.add_option("-t",
723 help_str = "Force all products to be installed from sources \n"
724 help_str += "including SALOME modules.\n"
725 help_str += "If this option is used all the default installation modes are ignored."
726 opt_parser.add_option("-a",
727 "--all-from-sources",
729 dest="force_sources",
732 help_str = "Install all SALOME binaries packages to one directory.\n"
733 help_str += "This option is ignored when --all-from-sources (-a) option is used."
734 opt_parser.add_option("-s",
735 "--single-directory",
740 help_str = "Prints version information and quits."
741 opt_parser.add_option("-v",
745 help_str = "Prints this help and quits."
746 opt_parser.add_option("-h",
750 (options, args) = opt_parser.parse_args()
752 # print help info and quit
753 print "\nSALOME Installation Wizard (running on %s)\n" % get_os_name()
754 opt_parser.print_help()
758 # print version info and quit
760 cmd = "./bin/SALOME_InstallWizard --version"
764 return [options.xmlfile, options.target_dir, options.tmp_dir, options.gui, options.force_sources, options.single_dir, options.platform]
766 #=================================================================
767 # strip : removes spaces at the beginning and at the end of the
768 # <param> if it is of string type
769 #=================================================================
772 Removes spaces at the beginning and at the end
773 of the given parameter.
775 if type(param) == types.StringType:
779 #=================================================================
780 # get_dependencies : extract products dependencies
781 #=================================================================
782 def get_dependencies(prods):
784 Gets a list of installed and required products.
787 for product in prods:
788 for dep in product.dependencies:
789 if dep and dep not in prods_list:
790 prods_list.append( dep )
792 if product.whattodo == __BUILDSRC__:
793 dep_name = dep + "_src"
794 if dep_name not in parser.full_prods_list:
795 msg = "Prerequisite '%s' is required for '%s' product,\n"%(dep, product.name)
796 msg += "but the first one is absent in the list of products to be installed!\n"
797 msg += "Please check your XML file."
800 if product.name and product.name not in prods_list:
801 prods_list.append( product.name )
803 return " ".join( prods_list )
805 #==============================================================
806 # create_dir : creates a directory with (optional) permissions,
807 # returns the part of path that existed before
808 # directory creation; exits with error if access
810 #==============================================================
811 def create_dir(directory, access = 0777):
813 Creates a directory with (optional) permissions,
814 returns the part of path that existed before
815 directory creation; exits with error if access
818 dirs = directory.split("/")
823 if len(subdir) == 0: continue
824 dir = "%s/%s"%(dir, subdir)
825 if os.path.exists(dir):
829 os.mkdir(dir, access)
831 error_exit("Can't create directory: %s.\nAccess is denied."%directory)
832 if dir == "%s/%s"%(existing, subdir):
836 #==============================================================
837 # substituteVars : performes environment variables substistution
838 # the given string; if varibale is not defined
839 # it is substituted by the empty string
840 #==============================================================
841 def substituteVars(str):
843 Performes environment variables substistution.
845 str = os.path.expanduser(str)
846 str = os.path.expandvars(str)
849 #================================================================
850 # get_program_path : gets program's directory path
851 # (and performs 'cd' command there)
852 #================================================================
853 def get_program_path():
855 Returns the program directory path
856 (and make this directory current).
858 path = os.path.dirname(sys.argv[0])
863 #================================================================
864 # check_dir : checks directory existence
865 #================================================================
868 Checks directory existence.
870 if (os.path.islink(dir)):
871 realpath = os.path.realpath(dir)
872 if not os.path.exists(realpath):
873 msg = "Invalid link %s.\nThe directory %s a link points to does not exist. Stopped..."%(dir,realpath)
874 error_exit(msg, False)
876 if not os.path.exists(dir):
877 msg = "Directory %s does not exist. Stopped..."%dir
878 error_exit(msg, False)
881 #===============================================================
882 # check_disk_space : checks the disk space;
883 # quits if there is no enough disk space
884 #===============================================================
885 def check_disk_space(products, scripts_dir, target_dir, tmp_dir, is_force_src=False):
887 Checks if there is enough disk space to install products.
888 Quits with error if there is no enough disk space.
892 for product in products:
895 spaces = product.installdiskspace.split(',')
896 prod_space = int( spaces[0] )
897 if product.whattodo == __BINARIES__:
898 prod_space = int( spaces[0] )
899 if product.type == __CTX__COMPONENT__:
900 prod_space += int( spaces[1] )
902 if product.type == __CTX__PREREQUISITE__:
903 prod_space = int( spaces[0] )
905 prod_space = int( spaces[2] )
908 install_space = install_space + prod_space
911 res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", target_dir, install_space))
913 msg = "There is no enough space to install the products. Stopped..."
914 error_exit(msg, False)
917 #===============================================================
918 # remove_dir : removes temporary directory
919 #===============================================================
920 def remove_dir(path):
922 Removes temporary directory.
924 if path and os.path.exists(path):
925 os.system("rm -rf " + path)
928 #==============================================================
929 # has_binaries : returns True if some product is installed from
931 #===============================================================
932 def has_binaries(products):
934 Returns True if some product is installed in 'binaries' mode.
936 for product in products:
937 if product.whattodo == __BINARIES__:
941 #==============================================================
942 # has_sources : returns True if some product is installed from
944 #===============================================================
945 def has_sources(products):
947 Returns True if some product is installed in 'sources' mode.
949 for product in products:
950 if product.whattodo == __BUILDSRC__:
954 #==============================================================
955 # get_tmp_dir : gets temporary directory name
956 #===============================================================
957 def get_tmp_dir(dir):
959 Gets temporary directory path.
962 dir_prefix="INSTALLWORK"
963 range_bottom = 0; range_top = 999999
964 for i in xrange(max_attempts):
965 tmp_dir = "%s/%s%d"%(dir, dir_prefix, random.randint(range_bottom,range_top))
966 if not os.path.exists( tmp_dir ):
968 return "%s/%s%d"%(dir, dir_prefix, random.randint(range_bottom,range_top))
970 #==============================================================
971 # get_os_release : gets OS release; the OS name, version and
974 # RedHat, 8.0; Mandriva, 2006.0, 64
975 #===============================================================
976 def get_os_release():
977 filename = "/etc/issue"
982 if os.path.exists(filename):
985 lines = f.readlines()
988 regvar = re.compile("(.*)\s+[^\s]*[R|r]elease[^\s]*\s+([\d.]*)")
989 regvar1 = re.compile("(.*)\s+[^\s]*[L|l][I|i][N|n][U|u][X|x][^\s]*(.*)\s+([\d.]*)\s+")
990 regvar2 = re.compile("([A-Za-z]+)\s+([0-9.]+)\s+.*")
992 res = re.search(regvar, l)
994 res = re.search(regvar1, l)
996 res = re.search(regvar2, l)
998 plt_name = " ".join(" ".join(res.groups()[:len(res.groups())-1]).split())
999 # workaround for Mandrake and other platforms
1000 plt_name = plt_name.replace("Linux", "").replace("linux", "").replace("LINUX", "").strip()
1001 # workaround for SuSe
1002 plt_name = plt_name.replace("Welcome to", "").strip()
1004 plt_name = " ".join(plt_name.split())
1005 plt_ver = res.group(len(res.groups()))
1006 if re.search(r'x86_64', l):
1009 # workaround for Red Hat Enterprise
1013 if platform.machine() == "x86_64":
1024 return plt_name, plt_ver, plt_arch
1026 #==============================================================
1027 # get_os_name : gets qualified OS name
1029 # Mandriva 2010.0 64bit
1030 #===============================================================
1032 plt_name, plt_ver, plt_arch = get_os_release()
1034 for i in plt_name, plt_ver, plt_arch:
1035 if i: data.append(i)
1036 return " ".join(data)
1038 #==============================================================
1039 # check_xml_file : checks XML file existence and readability
1040 #===============================================================
1041 def check_xml_file(xml_file):
1043 Checks XML file existence and readability.
1045 if not os.path.isfile(xml_file):
1046 msg = "Configuration file %s is not found!"%xml_file
1047 error_exit(msg, False)
1049 if not os.access(xml_file, os.R_OK):
1050 msg = "There is no read access for %s file!"%xml_file
1051 error_exit(msg, False)
1054 #==============================================================
1055 # get_supported_plts : gets map of supported Linux platforms and
1056 # corresponding configuration files
1057 #===============================================================
1058 def get_supported_platforms(xml_file=None):
1060 Gets map of supported Linux platforms and
1061 corresponding configuration files.
1065 xml_file_list = [xml_file]
1068 xml_file_list = filter(lambda i: i.endswith(".xml"), os.listdir(get_program_path()))
1069 while 'config.xml' in xml_file_list: xml_file_list.remove('config.xml')
1070 if os.path.exists(os.path.join(get_program_path(), 'config.xml')):
1071 xml_file_list.append('config.xml')
1072 xml_file_list = [os.path.abspath(i) for i in xml_file_list]
1074 for an_xml_file in xml_file_list: # XML files parsing
1075 check_xml_file(an_xml_file)
1076 parser = ConfigParser()
1077 parser.parse(an_xml_file)
1078 if parser.config.platforms is not None:
1079 for plt in parser.config.platforms.split(","):
1080 if not plt or plt in platforms_map.keys(): continue
1081 platforms_map[strip(plt)] = an_xml_file
1085 return platforms_map
1087 #==============================================================
1088 # Print menu with list of supported platform
1089 # and return user choice
1090 #===============================================================
1091 def select_platform(all_platforms):
1092 platforms = all_platforms.keys()
1096 print "Please, select any platform from the list below."
1097 print "--------------------------"
1098 for idx in range(len(platforms)):
1099 print " %2d. %s" % (idx+1, " ".join(platforms[idx].split("_")))
1101 print "--------------------------"
1102 print "Type your choice (%d-%d) and press <Enter>:" % (0, len(platforms)),
1110 warning("Invalid input!")
1112 if idx == 0: sys.exit(0)
1113 if idx > 0 and idx <= len(platforms):
1114 pltname = platforms[idx-1]
1116 warning("Invalid input!")
1118 return pltname, all_platforms[pltname]
1120 #==============================================================
1121 # Check existence of required libraries in system and
1122 # warn user if some ones are absent
1123 #===============================================================
1124 def check_not_found_libs(filepath, optlibs):
1125 a_file = open(filepath, 'r')
1126 nf_mand_libs = list()
1127 nf_opt_libs = list()
1128 pref_opt_libs = optlibs.split(",")
1133 line = line.split(" ")[0]
1134 if line in nf_mand_libs or line in nf_opt_libs:
1136 is_optional = False;
1137 for opt_lib in pref_opt_libs:
1138 if line.lower().startswith(opt_lib.lower().strip()):
1142 nf_opt_libs.append(line)
1144 nf_mand_libs.append(line)
1147 msg = "=== WARNING: Some libraries are absent! ===\n"
1149 msg += "One or several MANDATORY libraries listed below are not found. SALOME may not work properly.\n\t"
1150 msg += "\n\t".join(nf_mand_libs)
1153 msg += "One or several OPTIONAL libraries listed below are not found. This does not affect on the correct work of SALOME platform.\n\t"
1154 msg += "\n\t".join(nf_opt_libs)
1155 if nf_mand_libs or nf_opt_libs:
1160 #------------------------------------------------------------------#
1162 # EXECUTION STARTS HERE #
1164 #------------------------------------------------------------------#
1166 if __name__ == "__main__":
1168 cur_dir = get_program_path()
1169 # parse command line
1170 [xml_file, target_dir, tmp_dir, is_gui, is_force_src, is_single_dir, pltname] = parse_parameters()
1171 if xml_file: xml_file = os.path.abspath(xml_file)
1172 if target_dir: target_dir = os.path.abspath(target_dir)
1173 if tmp_dir: tmp_dir = os.path.abspath(tmp_dir)
1175 #---- GUI ----------------
1179 if not env.has_key("PATH") :
1181 if not env.has_key("LD_LIBRARY_PATH") :
1182 env["LD_LIBRARY_PATH"] = ""
1184 env["LD_LIBRARY_PATH"] = "./bin/lib:" + ".:" + env["LD_LIBRARY_PATH"]
1185 env["PATH"] = ".:" + env["PATH"]
1187 cmd = "./bin/SALOME_InstallWizard"
1188 if xml_file is not None:
1189 cmd += " --file %s"%xml_file
1190 if pltname is not None:
1191 cmd += " --platform %s"%pltname
1192 if target_dir is not None:
1193 cmd += " --target %s"%target_dir
1194 if tmp_dir is not None:
1195 cmd += " --tmp %s"%tmp_dir
1197 cmd += " --all-from-sources"
1199 cmd += " --single-directory"
1201 sys.exit(os.system(cmd))
1203 #----- TUI ---------------------
1205 # define xml file to be used
1207 # get current Linux platform
1208 plt_name, plt_ver, plt_arch = get_os_release()
1210 for i in plt_name, plt_ver, plt_arch:
1211 if i: data.append(i)
1212 full_plt_name = " ".join(data)
1213 # get all supported platforms
1214 all_platforms = get_supported_platforms(xml_file)
1217 # platform name is specified in the command line
1218 if pltname in all_platforms:
1219 # if specified platform is supported, choose the corresponding XML file for use
1220 xml_file = all_platforms[pltname]
1222 # if specified platform is NOT supported, print warning message
1223 # and prompt user to choose another platform
1224 msg = "Specified platform is not supported: %s" % (pltname)
1226 pltname, xml_file = select_platform(all_platforms)
1229 elif full_plt_name in all_platforms:
1230 # if current platform is supported, choose the corresponding XML file for use
1231 pltname = full_plt_name
1232 xml_file = all_platforms[pltname]
1234 if xml_file and len(all_platforms) == 1:
1235 # XML file is specified and contains only one platform definition
1236 xml_file = all_platforms.values()[0]
1237 pltname = all_platforms.keys()[0]
1239 # current Linux platform is not supported, print warning message
1240 # and prompt user to choose platform from the list
1241 warning("Not supported Linux platform: %s."%" ".join(data))
1242 pltname, xml_file = select_platform(all_platforms)
1246 # current Linux platform is not supported, exit
1248 msg = "Not supported Linux platform: %s."%pltname
1250 msg = "Not supported Linux platform: %s."%" ".join(data)
1251 error_exit(msg, False)
1254 # parse XML file -----------
1255 message("Parsing XML configuration file: %s"%xml_file)
1256 parser = ConfigParser(is_force_src, pltname)
1257 parser.parse(xml_file)
1259 # source directory map
1261 if parser.config.platforms:
1262 bin_dir += "/%s"%"_".join( parser.pltname.split() )
1263 subdir = { __BINARIES__ : "BINARIES" + bin_dir,
1264 __BUILDSRC__ : "SOURCES",
1265 __PREINSTALL__ : ""}
1267 # check scripts directory -----------
1268 scripts_dir = "%s/%s"%(cur_dir, "config_files")
1269 check_dir(scripts_dir)
1271 # check products archives directories -----------
1272 has_bin = has_binaries(parser.products)
1273 has_src = has_sources(parser.products)
1274 source_dir = "%s/%s"%(cur_dir, "Products")
1276 if has_src or has_bin:
1277 check_dir(source_dir)
1280 check_dir("%s/%s"%(source_dir,subdir[__BUILDSRC__]))
1283 check_dir("%s/%s"%(source_dir,subdir[__BINARIES__]))
1285 # check/create target dir -----------
1286 if target_dir is None:
1287 target_dir = parser.config.targetdir
1288 target_dir = substituteVars(target_dir)
1290 message("Creating target directory: " + target_dir)
1291 create_dir(target_dir, 0755)
1293 if not os.path.exists(target_dir):
1294 error_exit("Invalid target directory: " + target_dir)
1296 if not os.access(target_dir, os.W_OK) :
1297 error_exit("There is no write permissions for the directory: " + target_dir)
1299 # check/create temporary dir -----------
1301 tmp_dir = parser.config.tmpdir
1304 tmp_dir = substituteVars(tmp_dir)
1305 tmp_dir = get_tmp_dir(tmp_dir)
1307 message("Creating temporary directory: " + tmp_dir)
1308 root_path = create_dir(tmp_dir, 0755)
1310 if not os.path.exists(tmp_dir):
1311 error_exit("Invalid temporary directory: " + tmp_dir)
1313 if not os.access(tmp_dir, os.W_OK) :
1314 error_exit("There is no write permissions for the directory: " + tmp_dir)
1316 # check available disk space -----------
1317 message("Checking available disk space")
1318 check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir, is_force_src)
1320 # change current directory -----------
1321 os.chdir(scripts_dir)
1323 # get dependencies list -----------
1324 list_of_dep = get_dependencies(parser.products)
1325 products_string = " ".join(parser.full_prods_list)
1327 # don't remove sources and tmp files, by default -----------
1328 rm_src_tmp = "FALSE"
1330 # starting -----------
1331 message("Starting ...")
1333 # install products -----------
1334 for product in parser.products:
1335 # remove only prerequisites temporary files
1336 if product.type == __CTX__PREREQUISITE__ or \
1337 (product.type == __CTX__COMPONENT__ and product.whattodo == __BUILDSRC__):
1339 message("... processing %s ..."%product.name)
1340 cmd = '%s/%s %s %s %s/%s %s "%s" %s "%s" %s/%s %s %s/%s' % (
1341 scripts_dir, product.script,
1344 source_dir, subdir[product.whattodo],
1349 source_dir, subdir[__BUILDSRC__],
1351 source_dir, subdir[__BINARIES__]
1353 # install all modules with GUI
1354 if product.woguiinst is not None and product.woguiinst != "":
1356 # use single directory or not
1357 if product.whattodo == __BINARIES__ and product.type == __CTX__COMPONENT__ and is_single_dir:
1359 res = os.system(cmd)
1360 rm_src_tmp = "FALSE"
1363 # pickup environment -----------
1364 message("Creating environment files")
1365 for product in parser.products :
1366 if check_bool(product.pickupEnv):
1367 cmd = '%s/%s pickup_env %s %s/%s %s "%s" %s "%s" %s/%s %s %s/%s' % (
1368 scripts_dir, product.script,
1370 source_dir, subdir[product.whattodo],
1375 source_dir, subdir[__BUILDSRC__],
1377 source_dir, subdir[__BINARIES__]
1379 # install all modules with GUI
1380 if product.woguiinst is not None and product.woguiinst != "":
1382 # use single directory or not
1383 if product.whattodo == __BINARIES__ and product.type == __CTX__COMPONENT__ and is_single_dir:
1385 res = os.system(cmd)
1389 if not is_force_src:
1391 # modify *.la files, if --single-directory option was pointed -----------
1392 message("Modifying of *.la files of SALOME modules...")
1393 cmd = '%s/modifyLaFiles.sh modify_la_files %s' % (scripts_dir, target_dir)
1394 res = os.system(cmd)
1396 # check that all required libraries are in system
1397 message("Check existence of Fortran and other required libraries...")
1398 cmd = '%s/checkFortran.sh find_libraries %s > %s/not_found_libs.txt' % (scripts_dir, target_dir, tmp_dir)
1400 check_not_found_libs("%s/not_found_libs.txt" % (tmp_dir), parser.config.optlibs)
1402 # clean temporary directory -----------
1403 message("Cleaning temporary directory")
1406 # finishing -----------
1407 message("Finished!")