2 # -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
5 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
22 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
26 # \brief Module that provides services to launch SALOME
29 import sys, os, string, glob, time, pickle, re
31 from server import process_id, Server
34 from salomeContextUtils import ScriptAndArgsObjectEncoder
37 logger = logging.getLogger()
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):
46 COLOR_SEQ = "\033[1;%dm"
48 frame = inspect.currentframe()
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)
55 class BackTraceFormatter(logging.Formatter):
56 def __init__(self, *args, **kwargs):
57 logging.Formatter.__init__(self, *args, **kwargs)
58 def format(self, record):
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
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)
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")
74 if current_version >= version_ref:
75 formatter = BackTraceFormatter('%(levelname)s : %(asctime)s : %(message)s ',style='%')
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)
84 verbose_map = { "0": logging.WARNING, "1": logging.INFO, "2": logging.DEBUG}
85 if verbose in verbose_map:
86 logger.setLevel(verbose_map[verbose])
88 # -----------------------------------------------------------------------------
90 # Class definitions to launch CORBA Servers
93 class InterpServer(Server):
94 def __init__(self,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']
102 env_ld_library_path=['env', 'LD_LIBRARY_PATH=' + os.getenv("LD_LIBRARY_PATH")]
103 self.CMD=['xterm', '-e'] + env_ld_library_path + ['python']
108 print("INTERPSERVER::command = ", command)
110 pid = subprocess.Popen(command).pid
111 process_id[pid]=self.CMD
116 def get_cata_path(list_modules,modules_root_dir):
117 """Build a list of catalog paths (cata_path) to initialize the ModuleCatalog server
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)
128 if os.path.exists(cata_file):
129 cata_path.append(cata_file)
130 modules_cata[module]=cata_file
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
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
147 class CatalogServer(Server):
148 def __init__(self,args):
151 self.SCMD1=['SALOME_ModuleCatalog_Server']
152 if 'launcher' in self.args:
153 pos = args['launcher'].find(":")
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']
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')]
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
171 list_modules = ["KERNEL"] + list_modules
173 cata_path=get_cata_path(list_modules,modules_root_dir)
175 self.CMD=self.SCMD1 + ['"' + '"::"'.join(cata_path) + '"'] + self.SCMD2
179 class SalomeDSServer(Server):
180 def __init__(self,args):
183 self.CMD=['SALOMEDS_Server']
184 if 'launcher' in self.args:
185 pos = args['launcher'].find(":")
187 self.CMD+=['-ORBInitRef']
188 machine = args['launcher'][0:pos]
189 port = args['launcher'][pos+1:]
190 self.CMD+=["NameService=corbaname::" + machine + ":" + port]
194 class ConnectionManagerServer(Server):
195 def __init__(self,args):
198 self.CMD=['SALOME_ConnectionManagerServer']
199 if 'launcher' in self.args:
200 pos = args['launcher'].find(":")
202 self.CMD+=['-ORBInitRef']
203 machine = args['launcher'][0:pos]
204 port = args['launcher'][pos+1:]
205 self.CMD+=["NameService=corbaname::" + machine + ":" + port]
210 class RegistryServer(Server):
211 def __init__(self,args):
214 self.CMD=['SALOME_Registry_Server', '--salome_session','theSession']
215 if 'launcher' in self.args:
216 pos = args['launcher'].find(":")
218 self.CMD+=['-ORBInitRef']
219 machine = args['launcher'][0:pos]
220 port = args['launcher'][pos+1:]
221 self.CMD+=["NameService=corbaname::" + machine + ":" + port]
225 class ContainerCPPServer(Server):
226 def __init__(self,args,with_gui=False):
229 self.CMD=['SALOME_Container']
230 if 'launcher' in self.args:
231 pos = args['launcher'].find(":")
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"]:
240 val = os.getenv("VALGRIND_OPTIONS")
244 self.CMD = l + self.CMD
249 class LoggerServer(Server):
250 def __init__(self,args):
253 from salome_utils import generateFileName, getLogDir
254 logfile = generateFileName( getLogDir(),
260 print("===========================================================")
261 print("Logger server: put log to the file:")
263 print("===========================================================")
264 self.CMD=['SALOME_Logger_Server', logfile]
266 pass # end of LoggerServer class
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
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])]
283 os.environ["LD_LIBRARY_PATH"] = os.environ["SQUISH_PREFIX"] + "/lib:" + os.environ["LD_LIBRARY_PATH"]
285 if 'launcher' in self.args:
286 pos = args['launcher'].find(":")
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')]
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','(',')']
308 if 'cppContainer' in self.args['standalone'] or 'cppContainer' in self.args['embedded']:
310 if 'pyContainer' in self.args['standalone'] or 'pyContainer' in self.args['embedded']:
311 raise Exception('Python containers no longer supported')
313 session_gui = self.args.get('session_gui', True)
315 self.SCMD2+=['--hide-desktop']
317 if not self.args['splash']:
318 self.SCMD2+=['--hide-splash']
320 if self.args['study_hdf'] is not None:
321 self.SCMD2+=['--study-hdf=%s'%self.args['study_hdf']]
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)]
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:
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)
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)]
348 if 'language' in self.args:
349 self.SCMD2+=['--language=%s' % self.args['language']]
350 os_handle, iorfakens = tempfile.mkstemp()
351 self.iorfakens = iorfakens
353 self.SCMD2+=["--iorfakens={}".format(iorfakens)]
357 def getSessionServerExe(self):
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
366 list_modules = ["KERNEL"] + list_modules
368 cata_path=get_cata_path(list_modules,modules_root_dir)
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
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']
380 if self.args["gdb_session"] or self.args["ddd_session"]:
381 f = open(".gdbinit4salome", "w")
383 args = " ".join(self.CMD[1:])
384 args = args.replace("(", "\(")
385 args = args.replace(")", "\)")
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]]
396 if self.args["valgrind_session"]:
398 val = os.getenv("VALGRIND_OPTIONS")
402 self.CMD = l + self.CMD
405 class SessionServer(CommonSessionServer):
406 def __init__(self,args,modules_list,modules_root_dir):
407 super().__init__(args,modules_list,modules_root_dir)
409 KernelBasis.setSSLMode(False)
411 def getSessionServerExe(self):
412 return "SALOME_Session_Server"
415 class LauncherServer(Server):
416 def __init__(self,args):
419 self.SCMD1=['SALOME_LauncherServer']
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')]
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',')']
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
442 list_modules = ["KERNEL"] + list_modules
444 cata_path=get_cata_path(list_modules,modules_root_dir)
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
450 self.CMD=self.SCMD1 + self.SCMD2