Salome HOME
PR: merge from tag BR_CCRT2_mergeto_V2_1_0b1
[modules/yacs.git] / bin / runSalome.py
1 #!/usr/bin/env python
2
3 import sys, os, string, glob, time, pickle
4 import orbmodule
5
6 process_id = {}
7
8 # -----------------------------------------------------------------------------
9
10 def add_path(directory, variable_name):
11     """Function helper to add environment variables"""
12     if not os.environ.has_key(variable_name):
13         os.environ[variable_name] = ""
14         pass
15     if os.path.exists(directory):
16         newpath=[]
17         for _dir in os.environ[variable_name].split(":"):
18             if os.path.exists(_dir):
19                 if not os.path.samefile(_dir, directory):
20                   newpath.append(_dir)
21             else:
22                 if os.path.abspath(_dir) != os.path.abspath(directory):
23                   newpath.append(_dir)
24             pass
25         import string
26         newpath[:0] = [ directory ]
27         newpath = string.join(newpath,":")
28         os.environ[variable_name] = newpath
29         if variable_name == "PYTHONPATH":
30             sys.path[:0] = [directory]
31
32 # -----------------------------------------------------------------------------
33
34 def get_config():
35     """
36     Get list of modules, paths.
37     
38     Read args from launch configure xml file and command line options.
39     Check variables <module>_ROOT_DIR and set list of used modules.
40     Return args, modules_list, modules_root_dir    
41     """
42     
43     # read args from launch configure xml file and command line options
44     
45     import launchConfigureParser
46     args = launchConfigureParser.args
47     
48     # Check variables <module>_ROOT_DIR
49     # and set list of used modules (without KERNEL)
50
51     modules_list = []
52     if args.has_key("modules"):
53         modules_list += args["modules"]
54     # KERNEL must be last in the list to locate it at the first place in PATH 
55     modules_list[:0] = ["KERNEL"]
56     modules_list.reverse()
57
58     modules_root_dir = {}
59
60     to_remove_list=[]
61     for module in modules_list :
62         module_variable=module.upper()+"_ROOT_DIR"
63         if not os.environ.has_key(module_variable):
64             print "*******************************************************"
65             print "*"
66             print "* Environment variable",module_variable,"must be set"
67             print "* Module", module, "will be not available"
68             print "*"
69             print "********************************************************"
70             to_remove_list.append(module)
71             continue
72             pass
73         module_root_dir = os.environ[module_variable]
74         modules_root_dir[module]=module_root_dir
75
76     for to_remove in to_remove_list:
77         modules_list.remove(to_remove)
78
79     while "KERNEL" in modules_list:
80         modules_list.remove("KERNEL")
81         pass
82
83     if "SUPERV" in modules_list and not 'superv' in args['standalone']:
84         args['standalone'].append("superv")
85         pass
86    
87     return args, modules_list, modules_root_dir
88
89 # -----------------------------------------------------------------------------
90
91 def set_env(args, modules_list, modules_root_dir):
92     """Add to the PATH-variables modules specific paths"""
93     
94     python_version="python%d.%d" % sys.version_info[0:2]
95     modules_root_dir_list = []
96     modules_list = modules_list[:] + ["KERNEL"] 
97     for module in modules_list :
98         module_root_dir = modules_root_dir[module]
99         modules_root_dir_list[:0] = [module_root_dir]
100         add_path(os.path.join(module_root_dir,"lib",args['appname']),
101                  "LD_LIBRARY_PATH")
102         add_path(os.path.join(module_root_dir,"bin",args['appname']),
103                  "PATH")
104         if os.path.exists(module_root_dir + "/examples") :
105             add_path(os.path.join(module_root_dir,"examples"),
106                      "PYTHONPATH")
107         add_path(os.path.join(module_root_dir,"bin",args['appname']),
108                  "PYTHONPATH")
109         add_path(os.path.join(module_root_dir,"lib",
110                               python_version,"site-packages",args['appname']),
111                  "PYTHONPATH")
112         add_path(os.path.join(module_root_dir,"lib",args['appname']),
113                  "PYTHONPATH")
114         add_path(os.path.join(module_root_dir,"lib",
115                               python_version,"site-packages",args['appname'],
116                               "shared_modules"),
117                  "PYTHONPATH")
118
119     os.environ["SALOMEPATH"]=":".join(modules_root_dir_list)
120     
121     # special path for logger lib if needeed
122     
123     os.environ["SALOME_trace"]="local"
124     if args['logger']:
125         os.environ["SALOME_trace"]="with_logger"
126         locdir=os.environ['PWD']
127         libtracedir=os.path.join(locdir,"libSalomeTrace")
128         libtrace = os.path.join(modules_root_dir["KERNEL"],"lib",
129                                 args['appname'],
130                                 "libSALOMELoggerClient.so.0.0.0")
131         libtraceln = os.path.join(libtracedir,"libSALOMELocalTrace.so")
132         aCommand = 'rm -rf ' + libtracedir + "; "
133         aCommand += 'mkdir ' + libtracedir + "; "
134         aCommand += 'ln -s ' + libtrace + " " + libtraceln + "; "
135         aCommand += 'ln -s ' + libtrace + " " + libtraceln + ".0; "
136         aCommand += 'ln -s ' + libtrace + " " + libtraceln + ".0.0.0; "
137         os.system(aCommand)
138         add_path(libtracedir, "LD_LIBRARY_PATH")
139
140     # set environment for SMESH plugins
141
142     if "SMESH" in modules_list:
143         os.environ["SMESH_MeshersList"]="StdMeshers"
144         if not os.environ.has_key("SALOME_StdMeshersResources"):
145             os.environ["SALOME_StdMeshersResources"] \
146             = modules_root_dir["SMESH"]+"/share/"+args["appname"]+"/resources"
147             pass
148         if args.has_key("SMESH_plugins"):
149             for plugin in args["SMESH_plugins"]:
150                 if os.environ.has_key(plugin.upper()+"_ROOT_DIR"):
151                     os.environ["SMESH_MeshersList"] \
152                     = os.environ["SMESH_MeshersList"]+":"+plugin
153                     plugin_root = os.environ[plugin.upper()+"_ROOT_DIR"]
154                     if not os.environ.has_key("SALOME_"+plugin+"Resources"):
155                         os.environ["SALOME_"+plugin+"Resources"] \
156                         = plugin_root+"/share/"+args["appname"]+"/resources"
157                     add_path(os.path.join(plugin_root,"lib",python_version,
158                                           "site-packages",args['appname']),
159                              "PYTHONPATH")
160                     add_path(os.path.join(plugin_root,"lib",args['appname']),
161                              "PYTHONPATH")
162                     add_path(os.path.join(plugin_root,"lib",args['appname']),
163                              "LD_LIBRARY_PATH")
164                     add_path(os.path.join(plugin_root,"bin",args['appname']),
165                              "PYTHONPATH")
166                     add_path(os.path.join(plugin_root,"bin",args['appname']),
167                              "PATH")
168             pass
169         pass
170
171     # set environment for SUPERV module
172     os.environ["ENABLE_MACRO_NODE"]="1"
173    
174
175 # -----------------------------------------------------------------------------
176
177 from killSalome import killAllPorts
178
179 def killLocalPort():
180     """
181     kill servers from a previous SALOME exection, if needed,
182     on the CORBA port given in args of runSalome
183     """
184     
185     from killSalomeWithPort import killMyPort
186     my_port=str(args['port'])
187     try:
188         killMyPort(my_port)
189     except:
190         print "problem in killLocalPort()"
191         pass
192     pass
193     
194 def givenPortKill(port):
195     """
196     kill servers from a previous SALOME exection, if needed,
197     on the same CORBA port
198     """
199     
200     from killSalomeWithPort import killMyPort
201     my_port=port
202     try:
203         killMyPort(my_port)
204     except:
205         print "problem in LocalPortKill(), killMyPort("<<port<<")"
206         pass
207     pass
208
209 def kill_salome(args):
210     """
211     Kill servers from previous SALOME executions, if needed;
212     depending on args 'killall' or 'portkill', kill all executions,
213     or only execution on the same CORBA port
214     """
215
216     if args['killall']:
217         killAllPorts()
218     elif args['portkill']:
219         givenPortKill(str(args['port']))
220         
221 # -----------------------------------------------------------------------------
222 #
223 # Définition des classes d'objets pour le lancement des Server CORBA
224 #
225
226 class Server:
227     """Generic class for CORBA server launch"""
228
229     def initArgs(self):
230         self.CMD=[]
231         self.ARGS=[]    
232         if self.args['xterm']:
233             self.ARGS=['xterm', '-iconic', '-sb', '-sl', '500', '-hold']
234
235     def __init__(self,args):
236         self.args=args
237         self.initArgs()
238
239
240     def run(self):
241         global process_id
242         myargs=self.ARGS
243         if self.args['xterm']:
244             # (Debian) send LD_LIBRARY_PATH to children shells (xterm)
245             env_ld_library_path=['env', 'LD_LIBRARY_PATH='
246                                  + os.getenv("LD_LIBRARY_PATH")]
247             myargs = myargs +['-T']+self.CMD[:1]+['-e'] + env_ld_library_path
248         command = myargs + self.CMD
249         # print "command = ", command
250         pid = os.spawnvp(os.P_NOWAIT, command[0], command)
251         process_id[pid]=self.CMD
252
253 # ---
254
255 class CatalogServer(Server):
256     def __init__(self,args):
257         self.args=args
258         self.initArgs()
259         self.SCMD1=['SALOME_ModuleCatalog_Server','-common']
260         self.SCMD2=['-personal',
261                     '${HOME}/Salome/resources/CatalogModulePersonnel.xml'] 
262
263     def setpath(self,modules_list,modules_root_dir):
264         cata_path=[]
265         list_modules = modules_list[:]
266         list_modules.reverse()
267         for module in ["KERNEL"] + list_modules:
268             module_root_dir=modules_root_dir[module]
269             module_cata=module+"Catalog.xml"
270             print "   ", module_cata
271             cata_path.extend(
272                 glob.glob(os.path.join(module_root_dir,
273                                        "share",self.args['appname'],
274                                        "resources",module_cata)))
275         self.CMD=self.SCMD1 + [string.join(cata_path,':')] + self.SCMD2
276
277 # ---
278
279 class SalomeDSServer(Server):
280     def __init__(self,args):
281         self.args=args
282         self.initArgs()
283         self.CMD=['SALOMEDS_Server']
284
285 # ---
286
287 class RegistryServer(Server):
288     def __init__(self,args):
289         self.args=args
290         self.initArgs()
291         self.CMD=['SALOME_Registry_Server', '--salome_session','theSession']
292
293 # ---
294
295 class ContainerCPPServer(Server):
296     def __init__(self,args):
297         self.args=args
298         self.initArgs()
299         self.CMD=['SALOME_Container','FactoryServer']
300
301 # ---
302
303 class ContainerPYServer(Server):
304     def __init__(self,args):
305         self.args=args
306         self.initArgs()
307         self.CMD=['SALOME_ContainerPy.py','FactoryServerPy']
308
309 # ---
310
311 class ContainerSUPERVServer(Server):
312     def __init__(self,args):
313         self.args=args
314         self.initArgs()
315         self.CMD=['SALOME_Container','SuperVisionContainer']
316
317 # ---
318
319 class LoggerServer(Server):
320     def __init__(self,args):
321         self.args=args
322         self.initArgs()
323         self.CMD=['SALOME_Logger_Server', 'logger.log']
324
325 # ---
326
327 class SessionLoader(Server):
328     def __init__(self,args):
329         self.args=args
330         self.initArgs()
331         self.CMD=['SALOME_Session_Loader']
332         if "cppContainer" in self.args['standalone'] \
333         or "cppContainer" in self.args['embedded']:
334             self.CMD=self.CMD+['CPP']
335         if "pyContainer" in self.args['standalone'] \
336         or "pyContainer" in self.args['embedded']:
337             self.CMD=self.CMD+['PY']
338         if "supervContainer" in self.args['containers'] \
339         or "supervContainer" in self.args['standalone']:
340             self.CMD=self.CMD+['SUPERV']
341         if self.args['gui']:
342             self.CMD=self.CMD+['GUI']
343         print self.CMD
344
345 # ---
346
347 class SessionServer(Server):
348     def __init__(self,args):
349         self.args=args
350         self.initArgs()
351         self.SCMD1=['SALOME_Session_Server']
352         self.SCMD2=[]
353         if 'registry' in self.args['embedded']:
354             self.SCMD1+=['--with','Registry',
355                          '(','--salome_session','theSession',')']
356         if 'moduleCatalog' in self.args['embedded']:
357             self.SCMD1+=['--with','ModuleCatalog','(','-common']
358             self.SCMD2+=['-personal',
359                      '${HOME}/Salome/resources/CatalogModulePersonnel.xml',')']
360         if 'study' in self.args['embedded']:
361             self.SCMD2+=['--with','SALOMEDS','(',')']
362         if 'cppContainer' in self.args['embedded']:
363             self.SCMD2+=['--with','Container','(','FactoryServer',')']
364
365     def setpath(self,modules_list,modules_root_dir):
366         cata_path=[]
367         list_modules = modules_list[:]
368         list_modules.reverse()
369         for module in ["KERNEL"] + list_modules:
370             module_root_dir=modules_root_dir[module]
371             module_cata=module+"Catalog.xml"
372             print "   ", module_cata
373             cata_path.extend(
374                 glob.glob(os.path.join(module_root_dir,"share",
375                                        self.args['appname'],"resources",
376                                        module_cata)))
377         if 'moduleCatalog' in self.args['embedded']:
378             self.CMD=self.SCMD1 + [string.join(cata_path,':')] + self.SCMD2
379         else:
380             self.CMD=self.SCMD1 + self.SCMD2
381
382 ##      # arguments SALOME_Session_Server pour ddd
383 ##      comm_ddd=""
384 ##      for mot in self.CMD:
385 ##          if mot == "(":
386 ##              comm_ddd+='"(" '
387 ##          elif mot == ")":
388 ##              comm_ddd+='")" '
389 ##          else:
390 ##              comm_ddd+=mot+" "
391 ##      print comm_ddd
392       
393 # ---
394
395 class NotifyServer(Server):
396     def __init__(self,args,modules_root_dir):
397         self.args=args
398         self.initArgs()
399         self.modules_root_dir=modules_root_dir
400         myLogName = os.environ["LOGNAME"]
401         self.CMD=['notifd','-c',
402                   self.modules_root_dir["KERNEL"]
403                   +'/share/salome/resources/channel.cfg',
404                   '-DFactoryIORFileName=/tmp/'+myLogName+'_rdifact.ior',
405                   '-DChannelIORFileName=/tmp/'+myLogName+'_rdichan.ior']
406
407 #
408 # -----------------------------------------------------------------------------
409
410 def startGUI():
411     """Salome Session Graphic User Interface activation"""
412     import SALOME
413     session=clt.waitNS("/Kernel/Session",SALOME.Session)
414     session.GetInterface()
415   
416 # -----------------------------------------------------------------------------
417
418 def startSalome(args, modules_list, modules_root_dir):
419     """Launch all SALOME servers requested by args"""
420     init_time = os.times()
421
422     #
423     # Lancement Session Loader
424     #
425
426     print "startSalome ", args
427     
428     if args['gui']:
429         myServer=SessionLoader(args)
430         myServer.run()
431
432     #
433     # Initialisation ORB et Naming Service
434     #
435    
436     clt=orbmodule.client()
437
438     # (non obligatoire) Lancement Logger Server
439     # et attente de sa disponibilite dans le naming service
440     #
441
442     if args['logger']:
443         myServer=LoggerServer(args)
444         myServer.run()
445         clt.waitLogger("Logger")
446
447     # Notify Server launch
448     #
449
450     myServer=NotifyServer(args,modules_root_dir)
451     myServer.run()
452
453     #
454     # Lancement Registry Server,
455     # attente de la disponibilité du Registry dans le Naming Service
456     #
457
458     if 'registry' not in args['embedded']:
459         myServer=RegistryServer(args)
460         myServer.run()
461         clt.waitNS("/Registry")
462
463     #
464     # Lancement Catalog Server,
465     # attente de la disponibilité du Catalog Server dans le Naming Service
466     #
467
468     if 'moduleCatalog' not in args['embedded']:
469         cataServer=CatalogServer(args)
470         cataServer.setpath(modules_list,modules_root_dir)
471         cataServer.run()
472         import SALOME_ModuleCatalog
473         clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog)
474
475     #
476     # Lancement SalomeDS Server,
477     # attente de la disponibilité du SalomeDS dans le Naming Service
478     #
479
480     os.environ["CSF_PluginDefaults"] \
481     = os.path.join(modules_root_dir["KERNEL"],"share",
482                    args['appname'],"resources")
483     os.environ["CSF_SALOMEDS_ResourcesDefaults"] \
484     = os.path.join(modules_root_dir["KERNEL"],"share",
485                    args['appname'],"resources")
486
487     if "GEOM" in modules_list:
488         print "GEOM OCAF Resources"
489         os.environ["CSF_GEOMDS_ResourcesDefaults"] \
490         = os.path.join(modules_root_dir["GEOM"],"share",
491                        args['appname'],"resources")
492         print "GEOM Shape Healing Resources"
493         os.environ["CSF_ShHealingDefaults"] \
494         = os.path.join(modules_root_dir["GEOM"],"share",
495                        args['appname'],"resources")
496
497     if 'study' not in args['embedded']:
498         myServer=SalomeDSServer(args)
499         myServer.run()
500         clt.waitNS("/myStudyManager")
501
502     #
503     # Lancement Session Server
504     #
505
506     mySessionServ = SessionServer(args)
507     mySessionServ.setpath(modules_list,modules_root_dir)
508     mySessionServ.run()
509
510     #macomm2=['ddd']
511     #pid = os.spawnvp(os.P_NOWAIT, macomm2[0], macomm2)
512     #
513     # Attente de la disponibilité du Session Server dans le Naming Service
514     #
515
516     import SALOME
517     session=clt.waitNS("/Kernel/Session",SALOME.Session)
518
519     from Utils_Identity import getShortHostName
520     
521     if os.getenv("HOSTNAME") == None:
522         if os.getenv("HOST") == None:
523             os.environ["HOSTNAME"]=getShortHostName()
524         else:
525             os.environ["HOSTNAME"]=os.getenv("HOST")
526
527     theComputer = getShortHostName()
528   
529     #
530     # Lancement Container C++ local,
531     # attente de la disponibilité du Container C++ local dans le Naming Service
532     #
533
534     if 'cppContainer' in args['standalone']:
535         myServer=ContainerCPPServer(args)
536         myServer.run()
537         clt.waitNS("/Containers/" + theComputer + "/FactoryServer")
538
539     #
540     # Lancement Container Python local,
541     # attente de la disponibilité du Container Python local
542     # dans le Naming Service
543     #
544
545     if 'pyContainer' in args['standalone']:
546         myServer=ContainerPYServer(args)
547         myServer.run()
548         clt.waitNS("/Containers/" + theComputer + "/FactoryServerPy")
549
550     #
551     # Lancement Container Supervision local,
552     # attente de la disponibilité du Container Supervision local
553     # dans le Naming Service
554     #
555
556     if 'supervContainer' in args['standalone']:
557         myServer=ContainerSUPERVServer(args)
558         myServer.run()
559         clt.waitNS("/Containers/" + theComputer + "/SuperVisionContainer")
560
561     end_time = os.times()
562     print
563     print "Start SALOME, elapsed time : %5.1f seconds"% (end_time[4]
564                                                          - init_time[4])
565
566     return clt
567
568 # -----------------------------------------------------------------------------
569
570 def useSalome(args, modules_list, modules_root_dir):
571     """
572     Launch all SALOME servers requested by args,
573     save list of process, give info to user,
574     show registered objects in Naming Service.
575     """
576     
577     clt=None
578     try:
579         clt = startSalome(args, modules_list, modules_root_dir)
580     except:
581         print
582         print
583         print "--- erreur au lancement Salome ---"
584         
585     #print process_id
586     
587     filedict = '/tmp/' + os.getenv('USER') + "_" + str(args['port']) \
588              + '_' + args['appname'].upper() + '_pidict'
589    
590     process_ids = []
591     try:
592         fpid=open(filedict, 'r')
593         process_ids=pickle.load(fpid)
594         fpid.close()
595     except:
596         pass
597     
598     fpid=open(filedict, 'w')
599     process_ids.append(process_id)
600     pickle.dump(process_ids,fpid)
601     fpid.close()
602     
603     print """
604     Saving of the dictionary of Salome processes in %s
605     To kill SALOME processes from a console (kill all sessions from all ports):
606       python killSalome.py 
607     To kill SALOME from the present interpreter, if it is not closed :
608       killLocalPort()      --> kill this session
609                                (use CORBA port from args of runSalome)
610       givenPortKill(port)  --> kill a specific session with given CORBA port 
611       killAllPorts()       --> kill all sessions
612     
613     runSalome, with --killall option, starts with killing
614     the processes resulting from the previous execution.
615     """%filedict
616     
617     #
618     #  Impression arborescence Naming Service
619     #
620     
621     if clt != None:
622         print
623         print " --- registered objects tree in Naming Service ---"
624         clt.showNS()
625
626     return clt
627
628 # -----------------------------------------------------------------------------
629
630 def registerEnv(args, modules_list, modules_root_dir):
631     """
632     Register args, modules_list, modules_root_dir in a file
633     for further use, when SALOME is launched embedded in an other application.
634     """
635     fileEnv = '/tmp/' + os.getenv('USER') + "_" + str(args['port']) \
636             + '_' + args['appname'].upper() + '_env'
637     fenv=open(fileEnv,'w')
638     pickle.dump((args, modules_list, modules_root_dir),fenv)
639     fenv.close()
640     os.environ["SALOME_LAUNCH_CONFIG"] = fileEnv
641
642 # -----------------------------------------------------------------------------
643
644 def no_main():
645     """Salome Launch, when embedded in other application"""
646     fileEnv = os.environ["SALOME_LAUNCH_CONFIG"]
647     fenv=open(fileEnv,'r')
648     args, modules_list, modules_root_dir = pickle.load(fenv)
649     fenv.close()
650     kill_salome(args)
651     clt = useSalome(args, modules_list, modules_root_dir)
652     return clt
653
654 # -----------------------------------------------------------------------------
655
656 def main():
657     """Salome launch as a main application"""
658     args, modules_list, modules_root_dir = get_config()
659     kill_salome(args)
660     set_env(args, modules_list, modules_root_dir)
661     clt = useSalome(args, modules_list, modules_root_dir)
662     return clt,args
663
664 # -----------------------------------------------------------------------------
665
666 if __name__ == "__main__":
667    clt,args = main()