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