]> SALOME platform Git repositories - modules/kernel.git/blob - bin/runSalomeCommon.py
Salome HOME
[bos #32519][EDF] (2022-T3)
[modules/kernel.git] / bin / runSalomeCommon.py
1 #!/usr/bin/env python3
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2022  CEA/DEN, EDF R&D, 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 setenv
31 from server import process_id, Server
32 import json
33 import subprocess
34 from salomeContextUtils import ScriptAndArgsObjectEncoder
35 import platform
36 import logging
37 logger = logging.getLogger()
38
39 class ColoredFormatter(logging.Formatter):
40     BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(30,38)
41     COLORS = { 'WARNING': YELLOW, 'INFO': WHITE, 'DEBUG': BLUE, 'CRITICAL': YELLOW, 'ERROR': RED }
42     def __init__(self, *args, **kwargs):
43         logging.Formatter.__init__(self, *args, **kwargs)
44     def format(self, record):
45         RESET_SEQ = "\033[0m"
46         COLOR_SEQ = "\033[1;%dm"
47         import inspect
48         frame = inspect.currentframe()
49         for i in range(8):
50             frame = frame.f_back
51         record.levelname = COLOR_SEQ % ColoredFormatter.COLORS[record.levelname] + record.levelname + RESET_SEQ
52         record.msg = "{} ( callsite is {} of file \"{}\" at line {} )".format(record.msg, frame.f_code.co_name,inspect.getsourcefile(frame),inspect.getlineno(frame) )
53         return logging.Formatter.format(self, record)
54
55 class BackTraceFormatter(logging.Formatter):
56     def __init__(self, *args, **kwargs):
57         logging.Formatter.__init__(self, *args, **kwargs)
58     def format(self, record):
59         import inspect
60         frame = inspect.currentframe()
61         # go upward of the stack to catch the effective callsite. Not very steady....
62         # should be replaced by an analysis of frame.f_code
63         for i in range(8):
64             frame = frame.f_back
65         record.msg = "{} ( callsite is {} of file \"{}\" at line {} )".format(record.msg, frame.f_code.co_name,inspect.getsourcefile(frame),inspect.getlineno(frame) )
66         return logging.Formatter.format(self, record)
67
68 def setVerbose(verbose):
69     from packaging import version
70     current_version = version.parse("{}.{}".format(sys.version_info.major,sys.version_info.minor))
71     version_ref = version.parse("3.5.0")
72     global logger
73     formatter = None
74     if current_version >= version_ref:
75         formatter = BackTraceFormatter('%(levelname)s : %(asctime)s : %(message)s ',style='%')
76     else:
77         formatter = logging.Formatter('%(levelname)s : %(asctime)s : %(message)s ',style='%')
78     formatter.default_time_format = '%H:%M:%S'
79     formatter.default_msec_format = "%s.%03d"
80     stream_handler = logging.StreamHandler()
81     stream_handler.setFormatter(formatter)
82     logger.addHandler(stream_handler)
83
84     verbose_map = { "0": logging.WARNING, "1": logging.INFO, "2": logging.DEBUG}
85     if verbose in verbose_map:
86         logger.setLevel(verbose_map[verbose])
87
88 # -----------------------------------------------------------------------------
89 #
90 # Class definitions to launch CORBA Servers
91 #
92
93 class InterpServer(Server):
94     def __init__(self,args):
95         self.args=args
96         if sys.platform == "win32":
97           self.CMD=['cmd', '/c', 'start cmd.exe', '/K', 'python']
98         elif sys.platform == "darwin":
99           env_ld_library_path=['env', 'DYLD_LIBRARY_PATH=' + os.getenv("LD_LIBRARY_PATH")]
100           self.CMD=['xterm', '-e'] + env_ld_library_path + ['python']
101         else:
102           env_ld_library_path=['env', 'LD_LIBRARY_PATH=' + os.getenv("LD_LIBRARY_PATH")]
103           self.CMD=['xterm', '-e'] + env_ld_library_path + ['python']
104
105     def run(self):
106         global process_id
107         command = self.CMD
108         print("INTERPSERVER::command = ", command)
109         import subprocess
110         pid = subprocess.Popen(command).pid
111         process_id[pid]=self.CMD
112         self.PID = pid
113
114 # ---
115
116 def get_cata_path(list_modules,modules_root_dir):
117     """Build a list of catalog paths (cata_path) to initialize the ModuleCatalog server
118     """
119     modules_cata={}
120     cata_path=[]
121
122     for module in list_modules:
123         if module in modules_root_dir:
124             module_root_dir=modules_root_dir[module]
125             module_cata=module+"Catalog.xml"
126             cata_file=os.path.join(module_root_dir, "share",setenv.salome_subdir, "resources",module.lower(), module_cata)
127
128             if os.path.exists(cata_file):
129                 cata_path.append(cata_file)
130                 modules_cata[module]=cata_file
131             else:
132                 cata_file=os.path.join(module_root_dir, "share",setenv.salome_subdir, "resources", module_cata)
133                 if os.path.exists(cata_file):
134                     cata_path.append(cata_file)
135                     modules_cata[module]=cata_file
136
137     for path in os.getenv("SALOME_CATALOGS_PATH","").split(os.pathsep):
138         if os.path.exists(path):
139             for cata_file in glob.glob(os.path.join(path,"*Catalog.xml")):
140                 module_name= os.path.basename(cata_file)[:-11]
141                 if module_name not in modules_cata:
142                     cata_path.append(cata_file)
143                     modules_cata[module_name]=cata_file
144
145     return cata_path
146
147 class CatalogServer(Server):
148     def __init__(self,args):
149         self.args=args
150         self.initArgs()
151         self.SCMD1=['SALOME_ModuleCatalog_Server']
152         if 'launcher' in self.args:
153             pos = args['launcher'].find(":")
154             if pos != -1:
155               self.SCMD1+=['-ORBInitRef']
156               machine = args['launcher'][0:pos]
157               port = args['launcher'][pos+1:]
158               self.SCMD1+=["NameService=corbaname::" + machine + ":" + port]
159         self.SCMD1+=['-common']
160         self.SCMD2=[]
161         home_dir=os.path.expanduser("~")
162         if home_dir is not None:
163             self.SCMD2=['-personal',os.path.join(home_dir,'Salome', 'resources', 'CatalogModulePersonnel.xml')]
164
165     def setpath(self,modules_list,modules_root_dir):
166         list_modules = modules_list[:]
167         list_modules.reverse()
168         if self.args["gui"] :
169             list_modules = ["KERNEL", "GUI"] + list_modules
170         else :
171             list_modules = ["KERNEL"] + list_modules
172
173         cata_path=get_cata_path(list_modules,modules_root_dir)
174
175         self.CMD=self.SCMD1 + ['"' + '"::"'.join(cata_path) + '"'] + self.SCMD2
176
177 # ---
178
179 class SalomeDSServer(Server):
180     def __init__(self,args):
181         self.args=args
182         self.initArgs()
183         self.CMD=['SALOMEDS_Server']
184         if 'launcher' in self.args:
185             pos = args['launcher'].find(":")
186             if pos != -1:
187               self.CMD+=['-ORBInitRef']
188               machine = args['launcher'][0:pos]
189               port = args['launcher'][pos+1:]
190               self.CMD+=["NameService=corbaname::" + machine + ":" + port]
191
192 # ---
193
194 class ConnectionManagerServer(Server):
195     def __init__(self,args):
196         self.args=args
197         self.initArgs()
198         self.CMD=['SALOME_ConnectionManagerServer']
199         if 'launcher' in self.args:
200             pos = args['launcher'].find(":")
201             if pos != -1:
202               self.CMD+=['-ORBInitRef']
203               machine = args['launcher'][0:pos]
204               port = args['launcher'][pos+1:]
205               self.CMD+=["NameService=corbaname::" + machine + ":" + port]
206
207
208 # ---
209
210 class RegistryServer(Server):
211     def __init__(self,args):
212         self.args=args
213         self.initArgs()
214         self.CMD=['SALOME_Registry_Server', '--salome_session','theSession']
215         if 'launcher' in self.args:
216             pos = args['launcher'].find(":")
217             if pos != -1:
218               self.CMD+=['-ORBInitRef']
219               machine = args['launcher'][0:pos]
220               port = args['launcher'][pos+1:]
221               self.CMD+=["NameService=corbaname::" + machine + ":" + port]
222
223 # ---
224
225 class ContainerCPPServer(Server):
226     def __init__(self,args,with_gui=False):
227         self.args=args
228         self.initArgs()
229         self.CMD=['SALOME_Container']
230         if 'launcher' in self.args:
231             pos = args['launcher'].find(":")
232             if pos != -1:
233               self.CMD+=['-ORBInitRef']
234               machine = args['launcher'][0:pos]
235               port = args['launcher'][pos+1:]
236               self.CMD+=["NameService=corbaname::" + machine + ":" + port]
237         self.CMD+=['FactoryServer']
238         if not with_gui and self.args["valgrind_session"]:
239             l = ["valgrind"]
240             val = os.getenv("VALGRIND_OPTIONS")
241             if val:
242                 l += val.split()
243                 pass
244             self.CMD = l + self.CMD
245             pass
246
247 # ---
248
249 class LoggerServer(Server):
250     def __init__(self,args):
251         self.args=args
252         self.initArgs()
253         from salome_utils import generateFileName, getLogDir
254         logfile = generateFileName( getLogDir(),
255                                     prefix="logger",
256                                     extension="log",
257                                     with_username=True,
258                                     with_hostname=True,
259                                     with_port=True)
260         print("===========================================================")
261         print("Logger server: put log to the file:")
262         print(logfile)
263         print("===========================================================")
264         self.CMD=['SALOME_Logger_Server', logfile]
265         pass
266     pass # end of LoggerServer class
267
268 # ---
269 import abc
270 import tempfile
271 class CommonSessionServer(Server):
272     def __init__(self,args,modules_list,modules_root_dir):
273         self.args = args.copy()
274         # Bug 11512 (Problems with runSalome --xterm on Mandrake and Debian Sarge)
275         #self.args['xterm']=0
276         #
277         self.initArgs()
278         self.SCMD1=[self.getSessionServerExe()]
279         if "SQUISH_PREFIX" in os.environ:
280             if platform.system() == "Windows" :
281                 self.SCMD1 = [os.path.join(os.getenv("SQUISH_PREFIX"), "bin", "dllpreload.exe"),os.path.join(os.getenv("SQUISH_SALOME_PATH"), "W64", "GUI", "bin", "salome", self.SCMD1[0])]
282             else :
283                 os.environ["LD_LIBRARY_PATH"] = os.environ["SQUISH_PREFIX"] + "/lib:" + os.environ["LD_LIBRARY_PATH"]
284         self.SCMD2=[]
285         if 'launcher' in self.args:
286             pos = args['launcher'].find(":")
287             if pos != -1:
288               self.SCMD1+=['-ORBInitRef']
289               machine = args['launcher'][0:pos]
290               port = args['launcher'][pos+1:]
291               self.SCMD1+=["NameService=corbaname::" + machine + ":" + port]
292         if 'registry' in self.args['embedded']:
293             self.SCMD1+=['--with','Registry',
294                          '(','--salome_session','theSession',')']
295         if 'moduleCatalog' in self.args['embedded']:
296             self.SCMD1+=['--with','ModuleCatalog','(','-common']
297             home_dir=os.path.expanduser("~")
298             if home_dir is not None:
299                 self.SCMD2+=['-personal',os.path.join(home_dir,'Salome','resources','CatalogModulePersonnel.xml')]
300             self.SCMD2+=[')']
301         if 'study' in self.args['embedded']:
302             self.SCMD2+=['--with','SALOMEDS','(',')']
303         if 'cppContainer' in self.args['embedded']:
304             self.SCMD2+=['--with','Container','(','FactoryServer',')']
305         if 'SalomeAppEngine' in self.args['embedded']:
306             self.SCMD2+=['--with','SalomeAppEngine','(',')']
307
308         if 'cppContainer' in self.args['standalone'] or 'cppContainer' in self.args['embedded']:
309             self.SCMD2+=['CPP']
310         if 'pyContainer' in self.args['standalone'] or 'pyContainer' in self.args['embedded']:
311             raise Exception('Python containers no longer supported')
312         if self.args['gui']:
313             session_gui = self.args.get('session_gui', True)
314             if not session_gui:
315                 self.SCMD2+=['--hide-desktop']
316             else:
317                 if not self.args['splash']:
318                     self.SCMD2+=['--hide-splash']
319                     pass
320                 if self.args['study_hdf'] is not None:
321                     self.SCMD2+=['--study-hdf=%s'%self.args['study_hdf']]
322                     pass
323                 pass
324                 if 'pyscript' in self.args and len(self.args['pyscript']) > 0:
325                     msg = json.dumps(self.args['pyscript'], cls=ScriptAndArgsObjectEncoder)
326                     self.SCMD2+=['--pyscript=%s'%(msg)]
327                     pass
328                 pass
329             pass
330         if self.args['noexcepthandler']:
331             self.SCMD2+=['--no-exception-handler']
332         if 'user_config' in self.args:
333             self.SCMD2+=['--resources=%s'%self.args['user_config']]
334         if 'modules' in self.args:
335             list_modules = []
336             #keep only modules with GUI
337             for m in modules_list:
338               if m not in modules_root_dir:
339                 list_modules.insert(0,m)
340               else:
341                 fr1 = os.path.join(modules_root_dir[m],"share","salome","resources",m.lower(),"SalomeApp.xml")
342                 fr2 = os.path.join(modules_root_dir[m],"share","salome","resources","SalomeApp.xml")
343                 if os.path.exists(fr1) or os.path.exists(fr2):
344                   list_modules.insert(0,m)
345             list_modules.reverse()
346             self.SCMD2+=['--modules (%s)' % ":".join(list_modules)]
347             pass
348         if 'language' in self.args:
349             self.SCMD2+=['--language=%s' % self.args['language']]
350         os_handle, iorfakens = tempfile.mkstemp()
351         self.iorfakens = iorfakens
352         os.close(os_handle)
353         self.SCMD2+=["--iorfakens={}".format(iorfakens)]
354         pass
355
356     @abc.abstractmethod
357     def getSessionServerExe(self):
358         pass
359     
360     def setpath(self,modules_list,modules_root_dir):
361         list_modules = modules_list[:]
362         list_modules.reverse()
363         if self.args["gui"] :
364             list_modules = ["KERNEL", "GUI"] + list_modules
365         else :
366             list_modules = ["KERNEL"] + list_modules
367
368         cata_path=get_cata_path(list_modules,modules_root_dir)
369
370         if ("gui" in self.args) & ('moduleCatalog' in self.args['embedded']):
371             #Use '::' instead ":" because drive path with "D:\" is invalid on windows platform
372             self.CMD=self.SCMD1 + ['"' + '"::"'.join(cata_path) + '"'] + self.SCMD2
373         else:
374             self.CMD=self.SCMD1 + self.SCMD2
375         if 'test' in self.args:
376             self.CMD+=['-test'] + self.args['test']
377         elif 'play' in self.args:
378             self.CMD+=['-play'] + self.args['play']
379
380         if self.args["gdb_session"] or self.args["ddd_session"]:
381             f = open(".gdbinit4salome", "w")
382             f.write("set args ")
383             args = " ".join(self.CMD[1:])
384             args = args.replace("(", "\(")
385             args = args.replace(")", "\)")
386             f.write(args)
387             f.write("\n")
388             f.close()
389             if self.args["ddd_session"]:
390                 self.CMD = ["ddd", "--command=.gdbinit4salome", self.CMD[0]]
391             elif self.args["gdb_session"]:
392                 self.CMD = ["xterm", "-e", "gdb", "--command=.gdbinit4salome", self.CMD[0]]
393                 pass
394             pass
395
396         if self.args["valgrind_session"]:
397             l = ["valgrind"]
398             val = os.getenv("VALGRIND_OPTIONS")
399             if val:
400                 l += val.split()
401                 pass
402             self.CMD = l + self.CMD
403             pass
404
405 class SessionServer(CommonSessionServer):
406     def __init__(self,args,modules_list,modules_root_dir):
407         super().__init__(args,modules_list,modules_root_dir)
408         import KernelBasis
409         KernelBasis.setSSLMode(False)
410     
411     def getSessionServerExe(self):
412         return "SALOME_Session_Server"
413 # ---
414
415 class LauncherServer(Server):
416     def __init__(self,args):
417         self.args=args
418         self.initArgs()
419         self.SCMD1=['SALOME_LauncherServer']
420         self.SCMD2=[]
421         if args["gui"] :
422             if 'registry' in self.args['embedded']:
423                 self.SCMD1+=['--with','Registry',
424                              '(','--salome_session','theSession',')']
425             if 'moduleCatalog' in self.args['embedded']:
426                 self.SCMD1+=['--with','ModuleCatalog','(','-common']
427                 home_dir=os.path.expanduser("~")
428                 if home_dir is not None:
429                     self.SCMD2=['-personal',os.path.join(home_dir,'Salome','resources','CatalogModulePersonnel.xml')]
430                 self.SCMD2+=[')']
431             if 'study' in self.args['embedded']:
432                 self.SCMD2+=['--with','SALOMEDS','(',')']
433             if 'cppContainer' in self.args['embedded']:
434                 self.SCMD2+=['--with','Container','(','FactoryServer',')']
435
436     def setpath(self,modules_list,modules_root_dir):
437         list_modules = modules_list[:]
438         list_modules.reverse()
439         if self.args["gui"] :
440             list_modules = ["KERNEL", "GUI"] + list_modules
441         else :
442             list_modules = ["KERNEL"] + list_modules
443
444         cata_path=get_cata_path(list_modules,modules_root_dir)
445
446         if ("gui" in self.args) & ('moduleCatalog' in self.args['embedded']):
447             #Use '::' instead ":" because drive path with "D:\" is invalid on windows platform
448             self.CMD=self.SCMD1 + ['"' + '"::"'.join(cata_path) + '"'] + self.SCMD2
449         else:
450             self.CMD=self.SCMD1 + self.SCMD2