Salome HOME
0023299: [CEA] Finalize multi-study removal
[modules/homard.git] / bin / runHOMARD.py
1 #!/usr/bin/env python
2 # Copyright (C) 2011-2016  CEA/DEN, EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 usage="""USAGE: runHOMARD.py [options]
22
23 [command line options] :
24 --help                        : affichage de l'aide
25 --gui                         : lancement du GUI
26 --logger                      : redirection des messages dans un fichier
27 --xterm                       : les serveurs ouvrent une fen�tre xterm et les messages sont affich�s dans cette fen�tre
28 --modules=module1,module2,... : o� modulen est le nom d'un module Salome � charger dans le catalogue
29 --containers=cpp,python,superv: lancement des containers cpp, python et de supervision
30 --killall                     : arr�t des serveurs de salome
31
32  La variable d'environnement <modulen>_ROOT_DIR doit etre pr�alablement
33  positionn�e (modulen doit etre en majuscule).
34  KERNEL_ROOT_DIR est obligatoire.
35 """
36
37 # -----------------------------------------------------------------------------
38 #
39 # Fonction d'arr�t de salome
40 #
41
42 def killSalome():
43    print "arret des serveurs SALOME"
44    for pid, cmd in process_id.items():
45       print "arret du process %s : %s"% (pid, cmd[0])
46       try:
47         os.kill(pid,signal.SIGKILL)
48       except:
49          print "  ------------------ process %s : %s inexistant"% (pid, cmd[0])
50    print "arret du naming service"
51    os.system("killall -9 omniNames")
52    
53 # -----------------------------------------------------------------------------
54 #
55 # Fonction message
56 #
57
58 def message(code, msg=''):
59     if msg: print msg
60     sys.exit(code)
61
62 import sys,os,string,glob,time,signal,pickle,getopt
63
64 init_time=os.times()
65 opts, args=getopt.getopt(sys.argv[1:], 'hmglxck:', ['help','modules=','gui','logger','xterm','containers=','killall'])
66 modules_root_dir={}
67 process_id={}
68 liste_modules={}
69 liste_containers={}
70 with_gui=0
71 with_logger=0
72 with_xterm=0
73
74 with_container_cpp=0
75 with_container_python=0
76 with_container_superv=0
77
78 try:
79   for o, a in opts:
80     if o in ('-h', '--help'):
81       print usage
82       sys.exit(1)
83     elif o in ('-g', '--gui'):
84       with_gui=1
85     elif o in ('-l', '--logger'):
86       with_logger=1
87     elif o in ('-x', '--xterm'):
88       with_xterm=1
89     elif o in ('-m', '--modules'):
90       liste_modules = [x.upper() for x in a.split(',')]
91     elif o in ('-c', '--containers'):
92       liste_containers = [x.lower() for x in a.split(',')]
93       for r in liste_containers:
94         if r not in ('cpp', 'python', 'superv'):
95            message(1, 'Invalid -c/--containers option: %s' % a)
96       if 'cpp' in liste_containers:
97            with_container_cpp=1
98       else:
99            with_container_cpp=0
100       if 'python' in liste_containers:
101            with_container_python=1
102       else:
103            with_container_python=0
104       if 'superv' in liste_containers:
105            with_container_superv=1
106       else:
107            with_container_superv=0
108     elif o in ('-k', '--killall'):
109       filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict'
110       #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict'
111       found = 0
112       try:
113          fpid=open(filedict, 'r')
114          found = 1
115       except:
116          print "le fichier %s des process SALOME n'est pas accessible"% filedict
117
118       if found:
119          process_id=pickle.load(fpid)
120          fpid.close()
121          killSalome()
122          process_id={}
123          os.remove(filedict)
124         
125 except getopt.error, msg:
126   print usage
127   sys.exit(1)
128
129 # -----------------------------------------------------------------------------
130 #
131 # V�rification des variables d'environnement
132 #
133 try:
134   kernel_root_dir=os.environ["KERNEL_ROOT_DIR"]
135   modules_root_dir["KERNEL"]=kernel_root_dir
136 except:
137   print usage
138   sys.exit(1)
139
140 for module in liste_modules :
141    try:
142       module=module.upper()
143       module_root_dir=os.environ[module +"_ROOT_DIR"]
144       modules_root_dir[module]=module_root_dir
145    except:
146       print usage
147       sys.exit(1)
148
149 # il faut KERNEL en premier dans la liste des modules
150 # - l'ordre des modules dans le catalogue sera identique
151 # - la liste des modules presents dans le catalogue est exploit�e pour charger les modules CORBA python,
152 #   il faut charger les modules python du KERNEL en premier
153
154 if "KERNEL" in liste_modules:liste_modules.remove("KERNEL")
155 liste_modules[:0]=["KERNEL"]
156 #print liste_modules
157 #print modules_root_dir
158
159 os.environ["SALOMEPATH"]=":".join(modules_root_dir.values())
160 if "SUPERV" in liste_modules:with_container_superv=1
161
162
163 # -----------------------------------------------------------------------------
164 #
165 # D�finition des classes d'objets pour le lancement des Server CORBA
166 #
167
168 class Server:
169    CMD=[]
170    if with_xterm:
171         ARGS=['xterm', '-iconic', '-sb', '-sl', '500', '-e']
172    else:
173         ARGS=[] 
174
175    def run(self):
176       args = self.ARGS+self.CMD
177       #print "args = ", args
178       pid = os.spawnvp(os.P_NOWAIT, args[0], args)
179       process_id[pid]=self.CMD
180
181 class CatalogServer(Server):
182    SCMD1=['SALOME_ModuleCatalog_Server','-common']
183    SCMD2=['-personal','${HOME}/Salome/resources/CatalogModulePersonnel.xml'] 
184
185    def setpath(self,liste_modules):
186       cata_path=[]
187       for module in liste_modules:
188           module_root_dir=modules_root_dir[module]
189           module_cata=module+"Catalog.xml"
190           print "   ", module_cata
191           cata_path.extend(glob.glob(os.path.join(module_root_dir,"share","salome","resources",module_cata)))
192       self.CMD=self.SCMD1 + [string.join(cata_path,':')] + self.SCMD2
193
194 class SalomeDSServer(Server):
195    CMD=['SALOMEDS_Server']
196
197 class RegistryServer(Server):
198    CMD=['SALOME_Registry_Server', '--salome_session','theSession']
199
200 class ContainerCPPServer(Server):
201    CMD=['SALOME_Container','FactoryServer','-ORBInitRef','NameService=corbaname::localhost']
202
203 class ContainerPYServer(Server):
204    CMD=['SALOME_ContainerPy.py','FactoryServerPy','-ORBInitRef','NameService=corbaname::localhost']
205
206 class ContainerSUPERVServer(Server):
207    CMD=['SALOME_Container','SuperVisionContainer','-ORBInitRef','NameService=corbaname::localhost']
208
209 class LoggerServer(Server):
210    CMD=['SALOME_Logger_Server', 'logger.log']
211
212 class SessionLoader(Server):
213    CMD=['SALOME_Session_Loader']
214    if with_container_cpp:
215        CMD=CMD+['CPP']
216    if with_container_python:
217        CMD=CMD+['PY']
218    if with_container_superv:
219        CMD=CMD+['SUPERV']
220    if with_gui:
221        CMD=CMD+['GUI']
222
223 class SessionServer(Server):
224    CMD=['SALOME_Session_Server']
225
226 class NotifyServer(Server):
227    CMD=['notifd','-c','${KERNEL_ROOT_DIR}/share/salome/resources/channel.cfg -DFactoryIORFileName=/tmp/${LOGNAME}_rdifact.ior -DChannelIORFileName=/tmp/${LOGNAME}_rdichan.ior']
228
229 # -----------------------------------------------------------------------------
230 #
231 # Fonction de test
232 #
233
234 def test(clt):
235    """
236         Test function that creates an instance of PYHELLO component
237         usage : pyhello=test(clt)
238    """
239    # create an LifeCycleCORBA instance
240    import LifeCycleCORBA 
241    lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
242    import PYHELLO_ORB
243    pyhello = lcc.FindOrLoadComponent("FactoryServerPy", "PYHELLO")
244    return pyhello
245
246 # -----------------------------------------------------------------------------
247 #
248 # Fonctions helper pour ajouter des variables d'environnement
249 #
250
251 def add_path(directory):
252    os.environ["PATH"]=directory + ":" + os.environ["PATH"]
253
254 def add_ld_library_path(directory):
255    os.environ["LD_LIBRARY_PATH"]=directory + ":" + os.environ["LD_LIBRARY_PATH"]
256
257 def add_python_path(directory):
258    os.environ["PYTHONPATH"]=directory + ":" + os.environ["PYTHONPATH"]
259    sys.path[:0]=[directory]
260
261 # -----------------------------------------------------------------------------
262 #
263 # initialisation des variables d'environnement
264 #
265
266 python_version="python%d.%d" % sys.version_info[0:2]
267
268 #
269 # Ajout du chemin d'acces aux executables de KERNEL dans le PATH
270 #
271
272 add_path(os.path.join(kernel_root_dir,"bin","salome"))
273 #print "PATH=",os.environ["PATH"]
274
275 #
276 # Ajout des modules dans le LD_LIBRARY_PATH
277 #
278 for module in liste_modules:
279     module_root_dir=modules_root_dir[module]
280     add_ld_library_path(os.path.join(module_root_dir,"lib","salome"))
281 #print "LD_LIBRARY_PATH=",os.environ["LD_LIBRARY_PATH"]
282
283 #
284 # Ajout des modules dans le PYTHONPATH (KERNEL prioritaire, donc en dernier)
285 #
286
287 liste_modules_reverse=liste_modules[:]
288 liste_modules_reverse.reverse()
289 #print liste_modules
290 #print liste_modules_reverse
291 for module in liste_modules_reverse:
292     module_root_dir=modules_root_dir[module]
293     add_python_path(os.path.join(module_root_dir,"bin","salome"))
294     add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome"))
295     add_python_path(os.path.join(module_root_dir,"lib","salome"))
296     add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome","shared_modules"))
297
298 #print "PYTHONPATH=",sys.path
299
300 import orbmodule
301
302 #
303 # -----------------------------------------------------------------------------
304 #
305
306 def startGUI():
307   import SALOME
308   session=clt.waitNS("/Kernel/Session",SALOME.Session)
309
310   #
311   # Activation du GUI de Session Server
312   #
313         
314   session.GetInterface()
315   
316 #
317 # -----------------------------------------------------------------------------
318 #
319
320 def startSalome():
321
322   #
323   # Lancement Session Loader
324   #
325   SessionLoader().run()
326
327   #
328   # Initialisation ORB et Naming Service
329   #
330   clt=orbmodule.client()
331
332   # (non obligatoire) Lancement Logger Server et attente de sa 
333   #  disponibilite dans le naming service
334   #
335   if with_logger:
336         LoggerServer().run()
337         clt.waitLogger("Logger")
338
339   #
340   # Lancement Registry Server
341   #
342   RegistryServer().run()
343
344   #
345   # Attente de la disponibilit� du Registry dans le Naming Service
346   #
347   clt.waitNS("/Registry")
348
349   #
350   # Lancement Catalog Server
351   #
352   cataServer=CatalogServer()
353   cataServer.setpath(liste_modules)
354   cataServer.run()
355
356   #
357   # Attente de la disponibilit� du Catalog Server dans le Naming Service
358   #
359   import SALOME_ModuleCatalog
360   clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog)
361
362   #
363   # Lancement SalomeDS Server
364   #
365   os.environ["CSF_PluginDefaults"]=os.path.join(kernel_root_dir,"share","salome","resources")
366   os.environ["CSF_SALOMEDS_ResourcesDefaults"]=os.path.join(kernel_root_dir,"share","salome","resources")
367   SalomeDSServer().run()
368
369   if "GEOM" in liste_modules:
370         print "GEOM OCAF Resources"
371         os.environ["CSF_GEOMDS_ResourcesDefaults"]=os.path.join(modules_root_dir["GEOM"],"share","salome","resources")
372
373
374   #
375   # Attente de la disponibilit� du SalomeDS dans le Naming Service
376   #
377   clt.waitNS("/Study")
378
379   #
380   # Lancement Session Server
381   #
382   SessionServer().run()
383
384   #
385   # Attente de la disponibilit� du Session Server dans le Naming Service
386   #
387   import SALOME
388   session=clt.waitNS("/Kernel/Session",SALOME.Session)
389
390   #
391   # Lancement containers
392   #
393   theComputer = os.getenv("HOSTNAME")
394   theComputer = theComputer.split('.')[0]
395
396   #
397   # Lancement Container C++ local
398   #
399   if with_container_cpp:
400           ContainerCPPServer().run()
401           #
402           # Attente de la disponibilit� du Container C++ local 
403           # dans le Naming Service
404           #
405           clt.waitNS("/Containers/" + theComputer + "/FactoryServer")
406   #
407   # Lancement Container Python local
408   #
409   if with_container_python:
410           ContainerPYServer().run()
411           #
412           # Attente de la disponibilit� du Container Python local 
413           #  dans le Naming Service
414           #
415           clt.waitNS("/Containers/" + theComputer + "/FactoryServerPy")
416
417   if with_container_superv:
418         #
419         # Lancement Container Supervision local
420         #
421         ContainerSUPERVServer().run()
422         #
423         # Attente de la disponibilit� du Container Supervision local 
424         # dans le Naming Service
425         #
426         clt.waitNS("/Containers/" + theComputer + "/SuperVisionContainer")
427   #
428   # Activation du GUI de Session Server
429   #
430   #session.GetInterface()
431
432   end_time = os.times()
433   print
434   print "Start SALOME, elpased time : %5.1f seconds"% (end_time[4] - init_time[4])
435
436   return clt
437
438 #
439 # -----------------------------------------------------------------------------
440 #
441
442 if __name__ == "__main__":
443    clt=None
444    try:
445       clt = startSalome()
446    except:
447       print
448       print
449       print "--- erreur au lancement Salome ---"
450    
451    #print process_id
452    
453    
454    filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict'
455    #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict'
456    
457    fpid=open(filedict, 'w')
458    pickle.dump(process_id,fpid)
459    fpid.close()
460    
461    print """
462
463 Sauvegarde du dictionnaire des process dans , %s
464 Pour tuer les process SALOME, executer : python killSalome.py depuis
465 une console, ou bien killSalome() depuis le present interpreteur,
466 s'il n'est pas ferm�.
467
468 runHOMARD, avec l'option --killall, commence par tuer les process restants 
469 d'une execution pr�c�dente.
470
471 Pour lancer uniquement le GUI, executer startGUI() depuis le present interpreteur,
472 s'il n'est pas ferm�.
473
474 """ % filedict
475    
476    #
477    #  Impression arborescence Naming Service
478    #
479    
480    if clt != None:
481      print
482      print " --- registered objects tree in Naming Service ---"
483      clt.showNS()
484      session=clt.waitNS("/Kernel/Session")
485      catalog=clt.waitNS("/Kernel/ModulCatalog")
486      import socket
487      container =  clt.waitNS("/Containers/" + socket.gethostname().split('.')[0] + "/FactoryServerPy")
488    
489    if os.path.isfile("~/.salome/pystartup"):
490       f=open(os.path.expanduser("~/.salome/pystartup"),'w')
491       PYTHONSTARTUP=f.read()
492       f.close()
493    else:
494       PYTHONSTARTUP="""
495 # Add auto-completion and a stored history file of commands to your Python
496 # interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
497 # bound to the TAB key by default (you can change it - see readline docs).
498 #
499 # Store the history in ~/.salome/pyhistory, 
500 #
501 import atexit
502 import os
503 import readline
504 import rlcompleter
505 readline.parse_and_bind('tab: complete')
506
507 historyPath = os.path.expanduser("~/.salome/pyhistory")
508
509 def save_history(historyPath=historyPath):
510     import readline
511     readline.write_history_file(historyPath)
512
513 if os.path.exists(historyPath):
514     readline.read_history_file(historyPath)
515
516 atexit.register(save_history)
517 del os, atexit, readline, rlcompleter, save_history, historyPath
518 """
519       f=open(os.path.expanduser("~/.salome/pystartup"),'w')
520       f.write(PYTHONSTARTUP)
521       f.close()
522
523    exec PYTHONSTARTUP in {}
524