Salome HOME
7bce8f5023176fb621ca8e8b36c200c51d3e9c84
[modules/kernel.git] / bin / runSalomeOld.py
1 #!/usr/bin/env python3
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
4 #
5 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 #
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21 #
22 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #
24
25 ## @package runSalome
26 # \brief Module that provides services to launch SALOME
27 #
28
29 import sys, os, string, glob, time, pickle, re
30 import orbmodule
31 import setenv
32 from launchConfigureParser import verbose
33 from server import process_id, Server
34 import json
35 import subprocess
36 from salomeContextUtils import ScriptAndArgsObjectEncoder
37 import platform
38 from runSalomeCommon import setVerbose, InterpServer, CatalogServer, SalomeDSServer, ConnectionManagerServer, RegistryServer, ContainerCPPServer, LoggerServer, CommonSessionServer, SessionServer, LauncherServer
39 # -----------------------------------------------------------------------------
40
41 from killSalome import killAllPorts
42
43 def killLocalPort():
44     """
45     kill servers from a previous SALOME execution, if needed,
46     on the CORBA port given in args of runSalome
47     """
48
49     from killSalomeWithPort import killMyPort
50     my_port=str(args['port'])
51     try:
52         killMyPort(my_port)
53     except Exception:
54         print("problem in killLocalPort()")
55         pass
56     pass
57
58 def givenPortKill(port):
59     """
60     kill servers from a previous SALOME execution, if needed,
61     on the same CORBA port
62     """
63
64     from killSalomeWithPort import killMyPort
65     my_port=port
66     try:
67         killMyPort(my_port)
68     except Exception:
69         print("problem in LocalPortKill(), killMyPort(%s)"%port)
70         pass
71     pass
72
73 def kill_salome(args):
74     """
75     Kill servers from previous SALOME executions, if needed;
76     depending on args 'killall' or 'portkill', kill all executions,
77     or only execution on the same CORBA port
78     """
79
80     if args['killall']:
81         killAllPorts()
82     elif args['portkill']:
83         givenPortKill(str(args['port']))
84
85 def startGUI(clt):
86     """Salome Session Graphic User Interface activation"""
87     import Engines
88     import SALOME
89     import SALOMEDS
90     import SALOME_ModuleCatalog
91     import SALOME_Session_idl
92     session=clt.waitNS("/Kernel/Session",SALOME.Session)
93     session.GetInterface()
94
95 # -----------------------------------------------------------------------------
96
97 def startSalome(args, modules_list, modules_root_dir):
98     """Launch all SALOME servers requested by args"""
99     init_time = os.times()
100
101     if verbose(): print("startSalome ", args)
102
103     #
104     # Set server launch command
105     #
106     if 'server_launch_mode' in args:
107         Server.set_server_launch_mode(args['server_launch_mode'])
108
109     #
110     # Wake up session option
111     #
112     if args['wake_up_session']:
113         if "OMNIORB_CONFIG" not in os.environ:
114             from salome_utils import generateFileName
115             omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
116             kwargs={}
117             if omniorbUserPath is not None:
118                 kwargs["with_username"]=True
119
120             last_running_config = generateFileName(omniorbUserPath, prefix="omniORB",
121                                                    suffix="last",
122                                                    extension="cfg",
123                                                    hidden=True,
124                                                    **kwargs)
125             os.environ['OMNIORB_CONFIG'] = last_running_config
126             pass
127         pass
128
129     #
130     # Initialisation ORB and Naming Service
131     #
132
133     clt=orbmodule.client(args)
134     addToPidict(args)
135
136     #
137     # Wake up session option
138     #
139     if args['wake_up_session']:
140         import Engines
141         import SALOME
142         import SALOMEDS
143         import SALOME_ModuleCatalog
144         import SALOME_Session_idl
145         session = clt.waitNS("/Kernel/Session",SALOME.Session)
146         status = session.GetStatSession()
147         if status.activeGUI:
148             from salome_utils import getPortNumber
149             port = getPortNumber()
150             msg  = "Warning :"
151             msg += "\n"
152             msg += "Session GUI for port number %s is already active."%(port)
153             msg += "\n"
154             msg += "If you which to wake up another session,"
155             msg += "\n"
156             msg += "please use variable OMNIORB_CONFIG"
157             msg += "\n"
158             msg += "to get the correct session object in naming service."
159             sys.stdout.write(msg+"\n")
160             sys.stdout.flush()
161             return clt
162         session.GetInterface()
163         args["session_object"] = session
164         return clt
165
166     # Launch Logger Server (optional)
167     # and wait until it is registered in naming service
168     #
169
170     if args['logger']:
171         myServer=LoggerServer(args)
172         myServer.run()
173         clt.waitLogger("Logger")
174         addToPidict(args)
175
176     # Launch  Session Server (to show splash ASAP)
177     #
178
179     if args["gui"] and not args['launcher_only']:
180         mySessionServ = SessionServer(args,args['modules'],modules_root_dir)
181         mySessionServ.setpath(modules_list,modules_root_dir)
182         mySessionServ.run()
183         addToPidict(args)
184
185     #
186     # Launch Registry Server,
187     # and wait until it is registered in naming service
188     #
189
190     if ('registry' not in args['embedded']) | (args["gui"] == 0) :
191         myServer=RegistryServer(args)
192         myServer.run()
193         if sys.platform == "win32":
194           clt.waitNS("/Registry")
195         else:
196           clt.waitNSPID("/Registry",myServer.PID)
197         addToPidict(args)
198
199     #
200     # Launch Catalog Server,
201     # and wait until it is registered in naming service
202     #
203
204     if ('moduleCatalog' not in args['embedded']) | (args["gui"] == 0):
205         cataServer=CatalogServer(args)
206         cataServer.setpath(modules_list,modules_root_dir)
207         cataServer.run()
208         import SALOME_ModuleCatalog
209         if sys.platform == "win32":
210           clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog)
211         else:
212           clt.waitNSPID("/Kernel/ModulCatalog",cataServer.PID,SALOME_ModuleCatalog.ModuleCatalog)
213         addToPidict(args)
214
215     #
216     # Launch SalomeDS Server,
217     # and wait until it is registered in naming service
218     #
219
220     # print("ARGS = ",args)
221     if ('study' not in args['embedded']) | (args["gui"] == 0):
222         print("RunStudy")
223         myServer=SalomeDSServer(args)
224         myServer.run()
225         if sys.platform == "win32":
226           clt.waitNS("/Study")
227         else:
228           clt.waitNSPID("/Study",myServer.PID)
229         addToPidict(args)
230
231     #
232     # Launch LauncherServer
233     #
234
235     if not 'launcher' in args:
236       myCmServer = LauncherServer(args)
237       myCmServer.setpath(modules_list,modules_root_dir)
238       myCmServer.run()
239       addToPidict(args)
240
241     #
242     # Launch ConnectionManagerServer
243     #
244
245     if not args['launcher_only']:
246       myConnectionServer = ConnectionManagerServer(args)
247       myConnectionServer.run()
248
249     from Utils_Identity import getShortHostName
250
251     if os.getenv("HOSTNAME") == None:
252         if os.getenv("HOST") == None:
253             os.environ["HOSTNAME"]=getShortHostName()
254         else:
255             os.environ["HOSTNAME"]=os.getenv("HOST")
256
257     theComputer = getShortHostName()
258
259     #
260     # Launch local C++ Container (FactoryServer),
261     # and wait until it is registered in naming service
262     #
263
264     if ('cppContainer' in args['standalone']) | (args["gui"] == 0) :
265         myServer=ContainerCPPServer(args, with_gui=args["gui"]!=0)
266         myServer.run()
267         if sys.platform == "win32":
268           clt.waitNS("/Containers/" + theComputer + "/FactoryServer")
269         else:
270           clt.waitNSPID("/Containers/" + theComputer + "/FactoryServer",myServer.PID)
271         addToPidict(args)
272
273     if 'pyContainer' in args['standalone']:
274         raise Exception('Python containers no longer supported')
275
276     #
277     # Wait until Session Server is registered in naming service
278     #
279
280     if args["gui"] and not args['launcher_only']:
281 ##----------------
282         import Engines
283         import SALOME
284         import SALOMEDS
285         import SALOME_ModuleCatalog
286         import SALOME_Session_idl
287         if sys.platform == "win32":
288           session=clt.waitNS("/Kernel/Session",SALOME.Session)
289         else:
290           session=clt.waitNSPID("/Kernel/Session",mySessionServ.PID,SALOME.Session)
291         args["session_object"] = session
292     end_time = os.times()
293     if verbose(): print()
294     print("Start SALOME, elapsed time : %5.1f seconds"% (end_time[4]
295                                                          - init_time[4]))
296
297     # ASV start GUI without Loader
298     #if args['gui']:
299     #    session.GetInterface()
300
301     #
302     # additional external python interpreters
303     #
304     nbaddi=0
305
306     try:
307         if 'interp' in args:
308             nbaddi = args['interp']
309     except Exception:
310         import traceback
311         traceback.print_exc()
312         print("-------------------------------------------------------------")
313         print("-- to get an external python interpreter:runSalome --interp=1")
314         print("-------------------------------------------------------------")
315
316     if verbose(): print("additional external python interpreters: ", nbaddi)
317     if nbaddi:
318         for i in range(nbaddi):
319             print("i=",i)
320             anInterp=InterpServer(args)
321             anInterp.run()
322
323     # set PYTHONINSPECT variable (python interpreter in interactive mode)
324     if args['pinter']:
325         os.environ["PYTHONINSPECT"]="1"
326         try:
327             import readline
328         except ImportError:
329             pass
330
331     return clt
332
333 # -----------------------------------------------------------------------------
334
335 def useSalome(args, modules_list, modules_root_dir):
336     """
337     Launch all SALOME servers requested by args,
338     save list of process, give info to user,
339     show registered objects in Naming Service.
340     """
341     global process_id
342
343     clt=None
344     try:
345         clt = startSalome(args, modules_list, modules_root_dir)
346     except Exception:
347         import traceback
348         traceback.print_exc()
349         print()
350         print()
351         print("--- Error during Salome launch ---")
352
353     # print(process_id)
354
355     from addToKillList import addToKillList
356     from killSalomeWithPort import getPiDict
357
358     filedict = getPiDict(args['port'])
359     for pid, cmd in list(process_id.items()):
360         addToKillList(pid, cmd, args['port'])
361         pass
362
363     if verbose(): print("""
364     Saving of the dictionary of Salome processes in %s
365     To kill SALOME processes from a console (kill all sessions from all ports):
366       python killSalome.py
367     To kill SALOME from the present interpreter, if it is not closed :
368       killLocalPort()      --> kill this session
369                                (use CORBA port from args of runSalome)
370       givenPortKill(port)  --> kill a specific session with given CORBA port
371       killAllPorts()       --> kill all sessions
372
373     runSalome, with --killall option, starts with killing
374     the processes resulting from the previous execution.
375     """%filedict)
376
377     #
378     #  Print Naming Service directory list
379     #
380
381     if clt != None:
382         if verbose():
383             print()
384             print(" --- registered objects tree in Naming Service ---")
385             clt.showNS()
386             pass
387
388         if not args['gui'] or not args['session_gui']:
389             if args['shutdown_servers']:
390                 class __utils__:
391                     def __init__(self, port):
392                         self.port = port
393                         import killSalomeWithPort
394                         self.killSalomeWithPort = killSalomeWithPort
395                         return
396                     def __del__(self):
397                         self.killSalomeWithPort.killMyPort(self.port)
398                         return
399                     pass
400                 def func(s):
401                     del s
402                 import atexit
403                 atexit.register(func, __utils__(args['port']))
404                 pass
405             pass
406
407         # run python scripts, passed as command line arguments
408         toimport = []
409         if 'gui' in args and 'session_gui' in args:
410             if not args['gui'] or not args['session_gui']:
411                 if 'study_hdf' in args:
412                     toopen = args['study_hdf']
413                     if toopen:
414                         import salome
415                         salome.salome_init_with_session(path=toopen)
416                 if 'pyscript' in args:
417                     toimport = args['pyscript']
418         from salomeContextUtils import formatScriptsAndArgs
419         command = formatScriptsAndArgs(toimport, escapeSpaces=True)
420         if command:
421             proc = subprocess.Popen(command, shell=True)
422             addToKillList(proc.pid, command, args['port'])
423             res = proc.wait()
424             if res: sys.exit(1) # if there's an error when executing script, we should explicitly exit
425
426     return clt
427
428 def execScript(script_path):
429     print('executing', script_path)
430     sys.path.insert(0, os.path.realpath(os.path.dirname(script_path)))
431     exec(compile(open(script_path).read(), script_path, 'exec'),globals())
432     del sys.path[0]
433
434 # -----------------------------------------------------------------------------
435
436 def registerEnv(args, modules_list, modules_root_dir):
437     """
438     Register args, modules_list, modules_root_dir in a file
439     for further use, when SALOME is launched embedded in an other application.
440     """
441     from salome_utils import getTmpDir
442     fileEnv = getTmpDir()
443     from salome_utils import getUserName
444     fileEnv += getUserName() + "_" + str(args['port']) \
445             + '_' + args['appname'].upper() + '_env'
446     fenv=open(fileEnv,'w')
447     pickle.dump((args, modules_list, modules_root_dir),fenv)
448     fenv.close()
449     os.environ["SALOME_LAUNCH_CONFIG"] = fileEnv
450
451 # -----------------------------------------------------------------------------
452
453 def no_main():
454     """Salome Launch, when embedded in other application"""
455     fileEnv = os.environ["SALOME_LAUNCH_CONFIG"]
456     fenv=open(fileEnv,'r')
457     args, modules_list, modules_root_dir = pickle.load(fenv)
458     fenv.close()
459     kill_salome(args)
460     from searchFreePort import searchFreePort
461     searchFreePort(args, 0)
462     clt = useSalome(args, modules_list, modules_root_dir)
463     return clt
464
465 # -----------------------------------------------------------------------------
466
467 def addToPidict(args):
468     global process_id
469     from addToKillList import addToKillList
470     for pid, cmd in list(process_id.items()):
471         addToKillList(pid, cmd, args['port'])
472
473 # -----------------------------------------------------------------------------
474
475 def main(exeName=None):
476     """Salome launch as a main application"""
477
478     # define folder to store omniorb config (initially in virtual application folder)
479     try:
480         from salomeContextUtils import setOmniOrbUserPath
481         setOmniOrbUserPath()
482     except Exception as e:
483         print(e)
484         sys.exit(1)
485
486     from salome_utils import getHostName
487     keep_env = not os.getenv('SALOME_PLEASE_SETUP_ENVIRONMENT_AS_BEFORE')
488     args, modules_list, modules_root_dir = setenv.get_config(exeName=exeName, keepEnvironment=keep_env)
489     print("runSalome running on %s" % getHostName())
490
491     kill_salome(args)
492     save_config = True
493     if 'save_config' in args:
494         save_config = args['save_config']
495     # --
496     test = True
497     if args['wake_up_session']:
498         test = False
499         pass
500     if test and not 'launcher' in args:
501         from searchFreePort import searchFreePort
502         searchFreePort(args, save_config, args.get('useport'))
503         pass
504     # --
505     #setenv.main()
506     setenv.set_env(args, modules_list, modules_root_dir, keepEnvironment=keep_env)
507     clt = useSalome(args, modules_list, modules_root_dir)
508     return clt,args
509
510 # -----------------------------------------------------------------------------
511
512 def foreGround(clt, args):
513     # --
514     if "session_object" not in args:
515         return
516     session = args["session_object"]
517     # --
518     # Wait until gui is arrived
519     # tmax = nbtot * dt
520     # --
521     gui_detected = False
522     dt = 0.1
523     nbtot = 100
524     nb = 0
525     session_pid = None
526     while 1:
527         try:
528             status = session.GetStatSession()
529             gui_detected = status.activeGUI
530             session_pid = session.getPID()
531         except Exception:
532             pass
533         if gui_detected:
534             break
535         from time import sleep
536         sleep(dt)
537         nb += 1
538         if nb == nbtot:
539             break
540         pass
541     # --
542     if not gui_detected:
543         return
544     # --
545     from salome_utils import getPortNumber
546     port = getPortNumber()
547     # --
548     server = Server({})
549     if sys.platform == "win32":
550       server.CMD = [os.getenv("PYTHONBIN"), "-m", "killSalomeWithPort", "--spy", "%s"%(session_pid or os.getpid()), "%s"%(port)]
551     else:
552       server.CMD = ["killSalomeWithPort.py", "--spy", "%s"%(session_pid or os.getpid()), "%s"%(port)]
553     server.run(True)
554     # os.system("killSalomeWithPort.py --spy %s %s &"%(os.getpid(), port))
555     # --
556     dt = 1.0
557     try:
558         while 1:
559             try:
560                 status = session.GetStatSession()
561                 assert status.activeGUI
562             except Exception:
563                 break
564             from time import sleep
565             sleep(dt)
566             pass
567         pass
568     except KeyboardInterrupt:
569         from killSalomeWithPort import killMyPort
570         killMyPort(port)
571         pass
572     return
573 #
574
575 def runSalome():
576     clt,args = main()
577     # --
578     test = args['gui'] and args['session_gui']
579     test = test or args['wake_up_session']
580     # --
581     # The next test covers the --pinter option or if var PYTHONINSPECT is set
582     # --
583     test = test and not os.environ.get('PYTHONINSPECT')
584     # --
585     # The next test covers the python -i $KERNEL_ROOT_DIR/bin/salome/runSalome.py case
586     # --
587     try:
588         from ctypes import POINTER, c_int, cast, pythonapi
589         iflag_ptr = cast(pythonapi.Py_InteractiveFlag, POINTER(c_int))
590         test = test and not iflag_ptr.contents.value
591     except Exception:
592         pass
593     # --
594 #    test = test and os.getenv("SALOME_TEST_MODE", "0") != "1"
595     test = test and args['foreground']
596     # --
597     if test:
598         from time import sleep
599         sleep(3.0)
600         foreGround(clt, args)
601         pass
602     pass
603 #
604
605 # -----------------------------------------------------------------------------
606
607 if __name__ == "__main__":
608     runSalome()
609 #