Salome HOME
5fb5c006d8e5800c463e3afcae4451219aea7249
[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['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"]
404                   +'/share/salome/resources/channel.cfg',
405                   '-DFactoryIORFileName=/tmp/'+myLogName+'_rdifact.ior',
406                   '-DChannelIORFileName=/tmp/'+myLogName+'_rdichan.ior']
407
408 #
409 # -----------------------------------------------------------------------------
410
411 def startGUI():
412     """Salome Session Graphic User Interface activation"""
413     import SALOME
414     session=clt.waitNS("/Kernel/Session",SALOME.Session)
415     session.GetInterface()
416   
417 # -----------------------------------------------------------------------------
418
419 def startSalome(args, modules_list, modules_root_dir):
420     """Launch all SALOME servers requested by args"""
421     init_time = os.times()
422
423     #
424     # Lancement Session Loader
425     #
426
427     print "startSalome ", args
428     
429     if args['gui']:
430         myServer=SessionLoader(args)
431         myServer.run()
432
433     #
434     # Initialisation ORB et Naming Service
435     #
436    
437     clt=orbmodule.client()
438
439     # (non obligatoire) Lancement Logger Server
440     # et attente de sa disponibilite dans le naming service
441     #
442
443     if args['logger']:
444         myServer=LoggerServer(args)
445         myServer.run()
446         clt.waitLogger("Logger")
447
448     # Notify Server launch
449     #
450
451     print "Notify Server to launch"
452
453     myServer=NotifyServer(args,modules_root_dir)
454     myServer.run()
455
456     #
457     # Lancement Registry Server,
458     # attente de la disponibilité du Registry dans le Naming Service
459     #
460
461     if 'registry' not in args['embedded']:
462         myServer=RegistryServer(args)
463         myServer.run()
464         clt.waitNS("/Registry")
465
466     #
467     # Lancement Catalog Server,
468     # attente de la disponibilité du Catalog Server dans le Naming Service
469     #
470     
471
472     if 'moduleCatalog' not in args['embedded']:
473         cataServer=CatalogServer(args)
474         cataServer.setpath(modules_list,modules_root_dir)
475         cataServer.run()
476         import SALOME_ModuleCatalog
477         clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog)
478
479     #
480     # Lancement SalomeDS Server,
481     # attente de la disponibilité du SalomeDS dans le Naming Service
482     #
483
484     os.environ["CSF_PluginDefaults"] \
485     = os.path.join(modules_root_dir["KERNEL"],"share",
486                    args['appname'],"resources")
487     os.environ["CSF_SALOMEDS_ResourcesDefaults"] \
488     = os.path.join(modules_root_dir["KERNEL"],"share",
489                    args['appname'],"resources")
490
491     if "GEOM" in modules_list:
492         print "GEOM OCAF Resources"
493         os.environ["CSF_GEOMDS_ResourcesDefaults"] \
494         = os.path.join(modules_root_dir["GEOM"],"share",
495                        args['appname'],"resources")
496         print "GEOM Shape Healing Resources"
497         os.environ["CSF_ShHealingDefaults"] \
498         = os.path.join(modules_root_dir["GEOM"],"share",
499                        args['appname'],"resources")
500
501     if 'study' not in args['embedded']:
502         myServer=SalomeDSServer(args)
503         myServer.run()
504         clt.waitNS("/myStudyManager")
505
506     #
507     # Lancement Session Server
508     #
509
510     mySessionServ = SessionServer(args)
511     mySessionServ.setpath(modules_list,modules_root_dir)
512     mySessionServ.run()
513
514     #macomm2=['ddd']
515     #pid = os.spawnvp(os.P_NOWAIT, macomm2[0], macomm2)
516     #
517     # Attente de la disponibilité du Session Server dans le Naming Service
518     #
519
520     import SALOME
521     session=clt.waitNS("/Kernel/Session",SALOME.Session)
522
523     from Utils_Identity import getShortHostName
524     
525     if os.getenv("HOSTNAME") == None:
526         if os.getenv("HOST") == None:
527             os.environ["HOSTNAME"]=getShortHostName()
528         else:
529             os.environ["HOSTNAME"]=os.getenv("HOST")
530
531     theComputer = getShortHostName()
532     
533     #
534     # Lancement Container C++ local,
535     # attente de la disponibilité du Container C++ local dans le Naming Service
536     #
537
538     if 'cppContainer' in args['standalone']:
539         myServer=ContainerCPPServer(args)
540         myServer.run()
541         clt.waitNS("/Containers/" + theComputer + "/FactoryServer")
542
543     #
544     # Lancement Container Python local,
545     # attente de la disponibilité du Container Python local
546     # dans le Naming Service
547     #
548
549     if 'pyContainer' in args['standalone']:
550         myServer=ContainerPYServer(args)
551         myServer.run()
552         clt.waitNS("/Containers/" + theComputer + "/FactoryServerPy")
553
554     #
555     # Lancement Container Supervision local,
556     # attente de la disponibilité du Container Supervision local
557     # dans le Naming Service
558     #
559
560     if 'supervContainer' in args['standalone']:
561         myServer=ContainerSUPERVServer(args)
562         myServer.run()
563         clt.waitNS("/Containers/" + theComputer + "/SuperVisionContainer")
564
565     end_time = os.times()
566     print
567     print "Start SALOME, elapsed time : %5.1f seconds"% (end_time[4]
568                                                          - init_time[4])
569
570     return clt
571
572 # -----------------------------------------------------------------------------
573
574 def useSalome(args, modules_list, modules_root_dir):
575     """
576     Launch all SALOME servers requested by args,
577     save list of process, give info to user,
578     show registered objects in Naming Service.
579     """
580     
581     clt=None
582     try:
583         clt = startSalome(args, modules_list, modules_root_dir)
584     except:
585         print
586         print
587         print "--- erreur au lancement Salome ---"
588         
589     #print process_id
590     
591     filedict = '/tmp/' + os.getenv('USER') + "_" + str(args['port']) \
592              + '_' + args['appname'].upper() + '_pidict'
593    
594     process_ids = []
595     try:
596         fpid=open(filedict, 'r')
597         process_ids=pickle.load(fpid)
598         fpid.close()
599     except:
600         pass
601     
602     fpid=open(filedict, 'w')
603     process_ids.append(process_id)
604     pickle.dump(process_ids,fpid)
605     fpid.close()
606     
607     print """
608     Saving of the dictionary of Salome processes in %s
609     To kill SALOME processes from a console (kill all sessions from all ports):
610       python killSalome.py 
611     To kill SALOME from the present interpreter, if it is not closed :
612       killLocalPort()      --> kill this session
613                                (use CORBA port from args of runSalome)
614       givenPortKill(port)  --> kill a specific session with given CORBA port 
615       killAllPorts()       --> kill all sessions
616     
617     runSalome, with --killall option, starts with killing
618     the processes resulting from the previous execution.
619     """%filedict
620     
621     #
622     #  Impression arborescence Naming Service
623     #
624     
625     if clt != None:
626         print
627         print " --- registered objects tree in Naming Service ---"
628         clt.showNS()
629
630     return clt
631
632 # -----------------------------------------------------------------------------
633
634 def registerEnv(args, modules_list, modules_root_dir):
635     """
636     Register args, modules_list, modules_root_dir in a file
637     for further use, when SALOME is launched embedded in an other application.
638     """
639     fileEnv = '/tmp/' + os.getenv('USER') + "_" + str(args['port']) \
640             + '_' + args['appname'].upper() + '_env'
641     fenv=open(fileEnv,'w')
642     pickle.dump((args, modules_list, modules_root_dir),fenv)
643     fenv.close()
644     os.environ["SALOME_LAUNCH_CONFIG"] = fileEnv
645
646 # -----------------------------------------------------------------------------
647
648 def no_main():
649     """Salome Launch, when embedded in other application"""
650     fileEnv = os.environ["SALOME_LAUNCH_CONFIG"]
651     fenv=open(fileEnv,'r')
652     args, modules_list, modules_root_dir = pickle.load(fenv)
653     fenv.close()
654     kill_salome(args)
655     clt = useSalome(args, modules_list, modules_root_dir)
656     return clt
657
658 # -----------------------------------------------------------------------------
659
660 def main():
661     """Salome launch as a main application"""
662     args, modules_list, modules_root_dir = get_config()
663     kill_salome(args)
664     set_env(args, modules_list, modules_root_dir)
665     clt = useSalome(args, modules_list, modules_root_dir)
666     return clt,args
667
668 # -----------------------------------------------------------------------------
669
670 if __name__ == "__main__":
671    clt,args = main()