Salome HOME
Fix runSalome.py --logger
[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     
84     end_time = os.times()
85
86     #
87     # Wait until Session Server is registered in naming service
88     #
89     logger.debug("Start SALOME, elapsed time : %5.1f seconds"% (end_time[4] - init_time[4]))
90
91     #
92     # additional external python interpreters
93     #
94     nbaddi=0
95
96     try:
97         if 'interp' in args:
98             nbaddi = args['interp']
99     except Exception:
100         import traceback
101         traceback.print_exc()
102         logger.error("-------------------------------------------------------------")
103         logger.error("-- to get an external python interpreter:runSalome --interp=1")
104         logger.error("-------------------------------------------------------------")
105
106     logger.debug("additional external python interpreters: {}".format(nbaddi))
107     if nbaddi:
108         for i in range(nbaddi):
109             anInterp=InterpServer(args)
110             anInterp.run()
111
112     # set PYTHONINSPECT variable (python interpreter in interactive mode)
113     if args['pinter']:
114         os.environ["PYTHONINSPECT"]="1"
115         try:
116             import readline
117         except ImportError:
118             pass
119
120     return ior_fakens_filename
121
122 # -----------------------------------------------------------------------------
123
124 def useSalome(args, modules_list, modules_root_dir):
125     """
126     Launch all SALOME servers requested by args,
127     save list of process, give info to user,
128     show registered objects in Naming Service.
129     """
130     global process_id
131     ior_fakens_filename = None
132     try:
133         ior_fakens_filename = startSalome(args, modules_list, modules_root_dir)
134     except Exception:
135         import traceback
136         traceback.print_exc()
137         logger.error("--- Error during Salome launch ---")
138
139     # print(process_id)
140
141     from addToKillList import addToKillList
142     from killSalomeWithPort import getPiDict
143
144     filedict = getPiDict(args['port'])
145     for pid, cmd in list(process_id.items()):
146         addToKillList(pid, cmd, args['port'])
147         pass
148
149     logger.debug("""
150     Saving of the dictionary of Salome processes in %s
151     To kill SALOME processes from a console (kill all sessions from all ports):
152       python killSalome.py
153     To kill SALOME from the present interpreter, if it is not closed :
154       killLocalPort()      --> kill this session
155                                (use CORBA port from args of runSalome)
156       givenPortKill(port)  --> kill a specific session with given CORBA port
157       killAllPorts()       --> kill all sessions
158
159     runSalome, with --killall option, starts with killing
160     the processes resulting from the previous execution.
161     """%filedict)
162
163     return ior_fakens_filename
164
165 def execScript(script_path):
166     print('executing', script_path)
167     sys.path.insert(0, os.path.realpath(os.path.dirname(script_path)))
168     exec(compile(open(script_path).read(), script_path, 'exec'),globals())
169     del sys.path[0]
170
171 # -----------------------------------------------------------------------------
172
173 def addToPidict(args):
174     global process_id
175     from addToKillList import addToKillList
176     for pid, cmd in list(process_id.items()):
177         addToKillList(pid, cmd, args['port'])
178
179 # -----------------------------------------------------------------------------
180
181 def main(exeName=None):
182     """Salome launch as a main application"""
183     keep_env = not os.getenv('SALOME_PLEASE_SETUP_ENVIRONMENT_AS_BEFORE')
184     args, modules_list, modules_root_dir = setenv.get_config(exeName=exeName, keepEnvironment=keep_env)
185     runSalomeCommon.setVerbose(args["verbosity"])
186     kill_salome(args)
187     # --
188     setenv.set_env(args, modules_list, modules_root_dir, keepEnvironment=keep_env)
189     ior_fakens_filename = useSalome(args, modules_list, modules_root_dir)
190     return args, ior_fakens_filename
191
192 # -----------------------------------------------------------------------------
193
194 def foreGround(args, ior_fakens_filename):
195     # --
196     import os
197     gui_detected = False
198     dt = 0.1
199     nbtot = 100
200     nb = 0
201     if ior_fakens_filename is None:
202         logger.warn("No file set to host IOR of the fake naming server")
203         return
204     if not os.path.exists(ior_fakens_filename):
205         logger.warn("No file {} set to host IOR of the fake naming server does not exit !")
206         return
207     import CORBA
208     import Engines
209     import SALOME
210     from time import sleep
211     orb = CORBA.ORB_init([''], CORBA.ORB_ID)
212     ior_fakens = None
213     session = None
214     while True:
215         try:
216             ior_fakens = orb.string_to_object(open(ior_fakens_filename).read())
217             session = orb.string_to_object(ior_fakens.Resolve("/Kernel/Session").decode())
218         except Exception:
219             pass
220         if ( session is not None ) and (not CORBA.is_nil(session)):
221             try:
222                 os.remove(ior_fakens_filename)
223                 logger.debug("File {} has been removed".format(ior_fakens_filename))
224             except:
225                 pass
226             logger.debug("Session in child process has been found ! yeah ! {}".format(str(session)))
227             break
228         sleep(dt)
229         nb += 1
230         logger.debug("Unfortunately Session not found into {} : Sleep and retry. {}/{}".format(ior_fakens_filename,nb,nbtot))
231         if nb == nbtot:
232             break
233     nb = 0
234     # --
235     # Wait until gui is arrived
236     # tmax = nbtot * dt
237     # --
238     session_pid = None
239     while 1:
240         try:
241             status = session.GetStatSession()
242             gui_detected = status.activeGUI
243             session_pid = session.getPID()
244             logger.debug("Process of the session under monitoring {}".format(session_pid))
245         except Exception:
246             pass
247         if gui_detected:
248             break
249         sleep(dt)
250         nb += 1
251         if nb == nbtot:
252             break
253         pass
254     # --
255     if not gui_detected:
256         return
257     # --
258     from salome_utils import getPortNumber
259     port = getPortNumber()
260     # --
261     server = Server({})
262     if sys.platform == "win32":
263       server.CMD = [os.getenv("PYTHONBIN"), "-m", "killSalomeWithPort", "--spy", "%s"%(session_pid or os.getpid()), "%s"%(port)]
264     else:
265       server.CMD = ["killSalomeWithPort.py", "--spy", "%s"%(session_pid or os.getpid()), "%s"%(port)]
266     server.run(True)
267     # os.system("killSalomeWithPort.py --spy %s %s &"%(os.getpid(), port))
268     # --
269     dt = 1.0
270     try:
271         while 1:
272             try:
273                 status = session.GetStatSession()
274                 assert status.activeGUI
275             except Exception:
276                 break
277             from time import sleep
278             sleep(dt)
279             pass
280         pass
281     except KeyboardInterrupt:
282         from killSalomeWithPort import killMyPortSSL
283         killMyPortSSL(port)
284         pass
285     return
286 #
287
288 def runSalome():
289     args, ior_fakens_filename = main()
290     # --
291     test = args['gui'] and args['session_gui']
292     test = test or args['wake_up_session']
293     # --
294     # The next test covers the --pinter option or if var PYTHONINSPECT is set
295     # --
296     test = test and not os.environ.get('PYTHONINSPECT')
297     # --
298     # The next test covers the python -i $KERNEL_ROOT_DIR/bin/salome/runSalome.py case
299     # --
300     try:
301         from ctypes import POINTER, c_int, cast, pythonapi
302         iflag_ptr = cast(pythonapi.Py_InteractiveFlag, POINTER(c_int))
303         test = test and not iflag_ptr.contents.value
304     except Exception:
305         pass
306     # --
307 #    test = test and os.getenv("SALOME_TEST_MODE", "0") != "1"
308     test = test and args['foreground']
309     # --
310     if test:
311         from time import sleep
312         sleep(3.0)
313         foreGround(args, ior_fakens_filename)
314         pass
315     pass
316 #
317
318 # -----------------------------------------------------------------------------
319
320 if __name__ == "__main__":
321     runSalome()
322 #