2 # -*- coding: utf-8 -*-
5 import sys,os,shutil,glob,socket
9 appli_local=os.path.realpath(os.path.dirname(__file__))
10 APPLI=getAppliPath.relpath(appli_local,os.path.realpath(os.getenv('HOME')))
12 usage="""usage: %prog [options]
14 python update_catalogs.py
16 You need to have a well installed SALOME application with a CatalogResources.base.xml file.
17 This file is used (parsed) to collect all module catalogs from distant resources and
18 put them in the directory "remote_catalogs" with sub-directories with same name as the distant resource.
19 Distant resources are all the resources except the main SALOME application.
20 Module catalogs from distant resources are copied by the remote protocol declared in the catalog (rcp or rsh)
21 except for the user resources on the local machine (local copy: cp).
23 In a second time, this procedure generates a ready to use CatalogResources.xml with all available components
28 # cElementTree from Python 2.5+
29 import xml.etree.cElementTree as etree_
32 import xml.etree.ElementTree as etree_
35 import cElementTree as etree_
38 # normal ElementTree install
39 import elementtree.ElementTree as etree_
43 class ParseError(Exception):
46 catalog_file_base=os.path.join(appli_local,"CatalogResources.base.xml")
47 catalog_file=os.path.join(appli_local,"CatalogResources.xml")
49 cata_dir=os.path.join(appli_local,"remote_catalogs")
50 cata_dir_bak=os.path.join(appli_local,"remote_catalogs.bak")
53 if sys.platform == "win32":SEP=";"
56 return socket.gethostname().split('.')[0]
59 """Define a SALOME component
60 - name : component name
61 - moduleName : module name
63 def __init__(self,name,moduleName):
65 self.moduleName=moduleName
68 """Define a SALOME resource
69 - components : the list of available components of the resource
71 def __init__(self,node):
74 self.resource_dir=None
78 self.attrs=self.node.attrib
79 #remove all children (components and modules)
80 for child in list(self.node):
81 self.node.remove(child)
84 for compo in self.components:
85 child=etree_.Element("component",name=compo.name,moduleName=compo.moduleName)
87 self.node.append(child)
90 protocol= self.node.get("protocol")
91 if protocol and protocol[0]=='s':return "scp"
95 userName= self.node.get("userName")
97 userName=os.getenv('USER')
101 hostname= self.node.get("hostname")
105 name= self.node.get("name")
107 return self.get_host()
109 def get_appliPath(self):
110 appliPath= self.node.get("appliPath")
111 if appliPath is None:
115 def get_catalogs(self):
116 """Get module catalogs file from the resource and copy them locally in remote_catalogs/<resource name>"""
117 hostname=self.get_host()
118 appliPath= self.get_appliPath()
119 userName = self.get_user()
122 resource_dir=os.path.join(cata_dir,self.get_name())
124 if hostname == "localhost" or hostname == get_hostname() and userName == os.getenv("USER"):
125 #local machine, use cp
126 if appliPath[0]!='/':
128 appliPath=os.path.join(os.getenv("HOME"),appliPath)
130 if appliPath == appli_local:
132 os.mkdir(resource_dir)
133 cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
134 cmd="cp %s %s" % (cata_path,resource_dir)
137 cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
138 cmd="cp %s %s" % (cata_path,resource_dir)
142 #remote machine, use rcopy
143 os.mkdir(resource_dir)
144 cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
146 cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
149 cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
151 cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
155 schema_cata=os.path.join(resource_dir,"*SchemaCatalog.xml")
156 os.system("rm %s"% schema_cata)
158 self.resource_dir=os.path.abspath(resource_dir)
160 def get_components(self):
161 """Retrieve all components declared in module catalogs of the resource"""
162 appliPath= self.get_appliPath()
163 userName = self.get_user()
164 hostname=self.get_host()
165 resource_dir=os.path.join(cata_dir,self.get_name())
166 catalogs_list=glob.glob(os.path.join(resource_dir,"*Catalog.xml"))
168 if hostname == "localhost" or hostname == get_hostname() and userName == os.getenv("USER"):
170 if appliPath[0]!='/':
171 appliPath=os.path.join(os.getenv("HOME"),appliPath)
172 if appliPath == appli_local:
173 #main local resource: get catalogs in share/salome/resources
174 catalogs_list=glob.glob(os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml"))
175 catalogs_list=catalogs_list + glob.glob(os.path.join(appliPath,"share","salome","resources","*Catalog.xml"))
177 for cata in catalogs_list:
178 moduleName= os.path.basename(cata)[:-11]
179 #Parse module catalog
180 doc = etree_.parse(cata)
181 rootNode = doc.getroot()
182 for componentName in rootNode.findall("component-list/component/component-name"):
183 self.components.append(Component(componentName.text,moduleName))
187 parser = optparse.OptionParser(usage=usage)
189 options, args = parser.parse_args()
191 if not os.path.exists(catalog_file_base):
192 print "ERROR: the base catalog file %s is mandatory" % catalog_file_base
195 #Parse CatalogResource.xml
196 doc = etree_.parse(catalog_file_base)
198 rootNode = doc.getroot()
199 if rootNode.tag != "resources":
200 raise ParseError("First level tag must be resources not %s" % rootNode.tag)
205 for child in rootNode:
206 if child.tag != "machine":
207 raise ParseError("Second level tag must be machine not %s" % child.tag)
208 resources.append(Resource(child))
210 # Remove remote_catalogs directory and create a new empty one
211 if os.path.exists(cata_dir):
212 if os.path.exists(cata_dir_bak):
213 shutil.rmtree(cata_dir_bak)
214 os.rename(cata_dir,cata_dir_bak)
218 #Get catalogs from remote resources and copy them in remote_catalogs
219 for mach in resources:
222 #Get the list of SALOME components that are defined in catalogs
223 for mach in resources:
224 mach.get_components()
226 #Update the resource catalog dom object for further dump
227 for mach in resources:
230 #dump new CatalogResources.xml
231 f=open(catalog_file,'w')
232 f.write('<?xml version="1.0" ?>\n')
236 print "%s updated" % catalog_file
238 #update configRemote.sh in env.d directory (environment variable SALOME_CATALOGS_PATH)
240 for mach in resources:
241 if mach.resource_dir:
242 path.append(mach.resource_dir)
244 f=open(os.path.join(appli_local,"env.d","configRemote.sh"),'w')
245 f.write("export SALOME_CATALOGS_PATH=%s\n" % SEP.join(path))
249 if __name__ == '__main__':