From 3d92837312eab29e3efb0b54dc4bbdfdbda4d7b0 Mon Sep 17 00:00:00 2001 From: prascle Date: Mon, 4 Sep 2006 06:01:15 +0000 Subject: [PATCH] PR: SALOME application (virtual links) installation based on an xml descriptor. --- bin/Makefile.am | 2 + bin/appli_clean.sh | 2 +- bin/appli_gen.py | 246 +++++++++++++++++++++++++++++++++++++ bin/config_appli.xml | 20 +++ bin/virtual_salome.py | 110 +++++++++++------ doc/SALOME_Application.txt | 51 ++++---- 6 files changed, 372 insertions(+), 59 deletions(-) create mode 100644 bin/appli_gen.py create mode 100644 bin/config_appli.xml diff --git a/bin/Makefile.am b/bin/Makefile.am index 2120709f6..f50343d19 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -51,7 +51,9 @@ dist_salomescript_SCRIPTS=\ createAppli.sh \ appli_install.sh \ appli_clean.sh \ + appli_gen.py \ virtual_salome.py \ + config_appli.xml \ launchConfigureParser.py \ showNS.py \ addToKillList.py \ diff --git a/bin/appli_clean.sh b/bin/appli_clean.sh index c8cadf964..0046e946c 100644 --- a/bin/appli_clean.sh +++ b/bin/appli_clean.sh @@ -20,4 +20,4 @@ # #clean appli -rm -rf bin lib share doc envd setAppliPath.sh searchFreePort.sh runAppli runConsole runSession env.d +rm -rf bin lib share doc env.d envd setAppliPath.sh searchFreePort.sh runAppli runConsole runSession runRemote.sh runTests SalomeApp.xml *.pyc *~ .bashrc diff --git a/bin/appli_gen.py b/bin/appli_gen.py new file mode 100644 index 000000000..977b3f5c1 --- /dev/null +++ b/bin/appli_gen.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python +"""Create a virtual Salome installation + +""" +usage="""usage: %prog [options] +Typical use is: + python appli_gen.py +Use with options: + python appli_gen.py --prefix= --config= +""" + +import os, glob, string, sys, re +import xml.sax +import optparse +import virtual_salome + +# --- names of tags in XML configuration file +appli_tag = "application" +prereq_tag = "prerequisites" +modules_tag = "modules" +module_tag = "module" +samples_tag = "samples" + +# --- names of attributes in XML configuration file +nam_att = "name" +path_att = "path" +gui_att = "gui" + +# ----------------------------------------------------------------------------- + +# --- xml reader for SALOME application configuration file + +class xml_parser: + def __init__(self, fileName ): + print "Configure parser: processing %s ..." % fileName + self.space = [] + self.config = {} + self.config["modules"] = [] + self.config["guimodules"] = [] + parser = xml.sax.make_parser() + parser.setContentHandler(self) + parser.parse(fileName) + pass + + def boolValue( self, str ): + if str in ("yes", "y", "1"): + return 1 + elif str in ("no", "n", "0"): + return 0 + else: + return str + pass + + def startElement(self, name, attrs): + self.space.append(name) + self.current = None + # --- if we are analyzing "prerequisites" element then store its "path" attribute + if self.space == [appli_tag, prereq_tag] and path_att in attrs.getNames(): + self.config["prereq_path"] = attrs.getValue( path_att ) + pass + # --- if we are analyzing "samples" element then store its "path" attribute + if self.space == [appli_tag, samples_tag] and path_att in attrs.getNames(): + self.config["samples_path"] = attrs.getValue( path_att ) + pass + # --- if we are analyzing "module" element then store its "name" and "path" attributes + elif self.space == [appli_tag,modules_tag,module_tag] and \ + nam_att in attrs.getNames() and \ + path_att in attrs.getNames(): + nam = attrs.getValue( nam_att ) + path = attrs.getValue( path_att ) + gui = 1 + if gui_att in attrs.getNames(): + gui = self.boolValue(attrs.getValue( gui_att )) + pass + self.config["modules"].append(nam) + self.config[nam]=path + if gui: + self.config["guimodules"].append(nam) + pass + pass + pass + + def endElement(self, name): + p = self.space.pop() + self.current = None + pass + + def characters(self, content): + pass + + def processingInstruction(self, target, data): + pass + + def setDocumentLocator(self, locator): + pass + + def startDocument(self): + self.read = None + pass + + def endDocument(self): + self.read = None + pass + +# ----------------------------------------------------------------------------- + +class params: + pass + +# ----------------------------------------------------------------------------- + +def install(prefix,config_file): + home_dir=os.path.abspath(os.path.expanduser(prefix)) + filename=os.path.abspath(os.path.expanduser(config_file)) + _config={} + try: + p = xml_parser(filename) + _config = p.config + except xml.sax.SAXParseException, inst: + print inst.getMessage() + print "Configure parser: parse error in configuration file %s" % filename + pass + except xml.sax.SAXException, inst: + print inst.args + print "Configure parser: error in configuration file %s" % filename + pass + except: + print "Configure parser: Error : can not read configuration file %s, check existence and rights" % filename + pass + + for cle in _config.keys(): + print cle, _config[cle] + pass + + for module in _config["modules"]: + print "--- add module ", module, _config[module] + options = params() + options.verbose=0 + options.clear=0 + options.prefix=home_dir + options.module=_config[module] + virtual_salome.link_module(options) + pass + + appliskel_dir=os.path.join(home_dir,'bin','salome','appliskel') + + for fn in ('envd', + 'setAppliPath.sh', + 'searchFreePort.sh', + 'runRemote.sh', + 'runAppli', + 'runConsole', + 'runSession', + 'runTests', + '.bashrc', + ): + virtual_salome.symlink(os.path.join(appliskel_dir, fn),os.path.join(home_dir, fn)) + pass + + if filename != os.path.join(home_dir,"config_appli.xml"): + command = "cp -p " + filename + ' ' + os.path.join(home_dir,"config_appli.xml") + os.system(command) + pass + + virtual_salome.mkdir(os.path.join(home_dir,'env.d')) + if os.path.isfile(_config["prereq_path"]): + command='cp -p ' + _config["prereq_path"] + ' ' + os.path.join(home_dir,'env.d','envProducts.sh') + os.system(command) + pass + else: + print "WARNING: prerequisite file does not exist" + pass + + + f =open(os.path.join(home_dir,'env.d','configSalome.sh'),'w') + for module in _config["modules"]: + command='export '+ module + '_ROOT_DIR=' + _config[module] +'\n' + f.write(command) + pass + if _config.has_key("samples_path"): + command='export DATA_DIR=' + _config["samples_path"] +'\n' + f.write(command) + pass + f.close() + + + f =open(os.path.join(home_dir,'env.d','configGUI.sh'),'w') + command = 'export SalomeAppConfig=' + home_dir +'\n' + f.write(command) + command = 'export SUITRoot=' + os.path.join(home_dir,'share','salome') +'\n' + f.write(command) + f.write('export DISABLE_FPE=1\n') + f.close() + + + f =open(os.path.join(home_dir,'SalomeApp.xml'),'w') + command=""" +
+ + + + + + + + + + + + ') + command=""" + + + +
+
+""" + f.write(command) + f.close() + +def main(): + parser = optparse.OptionParser(usage=usage) + + parser.add_option('--prefix', dest="prefix", default='.', + help="Installation directory (default .)") + + parser.add_option('--config', dest="config", default='config_appli.xml', + help="XML configuration file (default config_appli.xml)") + + options, args = parser.parse_args() + install(prefix=options.prefix,config_file=options.config) + pass + +# ----------------------------------------------------------------------------- + +if __name__ == '__main__': + main() + pass diff --git a/bin/config_appli.xml b/bin/config_appli.xml new file mode 100644 index 000000000..bd7799353 --- /dev/null +++ b/bin/config_appli.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/bin/virtual_salome.py b/bin/virtual_salome.py index 8040c21c9..e6458665e 100644 --- a/bin/virtual_salome.py +++ b/bin/virtual_salome.py @@ -30,6 +30,8 @@ install module KERNEL in the current directory import sys, os, optparse, shutil,glob,fnmatch py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) +# ----------------------------------------------------------------------------- + def mkdir(path): """Create a directory and all the intermediate directories if path does not exist""" if not os.path.exists(path): @@ -41,6 +43,8 @@ def mkdir(path): pass pass +# ----------------------------------------------------------------------------- + def symlink(src, dest): """Create a link if it does not exist""" if not os.path.exists(dest): @@ -53,6 +57,8 @@ def symlink(src, dest): pass pass +# ----------------------------------------------------------------------------- + def rmtree(dir): """Remove (recursive) a directory if it exists""" if os.path.exists(dir): @@ -65,32 +71,18 @@ def rmtree(dir): pass pass +# ----------------------------------------------------------------------------- + def get_lib_dir(): """Get libraries directory according to the Linux platform being used""" - if os.path.exists("/usr/lib64/libc.so"): - return "lib64" + #ne marche pas sur Calibre 4.0 + #if os.path.exists("/usr/lib64/libc.so"): + # return "lib64" return "lib" -def main(): - usage="""usage: %prog [options] -Typical use is: - python virtual_salome.py -v --prefix="." --module=/local/chris/SALOME2/RELEASES/Install/KERNEL_V3_1_0b1 -""" - parser = optparse.OptionParser(usage=usage) - - parser.add_option('-v', '--verbose', action='count', dest='verbose', - default=0, help="Increase verbosity") - - parser.add_option('--prefix', dest="prefix", default='.', - help="The base directory to install to (default .)") - - parser.add_option('--module', dest="module", - help="The module directory to install in (mandatory)") - - parser.add_option('--clear', dest='clear', action='store_true', - help="Clear out the install and start from scratch") +# ----------------------------------------------------------------------------- - options, args = parser.parse_args() +def link_module(options): global verbose if not options.module: @@ -104,7 +96,6 @@ Typical use is: home_dir = os.path.expanduser(options.prefix) - #module_dir="/local/chris/SALOME2/RELEASES/Install/KERNEL_V3_1_0b1" module_bin_dir=os.path.join(module_dir,'bin','salome') module_lib_dir=os.path.join(module_dir,get_lib_dir(),'salome') module_lib_py_dir=os.path.join(module_dir,get_lib_dir(),py_version,'site-packages','salome') @@ -114,6 +105,7 @@ Typical use is: module_doc_gui_dir=os.path.join(module_dir,'doc','salome','gui') module_doc_tui_dir=os.path.join(module_dir,'doc','salome','tui') module_doc_dir=os.path.join(module_dir,'doc','salome') + module_sharedoc_dir=os.path.join(module_dir,'share','doc','salome') if not os.path.exists(module_lib_py_dir): print "Python directory %s does not exist" % module_lib_py_dir @@ -128,39 +120,49 @@ Typical use is: doc_gui_dir=os.path.join(home_dir,'doc','salome','gui') doc_tui_dir=os.path.join(home_dir,'doc','salome','tui') doc_dir=os.path.join(home_dir,'doc','salome') + sharedoc_dir=os.path.join(home_dir,'share','doc','salome') verbose = options.verbose if options.clear: rmtree(bin_dir) rmtree(lib_dir) + rmtree(lib_py_dir) rmtree(share_dir) rmtree(doc_dir) + rmtree(sharedoc_dir) pass #directory bin/salome : create it and link content - mkdir(bin_dir) - for fn in os.listdir(module_bin_dir): - # if os.path.splitext(fn)[1] not in (".pyc",".pyo"): #Compiled python are excluded - symlink(os.path.join(module_bin_dir, fn), os.path.join(bin_dir, fn)) + if os.path.exists(module_bin_dir): + mkdir(bin_dir) + for fn in os.listdir(module_bin_dir): + symlink(os.path.join(module_bin_dir, fn), os.path.join(bin_dir, fn)) + pass pass + else: + print module_bin_dir, " doesn't exist" + pass #directory lib/salome : create it and link content - mkdir(lib_dir) - for fn in os.listdir(module_lib_dir): - symlink(os.path.join(module_lib_dir, fn), os.path.join(lib_dir, fn)) - + if os.path.exists(module_lib_dir): + mkdir(lib_dir) + for fn in os.listdir(module_lib_dir): + symlink(os.path.join(module_lib_dir, fn), os.path.join(lib_dir, fn)) + pass + pass + else: + print module_lib_dir, " doesn't exist" + pass + #directory lib/py_version/site-packages/salome : create it and link content mkdir(lib_py_shared_dir) for fn in os.listdir(module_lib_py_dir): - # if os.path.splitext(fn)[1] not in (".pyc",".pyo"): #Compiled python are excluded - if os.path.split(fn)[1] != "shared_modules": - symlink(os.path.join(module_lib_py_dir, fn), os.path.join(lib_py_dir, fn)) - pass - pass + if fn == "shared_modules": continue + symlink(os.path.join(module_lib_py_dir, fn), os.path.join(lib_py_dir, fn)) + pass if os.path.exists(module_lib_py_shared_dir): for fn in os.listdir(module_lib_py_shared_dir): - # if os.path.splitext(fn)[1] not in (".pyc",".pyo"): #Compiled python are excluded symlink(os.path.join(module_lib_py_shared_dir, fn), os.path.join(lib_py_shared_dir, fn)) pass pass @@ -168,6 +170,15 @@ Typical use is: print module_lib_py_shared_dir, " doesn't exist" pass + #directory share/doc/salome (KERNEL doc) : create it and link content + if os.path.exists(module_sharedoc_dir): + mkdir(sharedoc_dir) + for fn in os.listdir(module_sharedoc_dir): + symlink(os.path.join(module_sharedoc_dir, fn), os.path.join(sharedoc_dir, fn)) + pass + pass + pass + #directory share/salome/resources : create it and link content mkdir(share_dir) @@ -199,7 +210,34 @@ Typical use is: symlink(os.path.join(module_doc_tui_dir, fn), os.path.join(doc_tui_dir, fn)) pass pass + +# ----------------------------------------------------------------------------- + +def main(): + usage="""usage: %prog [options] +Typical use is: + python virtual_salome.py -v --prefix="." --module=/local/chris/SALOME2/RELEASES/Install/KERNEL_V3_1_0b1 +""" + parser = optparse.OptionParser(usage=usage) + + parser.add_option('-v', '--verbose', action='count', dest='verbose', + default=0, help="Increase verbosity") + + parser.add_option('--prefix', dest="prefix", default='.', + help="The base directory to install to (default .)") + + parser.add_option('--module', dest="module", + help="The module directory to install in (mandatory)") + + parser.add_option('--clear', dest='clear', action='store_true', + help="Clear out the install and start from scratch") + + options, args = parser.parse_args() + link_module(options) + pass +# ----------------------------------------------------------------------------- + if __name__ == '__main__': main() pass diff --git a/doc/SALOME_Application.txt b/doc/SALOME_Application.txt index ab6c52b96..0abcaed1e 100644 --- a/doc/SALOME_Application.txt +++ b/doc/SALOME_Application.txt @@ -74,19 +74,29 @@ configure his own application. These files are described after, the list is: - CatalogResources.xml - SalomeApp.xml -Second way - one single virtual install directory -''''''''''''''''''''''''''''''''''''''''''''''''' - -The user must create an application directory in which he copies -appli_install.sh, appli_clean.sh and virtual_salome.py, -from ${KERNEL_ROOT_DIR}/bin/salome. - -appli_install.sh needs to be edited, to define a list of modules with their -install paths. -Then, the script appli_install.sh creates a virtual installation of SALOME -in the application directory (bin, lib, doc, share...), with, -for each file (executable, script, data,library, resources...), -symbolic links to the actual file. +Second and easiest way - one single virtual install directory +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +The user must create a SALOME application configuration file by modifying a +copy of ${KERNEL_ROOT_DIR}/bin/salome/config_appli.xml. +The file describes the list of SALOME modules used in the application, with +their respective installation path. The configuration file also defines the +path of an existing script which sets the SALOME prerequisites, +and optionnaly, the path of samples directory (SAMPLES_SRC). +The following command:: + + python /bin/salome/appli_gen.py --prefix= --config= + +creates a virtual installation of SALOME in the application directory ${APPLI} +(bin, lib, doc, share...), with, for each file (executable, script, data, +library, resources...), symbolic links to the actual file. + +Providing an existing an existing script for SALOME prerequisites (the same one +used for modules compilation, or given with the modules installation), the +installation works without further modification for a single computer (unless +some modules needs a special environment not defined in the above script). +For a distributed application (several computers), one must copy and adapt +CatalogResources.xml from ${KERNEL_ROOT_DIR}/bin/salome/appliskel (see below). General rules ------------- @@ -108,15 +118,12 @@ script is used by run scripts. env.d scripts ~~~~~~~~~~~~~ +With the first way of installation, each user **must define** his own +configuration for these scripts, following the above rules. +With the virtual installation (second way, above), env.d +scripts are built automatically. -Each user **must define** his own configuration for these scripts, following -the above rules. With the virtual installation (second way, above), env.d -scripts are built by appli_install.sh (given it's parameters). Otherwise, the -scripts must be manually defined. - - - **The following is only an example proposed by createAppli.sh, - not working as it is**. + **The following is only an example proposed by createAppli.sh, (first way of installation) not working as it is**. atFirst.sh Sets the computer configuration not directly related to SALOME, @@ -184,7 +191,7 @@ SalomeApp.xml CatalogRessources.xml - This files describes all the computer the application can use. The given + This files describes all the computers the application can use. The given example is minimal and suppose ${APPLI} is the same relative path to ${HOME}, on all the computers. A different directory can be set on a particular computer with a line:: -- 2.39.2