]> SALOME platform Git repositories - modules/kernel.git/blob - bin/runSalome.py
Salome HOME
Management of :
[modules/kernel.git] / bin / runSalome.py
1 #!/usr/bin/env python3
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2022 CEA/DEN, EDF R&D
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21
22 ## @package runSalome
23 # \brief Module that provides services to launch SALOME
24 #
25
26 import sys, os, string, glob, time, pickle, re
27 import orbmodule
28 import setenv
29 from server import process_id, Server
30 import json
31 import subprocess
32 from salomeContextUtils import ScriptAndArgsObjectEncoder
33 import runSalomeNoServer
34 import runSalomeCommon
35 import platform
36 import logging
37 logger = logging.getLogger()
38
39 # -----------------------------------------------------------------------------
40
41 from killSalome import killAllPorts
42
43 def kill_salome(args):
44     """
45     Kill servers from previous SALOME executions, if needed;
46     depending on args 'killall' or 'portkill', kill all executions,
47     or only execution on the same CORBA port
48     """
49
50     if args['killall']:
51         killAllPorts()
52 #
53 # -----------------------------------------------------------------------------
54
55 def startGUI(clt):
56     """Salome Session Graphic User Interface activation"""
57     import Engines
58     import SALOME
59     import SALOMEDS
60     import SALOME_ModuleCatalog
61     import SALOME_Session_idl
62     session=clt.waitNS("/Kernel/Session",SALOME.Session)
63     session.GetInterface()
64
65 # -----------------------------------------------------------------------------
66
67 def startSalome(args, modules_list, modules_root_dir):
68     """Launch all SALOME servers requested by args"""
69     init_time = os.times()
70
71     logger.debug("startSalome : {} ".format(args))
72
73     ior_fakens_filename = None
74
75     # Launch  Session Server (to show splash ASAP)
76     #
77
78     if args["gui"] and not args['launcher_only']:
79         mySessionServ = runSalomeNoServer.NoSessionServer(args,args['modules'],modules_root_dir)
80         mySessionServ.setpath(modules_list,modules_root_dir)
81         mySessionServ.run()
82         ior_fakens_filename = mySessionServ.iorfakens
83         logger.debug("Rendez-vous file for to retrieve IOR of session is \"{}\"".format(ior_fakens_filename))
84     
85     end_time = os.times()
86
87     #
88     # Wait until Session Server is registered in naming service
89     #
90     logger.debug("Start SALOME, elapsed time : %5.1f seconds"% (end_time[4] - init_time[4]))
91
92     #
93     # additional external python interpreters
94     #
95     nbaddi=0
96
97     try:
98         if 'interp' in args:
99             nbaddi = args['interp']
100     except Exception:
101         import traceback
102         traceback.print_exc()
103         logger.error("-------------------------------------------------------------")
104         logger.error("-- to get an external python interpreter:runSalome --interp=1")
105         logger.error("-------------------------------------------------------------")
106
107     logger.debug("additional external python interpreters: {}".format(nbaddi))
108     if nbaddi:
109         for i in range(nbaddi):
110             anInterp=runSalomeCommon.InterpServer(args)
111             anInterp.run()
112
113     # set PYTHONINSPECT variable (python interpreter in interactive mode)
114     if args['pinter']:
115         os.environ["PYTHONINSPECT"]="1"
116         try:
117             import readline
118         except ImportError:
119             pass
120
121     return ior_fakens_filename
122
123 # -----------------------------------------------------------------------------
124
125 def useSalome(args, modules_list, modules_root_dir):
126     """
127     Launch all SALOME servers requested by args,
128     save list of process, give info to user,
129     show registered objects in Naming Service.
130     """
131     global process_id
132     ior_fakens_filename = None
133     try:
134         ior_fakens_filename = startSalome(args, modules_list, modules_root_dir)
135     except Exception:
136         import traceback
137         traceback.print_exc()
138         logger.error("--- Error during Salome launch ---")
139
140     # print(process_id)
141
142     from addToKillList import addToKillList
143     from killSalomeWithPort import getPiDict
144
145     filedict = getPiDict(args['port'])
146     for pid, cmd in list(process_id.items()):
147         addToKillList(pid, cmd, args['port'])
148         pass
149
150     logger.debug("""
151     Saving of the dictionary of Salome processes in %s
152     To kill SALOME processes from a console (kill all sessions from all ports):
153       python killSalome.py
154     To kill SALOME from the present interpreter, if it is not closed :
155       killLocalPort()      --> kill this session
156                                (use CORBA port from args of runSalome)
157       givenPortKill(port)  --> kill a specific session with given CORBA port
158       killAllPorts()       --> kill all sessions
159
160     runSalome, with --killall option, starts with killing
161     the processes resulting from the previous execution.
162     """%filedict)
163
164     return ior_fakens_filename
165
166 def execScript(script_path):
167     print('executing', script_path)
168     sys.path.insert(0, os.path.realpath(os.path.dirname(script_path)))
169     exec(compile(open(script_path).read(), script_path, 'exec'),globals())
170     del sys.path[0]
171
172 # -----------------------------------------------------------------------------
173
174 def addToPidict(args):
175     global process_id
176     from addToKillList import addToKillList
177     for pid, cmd in list(process_id.items()):
178         addToKillList(pid, cmd)
179
180 # -----------------------------------------------------------------------------
181
182 def main(exeName=None):
183     """Salome launch as a main application"""
184     keep_env = not os.getenv('SALOME_PLEASE_SETUP_ENVIRONMENT_AS_BEFORE')
185     args, modules_list, modules_root_dir = setenv.get_config(exeName=exeName, keepEnvironment=keep_env)
186     runSalomeCommon.setVerbose(args["verbosity"])
187     kill_salome(args)
188     # --
189     setenv.set_env(args, modules_list, modules_root_dir, keepEnvironment=keep_env)
190     ior_fakens_filename = useSalome(args, modules_list, modules_root_dir)
191     # Management of -t <script.py>
192     toimport = []
193     if 'gui' in args and 'session_gui' in args:
194         if not args['gui'] or not args['session_gui']:
195             if 'study_hdf' in args:
196                 toopen = args['study_hdf']
197                 if toopen:
198                     import salome
199                     salome.salome_init(path=toopen)
200             if 'pyscript' in args:
201                 toimport = args['pyscript']
202     from salomeContextUtils import formatScriptsAndArgs
203     from addToKillList import addToKillList
204     command = formatScriptsAndArgs(toimport, escapeSpaces=True)
205     if command:
206         logger.debug("Launching following shell command : {}".format(str(command)))
207         proc = subprocess.Popen(command, shell=True)
208         addToKillList(proc.pid, command)
209         res = proc.wait()
210         if res: sys.exit(1) 
211     return args, ior_fakens_filename
212
213 # -----------------------------------------------------------------------------
214
215 def foreGround(args, ior_fakens_filename):
216     # --
217     import os
218     gui_detected = False
219     dt = 0.1
220     nbtot = 100
221     nb = 0
222     if ior_fakens_filename is None:
223         logger.warn("No file set to host IOR of the fake naming server")
224         return
225     if not os.path.exists(ior_fakens_filename):
226         logger.warn("No file {} set to host IOR of the fake naming server does not exit !")
227         return
228     import CORBA
229     import Engines
230     import SALOME
231     from time import sleep
232     orb = CORBA.ORB_init([''], CORBA.ORB_ID)
233     ior_fakens = None
234     session = None
235     while True:
236         try:
237             ior_fakens = orb.string_to_object(open(ior_fakens_filename).read())
238             session = orb.string_to_object(ior_fakens.Resolve("/Kernel/Session").decode())
239         except Exception:
240             pass
241         if ( session is not None ) and (not CORBA.is_nil(session)):
242             try:
243                 os.remove(ior_fakens_filename)
244                 logger.debug("File {} has been removed".format(ior_fakens_filename))
245             except:
246                 pass
247             logger.debug("Session in child process has been found ! yeah ! {}".format(str(session)))
248             break
249         sleep(dt)
250         nb += 1
251         logger.debug("Unfortunately Session not found into {} : Sleep and retry. {}/{}".format(ior_fakens_filename,nb,nbtot))
252         if nb == nbtot:
253             break
254     nb = 0
255     # --
256     # Wait until gui is arrived
257     # tmax = nbtot * dt
258     # --
259     session_pid = None
260     while 1:
261         try:
262             status = session.GetStatSession()
263             gui_detected = status.activeGUI
264             session_pid = session.getPID()
265             logger.debug("Process of the session under monitoring {}".format(session_pid))
266         except Exception:
267             pass
268         if gui_detected:
269             break
270         sleep(dt)
271         nb += 1
272         if nb == nbtot:
273             break
274         pass
275     # --
276     if not gui_detected:
277         return
278     # --
279     from salome_utils import getPortNumber
280     port = getPortNumber()
281     # --
282     server = Server({})
283     if sys.platform == "win32":
284       server.CMD = [os.getenv("PYTHONBIN"), "-m", "killSalomeWithPort", "--spy", "%s"%(session_pid or os.getpid()), "%s"%(port)]
285     else:
286       server.CMD = ["killSalomeWithPort.py", "--spy", "%s"%(session_pid or os.getpid()), "%s"%(port)]
287     server.run(True)
288     # os.system("killSalomeWithPort.py --spy %s %s &"%(os.getpid(), port))
289     # --
290     dt = 1.0
291     try:
292         while 1:
293             try:
294                 status = session.GetStatSession()
295                 assert status.activeGUI
296             except Exception:
297                 logger.debug("Process of the session under monitoring {} has vanished !".format(session_pid))
298                 break
299             from time import sleep
300             sleep(dt)
301             pass
302         pass
303     except KeyboardInterrupt:
304         logger.debug("Keyboard requested : killing all process attached to port {}".format(port))
305         from killSalomeWithPort import killMyPortSSL
306         killMyPortSSL(port)
307         pass
308     return
309 #
310
311 def runSalome():
312     args, ior_fakens_filename = main()
313     # --
314     test = args['gui'] and args['session_gui']
315     test = test or args['wake_up_session']
316     # --
317     # The next test covers the --pinter option or if var PYTHONINSPECT is set
318     # --
319     test = test and not os.environ.get('PYTHONINSPECT')
320     # --
321     # The next test covers the python -i $KERNEL_ROOT_DIR/bin/salome/runSalome.py case
322     # --
323     try:
324         from ctypes import POINTER, c_int, cast, pythonapi
325         iflag_ptr = cast(pythonapi.Py_InteractiveFlag, POINTER(c_int))
326         test = test and not iflag_ptr.contents.value
327     except Exception:
328         pass
329     # --
330 #    test = test and os.getenv("SALOME_TEST_MODE", "0") != "1"
331     test = test and args['foreground']
332     # --
333     if test:
334         from time import sleep
335         sleep(3.0)
336         foreGround(args, ior_fakens_filename)
337         pass
338     pass
339 #
340
341 # -----------------------------------------------------------------------------
342
343 if __name__ == "__main__":
344     runSalome()
345 #