Salome HOME
Merge branch 'master' of https://codev-tuleap.cea.fr/plugins/git/salome/SALOME
[tools/SALOME.git] / bin / salome.py
1 #!/usr/bin/env python3
2 # lightweight salome launcher
3 import subprocess
4 import os
5 import glob
6 import json
7 #
8 import orbmodule
9 from searchFreePort import searchFreePort
10 import SALOME
11 import SALOME_ModuleCatalog
12 #
13 # define supported options
14 # [PYTHON_FILE [args] [PYTHON_FILE [args]...]]
15 usage = """Usage: salome.py [options] [python_file [args]] [python_file [args]] ...
16        Python file arguments, if any, must be comma-separated and prefixed by args 
17        (without blank characters and quotes),  e.g. myscript.py args:arg1,arg2=val
18        
19        Starts salome and optionnally executes python scripts provided as trailing arguments"""
20 from optparse import OptionParser
21 parser = OptionParser(usage=usage)
22 parser.add_option("-g", "--gui", action="store_true", dest="gui", default=False, 
23                   help="Launch salome servers and start gui")
24 parser.add_option("-t", "--tui", action="store_true", dest="tui", default=False, 
25                   help="Launch salome servers")
26 parser.add_option("-e", "--environ", action="store_true", dest="env", default=False, 
27                   help="return a bash shell with Salome environement set")
28
29 # main programm
30 def main():
31     (options, args) = parser.parse_args()
32     if not (options.gui or options.tui or options.env):
33         # all options are set to false! activate gui option
34         options.gui=True
35
36     options.extra_args=None
37     if args: # parse optionnal python scripts args
38         options.extra_args=parse_extra_args(args)
39         
40     if options.env:
41         # return 
42         return bash_shell()
43
44     if options.tui or options.gui:
45         clt=start_salome(options)
46         #if clt != None:
47         #    print(" --- registered objects tree in Naming Service ---")
48         #    clt.showNS()
49
50 def parse_extra_args(args):
51     # these extra args represent python script files with optionnally their arguments
52     extra_args=[] # build a list of dicts (the form required by salome session server)
53     while args:
54         # pull first arg, check it is a file
55         pyfilename=args[0]
56         pyargs=[]
57         args=args[1:]
58         if not os.path.isfile(pyfilename):
59             continue # if the arg is not a file name we skip it
60         if args and args[0].startswith("args:"):
61             #if the next arg is related to pyscript, pull it and process it
62             pyargs=args[0][5:].split(",")
63             args=args[1:]
64         extra_args.append({pyfilename:pyargs})
65     return extra_args
66
67 def bash_shell():
68     cmd = ["/bin/bash"]
69     proc = subprocess.Popen(cmd, shell=False, close_fds=True)
70     proc.communicate()
71     return proc.returncode
72
73 def start_salome(options):
74     clt=start_orb()
75
76     # Launch Registry Server, and wait for it available in Naming Service
77     RegistryServer().run()
78     clt.waitNS("/Registry")
79     
80     # Launch Module Catalog Server, and wait for it available in Naming Service
81     CatalogServer().run()
82     clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog)
83
84     # launch SalomeDS server, wait for it available in Naming Service
85     SalomeDSServer().run()
86     clt.waitNS("/Study")
87
88     # launch 
89     ConnectionManagerServer().run()
90
91     # launch Session Server
92     if options.gui:
93         # process our list of extra args into a string redeable by session server (json style)
94         pyscriptargs=""
95         if options.extra_args: # pyscripts were specified, we transfer the info to gui
96             pyscriptargs='--pyscript=%s' % json.dumps(options.extra_args)
97         SessionServer().run(pyscriptargs) 
98
99     # start launcher server
100     LauncherServer().run()
101     # clt.waitNS("/LauncherServer")
102
103     if not options.gui:
104         # in tui mode, start FactoryServer standalone
105         # ContainerServer().run()  CNC KO?
106         # run specified pyscripts, if any
107         if options.extra_args:
108             for file_args_dict in options.extra_args:
109                 for f in file_args_dict.keys():
110                     command="python3 "+f
111                     for arg in file_args_dict[f]:
112                         command += " "+arg
113                 print ("command to execute pyscript: ", command)
114                 proc = subprocess.Popen(command, shell=True)
115                 #  addToKillList(proc.pid, command, args['port']) ??
116                 res = proc.wait()
117                 if res: sys.exit(1) # if there's an error when executing script, we should explicitly exit
118
119     if options.gui:
120         session=clt.waitNS("/Kernel/Session",SALOME.Session)
121     return clt
122
123 def start_orb():
124     # initialise orb and naming service
125     searchFreePort()
126     print("Initialise ORB and Naming Service")
127     clt=orbmodule.client()
128     return clt
129
130 def generate_module_catalog():
131     salome_modules=os.getenv("SALOME_MODULES")
132     assert salome_modules != None, "SALOME_MODULES variable not found!"
133     cata_path=[]
134     for module in salome_modules.split(","):
135         module_root_dir = os.getenv(module + "_ROOT_DIR")
136         module_cata = module + "Catalog.xml"
137         cata_path.extend(glob.glob(os.path.join(module_root_dir,"share","salome",
138                                                 "resources",module.lower(), module_cata)))
139     return ':'.join(cata_path)
140
141 # base class to start corba servers
142 class Server:
143     CMD=[]
144     def run(self):
145         args = self.CMD
146         pid = os.spawnvp(os.P_NOWAIT, args[0], args)
147         print ("start server ", args, "  (pid = %s)" % pid)
148
149 class LauncherServer(Server):
150    CMD=['SALOME_LauncherServer']
151
152 class ConnectionManagerServer(Server):
153    CMD=['SALOME_ConnectionManagerServer']
154
155 class SalomeDSServer(Server):
156    CMD=['SALOMEDS_Server']
157
158 class RegistryServer(Server):
159    CMD=['SALOME_Registry_Server', '--salome_session','theSession']
160
161 class ContainerServer(Server):
162    CMD=['SALOME_Container','FactoryServer','-ORBInitRef','NameService=corbaname::localhost']
163
164 class LoggerServer(Server):
165    CMD=['SALOME_Logger_Server', 'logger.log']
166
167 class CatalogServer(Server):
168    CMD=['SALOME_ModuleCatalog_Server','-common']
169    def run(self):
170        self.CMD = self.CMD + [generate_module_catalog()]
171        Server.run(self)
172
173 class NotifyServer(Server):
174    CMD=['notifd','-c','${KERNEL_ROOT_DIR}/share/salome/resources/channel.cfg -DFactoryIORFileName=/tmp/${LOGNAME}_rdifact.ior -DChannelIORFileName=/tmp/${LOGNAME}_rdichan.ior']
175
176 class SessionServer(Server):
177    CMD=['SALOME_Session_Server','--with','Container','(','FactoryServer',')','--with', 'SalomeAppEngine', '(', ')', 'CPP', 'GUI', 'SPLASH', '--language=fr']
178    def run(self, pyscriptopt):
179        if pyscriptopt:  # communicate to gui the scripts to run
180            self.CMD = self.CMD + [pyscriptopt] 
181        salome_modules=os.getenv("SALOME_MODULES")
182        assert salome_modules != None, "SALOME_MODULES variable not found!"
183        self.CMD = self.CMD + ['--modules (' + salome_modules.replace(",",":") + ')' ]
184        Server.run(self)
185
186 if __name__ == "__main__":
187     main()