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