2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
5 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
27 import sys,os,shutil,glob,socket
29 from salome_utils import getUserName
32 appli_local=os.path.realpath(os.path.dirname(__file__))
33 APPLI=getAppliPath.relpath(appli_local,os.path.realpath(os.getenv('HOME')))
35 usage="""usage: %prog [options]
37 python update_catalogs.py
39 You need to have a well installed SALOME application with a CatalogResources.base.xml file.
40 This file is used (parsed) to collect all module catalogs from distant resources and
41 put them in the directory "remote_catalogs" with sub-directories with same name as the distant resource.
42 Distant resources are all the resources except the main SALOME application.
43 Module catalogs from distant resources are copied by the remote protocol declared in the catalog (rcp or rsh)
44 except for the user resources on the local machine (local copy: cp).
46 In a second time, this procedure generates a ready to use CatalogResources.xml with all available components
51 # cElementTree from Python 2.5+
52 import xml.etree.cElementTree as etree_
55 import xml.etree.ElementTree as etree_
58 import cElementTree as etree_
61 # normal ElementTree install
62 import elementtree.ElementTree as etree_
66 class ParseError(Exception):
69 catalog_file_base=os.path.join(appli_local,"CatalogResources.base.xml")
70 catalog_file=os.path.join(appli_local,"CatalogResources.xml")
72 cata_dir=os.path.join(appli_local,"remote_catalogs")
73 cata_dir_bak=os.path.join(appli_local,"remote_catalogs.bak")
76 if sys.platform == "win32":SEP=";"
79 return socket.gethostname().split('.')[0]
82 """Define a SALOME component
83 - name : component name
84 - moduleName : module name
86 def __init__(self,name,moduleName):
88 self.moduleName=moduleName
91 """Define a SALOME resource
92 - components : the list of available components of the resource
94 def __init__(self,node):
97 self.resource_dir=None
101 self.attrs=self.node.attrib
102 #remove all children (components and modules)
103 for child in list(self.node):
104 self.node.remove(child)
107 for compo in self.components:
108 child=etree_.Element("component",name=compo.name,moduleName=compo.moduleName)
110 self.node.append(child)
113 protocol= self.node.get("protocol")
114 if protocol and protocol[0]=='s':return "scp"
118 userName= self.node.get("userName")
120 userName=getUserName()
124 hostname= self.node.get("hostname")
128 name= self.node.get("name")
130 return self.get_host()
132 def get_appliPath(self):
133 appliPath= self.node.get("appliPath")
134 if appliPath is None:
138 def get_catalogs(self):
139 """Get module catalogs file from the resource and copy them locally in remote_catalogs/<resource name>"""
140 hostname=self.get_host()
141 appliPath= self.get_appliPath()
142 userName = self.get_user()
145 resource_dir=os.path.join(cata_dir,self.get_name())
147 if hostname == "localhost" or hostname == get_hostname() and userName == getUserName():
148 #local machine, use cp
149 if appliPath[0]!='/':
151 appliPath=os.path.join(os.getenv("HOME"),appliPath)
153 if appliPath == appli_local:
155 os.mkdir(resource_dir)
156 cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
157 cmd="cp %s %s" % (cata_path,resource_dir)
160 cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
161 cmd="cp %s %s" % (cata_path,resource_dir)
165 #remote machine, use rcopy
166 os.mkdir(resource_dir)
167 cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
169 cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
172 cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
174 cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
178 schema_cata=os.path.join(resource_dir,"*SchemaCatalog.xml")
179 os.system("rm %s"% schema_cata)
181 self.resource_dir=os.path.abspath(resource_dir)
183 def get_components(self):
184 """Retrieve all components declared in module catalogs of the resource"""
185 appliPath= self.get_appliPath()
186 userName = self.get_user()
187 hostname=self.get_host()
188 resource_dir=os.path.join(cata_dir,self.get_name())
189 catalogs_list=glob.glob(os.path.join(resource_dir,"*Catalog.xml"))
191 if hostname == "localhost" or hostname == get_hostname() and userName == getUserName():
193 if appliPath[0]!='/':
194 appliPath=os.path.join(os.getenv("HOME"),appliPath)
195 if appliPath == appli_local:
196 #main local resource: get catalogs in share/salome/resources
197 catalogs_list=glob.glob(os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml"))
198 catalogs_list=catalogs_list + glob.glob(os.path.join(appliPath,"share","salome","resources","*Catalog.xml"))
200 for cata in catalogs_list:
201 moduleName= os.path.basename(cata)[:-11]
202 #Parse module catalog
203 doc = etree_.parse(cata)
204 rootNode = doc.getroot()
205 for componentName in rootNode.findall("component-list/component/component-name"):
206 self.components.append(Component(componentName.text,moduleName))
210 parser = optparse.OptionParser(usage=usage)
212 options, args = parser.parse_args()
214 if not os.path.exists(catalog_file_base):
215 print "ERROR: the base catalog file %s is mandatory" % catalog_file_base
218 #Parse CatalogResource.xml
219 doc = etree_.parse(catalog_file_base)
221 rootNode = doc.getroot()
222 if rootNode.tag != "resources":
223 raise ParseError("First level tag must be resources not %s" % rootNode.tag)
228 for child in rootNode:
229 if child.tag != "machine":
230 raise ParseError("Second level tag must be machine not %s" % child.tag)
231 resources.append(Resource(child))
233 # Remove remote_catalogs directory and create a new empty one
234 if os.path.exists(cata_dir):
235 if os.path.exists(cata_dir_bak):
236 shutil.rmtree(cata_dir_bak)
237 os.rename(cata_dir,cata_dir_bak)
241 #Get catalogs from remote resources and copy them in remote_catalogs
242 for mach in resources:
245 #Get the list of SALOME components that are defined in catalogs
246 for mach in resources:
247 mach.get_components()
249 #Update the resource catalog dom object for further dump
250 for mach in resources:
253 #dump new CatalogResources.xml
254 f=open(catalog_file,'w')
255 f.write('<?xml version="1.0" ?>\n')
259 print "%s updated" % catalog_file
261 #update configRemote.sh in env.d directory (environment variable SALOME_CATALOGS_PATH)
263 for mach in resources:
264 if mach.resource_dir:
265 path.append(mach.resource_dir)
267 f=open(os.path.join(appli_local,"env.d","configRemote.sh"),'w')
268 f.write("export SALOME_CATALOGS_PATH=%s\n" % SEP.join(path))
272 if __name__ == '__main__':