2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2013 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.
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
31 appli_local=os.path.realpath(os.path.dirname(__file__))
32 APPLI=getAppliPath.relpath(appli_local,os.path.realpath(os.getenv('HOME')))
34 usage="""usage: %prog [options]
36 python update_catalogs.py
38 You need to have a well installed SALOME application with a CatalogResources.base.xml file.
39 This file is used (parsed) to collect all module catalogs from distant resources and
40 put them in the directory "remote_catalogs" with sub-directories with same name as the distant resource.
41 Distant resources are all the resources except the main SALOME application.
42 Module catalogs from distant resources are copied by the remote protocol declared in the catalog (rcp or rsh)
43 except for the user resources on the local machine (local copy: cp).
45 In a second time, this procedure generates a ready to use CatalogResources.xml with all available components
50 # cElementTree from Python 2.5+
51 import xml.etree.cElementTree as etree_
54 import xml.etree.ElementTree as etree_
57 import cElementTree as etree_
60 # normal ElementTree install
61 import elementtree.ElementTree as etree_
65 class ParseError(Exception):
68 catalog_file_base=os.path.join(appli_local,"CatalogResources.base.xml")
69 catalog_file=os.path.join(appli_local,"CatalogResources.xml")
71 cata_dir=os.path.join(appli_local,"remote_catalogs")
72 cata_dir_bak=os.path.join(appli_local,"remote_catalogs.bak")
75 if sys.platform == "win32":SEP=";"
78 return socket.gethostname().split('.')[0]
81 """Define a SALOME component
82 - name : component name
83 - moduleName : module name
85 def __init__(self,name,moduleName):
87 self.moduleName=moduleName
90 """Define a SALOME resource
91 - components : the list of available components of the resource
93 def __init__(self,node):
96 self.resource_dir=None
100 self.attrs=self.node.attrib
101 #remove all children (components and modules)
102 for child in list(self.node):
103 self.node.remove(child)
106 for compo in self.components:
107 child=etree_.Element("component",name=compo.name,moduleName=compo.moduleName)
109 self.node.append(child)
112 protocol= self.node.get("protocol")
113 if protocol and protocol[0]=='s':return "scp"
117 userName= self.node.get("userName")
119 userName=os.getenv('USER')
123 hostname= self.node.get("hostname")
127 name= self.node.get("name")
129 return self.get_host()
131 def get_appliPath(self):
132 appliPath= self.node.get("appliPath")
133 if appliPath is None:
137 def get_catalogs(self):
138 """Get module catalogs file from the resource and copy them locally in remote_catalogs/<resource name>"""
139 hostname=self.get_host()
140 appliPath= self.get_appliPath()
141 userName = self.get_user()
144 resource_dir=os.path.join(cata_dir,self.get_name())
146 if hostname == "localhost" or hostname == get_hostname() and userName == os.getenv("USER"):
147 #local machine, use cp
148 if appliPath[0]!='/':
150 appliPath=os.path.join(os.getenv("HOME"),appliPath)
152 if appliPath == appli_local:
154 os.mkdir(resource_dir)
155 cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
156 cmd="cp %s %s" % (cata_path,resource_dir)
159 cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
160 cmd="cp %s %s" % (cata_path,resource_dir)
164 #remote machine, use rcopy
165 os.mkdir(resource_dir)
166 cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
168 cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
171 cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
173 cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
177 schema_cata=os.path.join(resource_dir,"*SchemaCatalog.xml")
178 os.system("rm %s"% schema_cata)
180 self.resource_dir=os.path.abspath(resource_dir)
182 def get_components(self):
183 """Retrieve all components declared in module catalogs of the resource"""
184 appliPath= self.get_appliPath()
185 userName = self.get_user()
186 hostname=self.get_host()
187 resource_dir=os.path.join(cata_dir,self.get_name())
188 catalogs_list=glob.glob(os.path.join(resource_dir,"*Catalog.xml"))
190 if hostname == "localhost" or hostname == get_hostname() and userName == os.getenv("USER"):
192 if appliPath[0]!='/':
193 appliPath=os.path.join(os.getenv("HOME"),appliPath)
194 if appliPath == appli_local:
195 #main local resource: get catalogs in share/salome/resources
196 catalogs_list=glob.glob(os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml"))
197 catalogs_list=catalogs_list + glob.glob(os.path.join(appliPath,"share","salome","resources","*Catalog.xml"))
199 for cata in catalogs_list:
200 moduleName= os.path.basename(cata)[:-11]
201 #Parse module catalog
202 doc = etree_.parse(cata)
203 rootNode = doc.getroot()
204 for componentName in rootNode.findall("component-list/component/component-name"):
205 self.components.append(Component(componentName.text,moduleName))
209 parser = optparse.OptionParser(usage=usage)
211 options, args = parser.parse_args()
213 if not os.path.exists(catalog_file_base):
214 print "ERROR: the base catalog file %s is mandatory" % catalog_file_base
217 #Parse CatalogResource.xml
218 doc = etree_.parse(catalog_file_base)
220 rootNode = doc.getroot()
221 if rootNode.tag != "resources":
222 raise ParseError("First level tag must be resources not %s" % rootNode.tag)
227 for child in rootNode:
228 if child.tag != "machine":
229 raise ParseError("Second level tag must be machine not %s" % child.tag)
230 resources.append(Resource(child))
232 # Remove remote_catalogs directory and create a new empty one
233 if os.path.exists(cata_dir):
234 if os.path.exists(cata_dir_bak):
235 shutil.rmtree(cata_dir_bak)
236 os.rename(cata_dir,cata_dir_bak)
240 #Get catalogs from remote resources and copy them in remote_catalogs
241 for mach in resources:
244 #Get the list of SALOME components that are defined in catalogs
245 for mach in resources:
246 mach.get_components()
248 #Update the resource catalog dom object for further dump
249 for mach in resources:
252 #dump new CatalogResources.xml
253 f=open(catalog_file,'w')
254 f.write('<?xml version="1.0" ?>\n')
258 print "%s updated" % catalog_file
260 #update configRemote.sh in env.d directory (environment variable SALOME_CATALOGS_PATH)
262 for mach in resources:
263 if mach.resource_dir:
264 path.append(mach.resource_dir)
266 f=open(os.path.join(appli_local,"env.d","configRemote.sh"),'w')
267 f.write("export SALOME_CATALOGS_PATH=%s\n" % SEP.join(path))
271 if __name__ == '__main__':