Back to index

salome-kernel  6.5.0
update_catalogs.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #  -*- coding: utf-8 -*-
00003 # Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00004 #
00005 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00006 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00007 #
00008 # This library is free software; you can redistribute it and/or
00009 # modify it under the terms of the GNU Lesser General Public
00010 # License as published by the Free Software Foundation; either
00011 # version 2.1 of the License.
00012 #
00013 # This library is distributed in the hope that it will be useful,
00014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 # Lesser General Public License for more details.
00017 #
00018 # You should have received a copy of the GNU Lesser General Public
00019 # License along with this library; if not, write to the Free Software
00020 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00021 #
00022 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00023 #
00024 
00025 """
00026 """
00027 import sys,os,shutil,glob,socket
00028 import optparse
00029 
00030 import getAppliPath
00031 appli_local=os.path.realpath(os.path.dirname(__file__))
00032 APPLI=getAppliPath.relpath(appli_local,os.path.realpath(os.getenv('HOME')))
00033 
00034 usage="""usage: %prog [options]
00035 Typical use is:
00036   python update_catalogs.py
00037 
00038 You need to have a well installed SALOME application with a CatalogResources.base.xml file.
00039 This file is used (parsed) to collect all module catalogs from distant resources and
00040 put them in the directory "remote_catalogs" with sub-directories with same name as the distant resource.
00041 Distant resources are all the resources except the main SALOME application.
00042 Module catalogs from distant resources are copied by the remote protocol declared in the catalog (rcp or rsh)
00043 except for the user resources on the local machine (local copy: cp).
00044 
00045 In a second time, this procedure generates a ready to use CatalogResources.xml with all available components
00046 for each resource.
00047 """
00048 
00049 try:
00050   # cElementTree from Python 2.5+
00051   import xml.etree.cElementTree as etree_
00052 except ImportError:
00053   try:
00054     import xml.etree.ElementTree as etree_
00055   except ImportError:
00056     try:
00057       import cElementTree as etree_
00058     except ImportError:
00059       try:
00060         # normal ElementTree install
00061         import elementtree.ElementTree as etree_
00062       except ImportError:
00063         raise
00064 
00065 class ParseError(Exception):
00066   pass
00067 
00068 catalog_file_base=os.path.join(appli_local,"CatalogResources.base.xml")
00069 catalog_file=os.path.join(appli_local,"CatalogResources.xml")
00070 
00071 cata_dir=os.path.join(appli_local,"remote_catalogs")
00072 cata_dir_bak=os.path.join(appli_local,"remote_catalogs.bak")
00073 
00074 SEP=":"
00075 if sys.platform == "win32":SEP=";"
00076 
00077 def get_hostname():
00078   return socket.gethostname().split('.')[0]
00079 
00080 class Component:
00081   """Define a SALOME component
00082       - name : component name
00083       - moduleName : module name
00084   """
00085   def __init__(self,name,moduleName):
00086     self.name=name
00087     self.moduleName=moduleName
00088 
00089 class Resource:
00090   """Define a SALOME resource
00091      - components : the list of available components of the resource
00092   """
00093   def __init__(self,node):
00094     self.node=node
00095     self.components=[]
00096     self.resource_dir=None
00097     self.build()
00098 
00099   def build(self):
00100     self.attrs=self.node.attrib
00101     #remove all children (components and modules)
00102     for child in list(self.node):
00103       self.node.remove(child)
00104 
00105   def update(self):
00106     for compo in self.components:
00107       child=etree_.Element("component",name=compo.name,moduleName=compo.moduleName)
00108       child.tail="\n"
00109       self.node.append(child)
00110 
00111   def get_rcp(self):
00112     protocol= self.node.get("protocol")
00113     if protocol and protocol[0]=='s':return "scp"
00114     else:return "rcp"
00115 
00116   def get_user(self):
00117     userName= self.node.get("userName")
00118     if not userName:
00119       userName=os.getenv('USER')
00120     return userName
00121 
00122   def get_host(self):
00123     hostname= self.node.get("hostname")
00124     return hostname
00125 
00126   def get_name(self):
00127     name= self.node.get("name")
00128     if name:return name
00129     return self.get_host()
00130 
00131   def get_appliPath(self):
00132     appliPath= self.node.get("appliPath")
00133     if appliPath is None:
00134       appliPath=APPLI
00135     return appliPath
00136 
00137   def get_catalogs(self):
00138     """Get module catalogs file from the resource and copy them locally in remote_catalogs/<resource name>"""
00139     hostname=self.get_host()
00140     appliPath= self.get_appliPath()
00141     userName = self.get_user()
00142     rcopy=self.get_rcp()
00143 
00144     resource_dir=os.path.join(cata_dir,self.get_name())
00145 
00146     if hostname == "localhost" or hostname == get_hostname() and userName == os.getenv("USER"):
00147       #local machine, use cp
00148       if appliPath[0]!='/':
00149         #relative path
00150         appliPath=os.path.join(os.getenv("HOME"),appliPath)
00151 
00152       if appliPath == appli_local:
00153         return
00154       os.mkdir(resource_dir)
00155       cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
00156       cmd="cp %s %s" % (cata_path,resource_dir)
00157       print cmd
00158       os.system(cmd)
00159       cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
00160       cmd="cp %s %s" % (cata_path,resource_dir)
00161       print cmd
00162       os.system(cmd)
00163     else:
00164       #remote machine, use rcopy
00165       os.mkdir(resource_dir)
00166       cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
00167       cmd="%s %s@%s:%s %s"
00168       cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
00169       print cmd
00170       os.system(cmd)
00171       cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
00172       cmd="%s %s@%s:%s %s"
00173       cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
00174       print cmd
00175       os.system(cmd)
00176 
00177     schema_cata=os.path.join(resource_dir,"*SchemaCatalog.xml")
00178     os.system("rm %s"% schema_cata)
00179 
00180     self.resource_dir=os.path.abspath(resource_dir)
00181 
00182   def get_components(self):
00183     """Retrieve all components declared in module catalogs of the resource"""
00184     appliPath= self.get_appliPath()
00185     userName = self.get_user()
00186     hostname=self.get_host()
00187     resource_dir=os.path.join(cata_dir,self.get_name())
00188     catalogs_list=glob.glob(os.path.join(resource_dir,"*Catalog.xml"))
00189 
00190     if hostname == "localhost" or hostname == get_hostname() and userName == os.getenv("USER"):
00191       #user local resource
00192       if appliPath[0]!='/':
00193         appliPath=os.path.join(os.getenv("HOME"),appliPath)
00194       if appliPath == appli_local:
00195         #main local resource: get catalogs in share/salome/resources
00196         catalogs_list=glob.glob(os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml"))
00197         catalogs_list=catalogs_list + glob.glob(os.path.join(appliPath,"share","salome","resources","*Catalog.xml"))
00198 
00199     for cata in catalogs_list:
00200       moduleName= os.path.basename(cata)[:-11]
00201       #Parse module catalog
00202       doc = etree_.parse(cata)
00203       rootNode = doc.getroot()
00204       for componentName in rootNode.findall("component-list/component/component-name"):
00205         self.components.append(Component(componentName.text,moduleName))
00206 
00207 
00208 def main():
00209   parser = optparse.OptionParser(usage=usage)
00210 
00211   options, args = parser.parse_args()
00212 
00213   if not os.path.exists(catalog_file_base):
00214     print "ERROR: the base catalog file %s is mandatory" % catalog_file_base
00215     sys.exit(1)
00216 
00217   #Parse CatalogResource.xml
00218   doc = etree_.parse(catalog_file_base)
00219 
00220   rootNode = doc.getroot()
00221   if rootNode.tag != "resources":
00222     raise  ParseError("First level tag must be resources not %s" % rootNode.tag)
00223 
00224   resources=[]
00225 
00226   #Extract resources
00227   for child in rootNode:
00228     if child.tag != "machine":
00229       raise  ParseError("Second level tag must be machine not %s" % child.tag)
00230     resources.append(Resource(child))
00231 
00232   # Remove remote_catalogs directory and create a new empty one
00233   if os.path.exists(cata_dir):
00234     if os.path.exists(cata_dir_bak):
00235       shutil.rmtree(cata_dir_bak)
00236     os.rename(cata_dir,cata_dir_bak)
00237 
00238   os.mkdir(cata_dir)
00239 
00240   #Get catalogs from remote resources and copy them in remote_catalogs
00241   for mach in resources:
00242     mach.get_catalogs()
00243 
00244   #Get the list of SALOME components that are defined in catalogs
00245   for mach in resources:
00246     mach.get_components()
00247 
00248   #Update the resource catalog dom object for further dump
00249   for mach in resources:
00250     mach.update()
00251 
00252   #dump new CatalogResources.xml
00253   f=open(catalog_file,'w')
00254   f.write('<?xml version="1.0" ?>\n')
00255   doc.write(f)
00256   f.write('\n')
00257   f.close()
00258   print "%s updated" % catalog_file
00259 
00260   #update configRemote.sh in env.d directory (environment variable SALOME_CATALOGS_PATH)
00261   path=[]
00262   for mach in resources:
00263     if mach.resource_dir:
00264       path.append(mach.resource_dir)
00265 
00266   f=open(os.path.join(appli_local,"env.d","configRemote.sh"),'w')
00267   f.write("export SALOME_CATALOGS_PATH=%s\n" % SEP.join(path))
00268   f.close()
00269 
00270 
00271 if __name__ == '__main__':
00272   main()
00273