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