]> SALOME platform Git repositories - modules/kernel.git/blob - bin/appliskel/runSalomeScript
Salome HOME
remove notification server
[modules/kernel.git] / bin / appliskel / runSalomeScript
1 #!/usr/bin/env python
2 #  -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2014  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 import os,sys,optparse
26 import socket,shutil
27 import re
28
29 usage="""
30         Connect to a SALOME session (local or remote) and execute a Python script with data files in argument (optional)
31
32         Usage: %prog [ options ] script
33
34           script           : The Python script to execute in the SALOME session
35
36         SALOME SESSION
37         --------------
38         If PORT and MACHINE are not given, try to connect to the last active session on the local machine
39         If PORT and MACHINE are given, try to connect to the remote session associated with PORT on MACHINE
40         If MACHINE is not given, try to connect to the session associated to PORT on the local machine
41         If PORT is not given, try to connect to the remote session associated to port 2810 on MACHINE
42
43         If MACHINE isn't localhost or hostname, USER is needed
44
45         If Salome isn't installed on the local machine, use APPLI_DIST to execute a distant session
46
47
48         INPUTS AND OUPUTS
49         -----------------
50         script is needed in all case
51         INPUT and OUTPUT are used only when Salome isn't on local machine. It defines a list of script (full path, blank separated)
52         Actions done with these two lists are :
53         - adjustment of path in a temporary script file
54         - copy of the input files and script file on the distant machine
55
56 """
57
58 appli_local=os.path.realpath(os.path.dirname(__file__))
59
60 def get_hostname():
61   return socket.gethostname().split('.')[0]
62
63 def vararg_callback(option, opt_str, value, parser):
64   """optparse callback for variable length arguments"""
65   assert value is None
66
67   done = 0
68   value = []
69   rargs = parser.rargs
70   while rargs:
71     arg = rargs[0]
72
73     # Stop if we hit an arg like "--foo", "-a", "-fx", "--file=f",
74     # etc.  Note that this also stops on "-3" or "-3.0", so if
75     # your option takes numeric values, you will need to handle this.
76     if ((arg[:2] == "--" and len(arg) > 2) or
77         (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")):
78       break
79     else:
80       value.append(arg)
81       del rargs[0]
82
83   setattr(parser.values, option.dest, value)
84
85 def parse_args():
86   """parse arguments, check validity and set defaults"""
87   parser = optparse.OptionParser(usage=usage)
88   parser.add_option('-p','--port', dest="port", default='', help="The port to connect to")
89   parser.add_option('-m','--machine', dest="machine", default='', help="The computer to connect to")
90   parser.add_option('-d','--directory', dest="directory", help="[Distant Mode] The APPLI_HOME path on the distant machine (must be used if Salome isn't on the local machine)")
91   parser.add_option('-u','--user', dest="user", default='', help="[Distant Mode] The user on the computer to connect to")
92   parser.add_option('-i','--infiles', dest="infiles", default=[], action="callback", callback=vararg_callback,
93                     help="[Distant Mode] The list of input files (blank separated) used in the Python script")
94   parser.add_option('-o','--outfiles', dest="outfiles", default=[], action="callback", callback=vararg_callback,
95                     help="[Distant Mode] The list of output files (blank separated) generated by the Python script")
96
97   args=sys.argv[1:]
98
99   script=""
100   if args:
101     script=args.pop()
102
103   options, args = parser.parse_args(args)
104
105   #check the arguments
106   if not os.path.exists(script):
107     print "ERROR: the script file is mandatory"
108     sys.exit(1)
109
110   machine=options.machine
111   port=options.port
112   user=options.user
113   infiles = options.infiles
114   outfiles = options.outfiles
115   directory=options.directory
116
117   mode="local"
118
119   if machine:
120     here=get_hostname()
121     if machine != here and machine != "localhost":
122       #SALOME server is on a remote computer
123       mode="remote"
124
125       if not user:
126         print "ERROR: the remote execution needs -u user argument"
127         sys.exit(1)
128
129       if not os.path.exists(os.path.join(appli_local,"runSession")):
130         if not directory:
131           print "ERROR: the remote execution without SALOME installation needs -d directory argument"
132           sys.exit(1)
133
134   return mode,user,machine,port,directory,infiles,outfiles,script
135
136 def copy_files(user,machine,script,infiles,outfiles,directory):
137   """modify script, copy files to remote computer and return lists of copied files"""
138
139   namescript=os.path.basename(script)
140   import getpass
141   logname = getpass.getuser()
142   tmp_script="/tmp/%s_%s_%s" % (logname,os.getpid(),namescript)
143   fscript=open(script)
144   script_text=fscript.read()
145   fscript.close()
146
147   list_infiles=[]
148   list_outfiles=[]
149
150   n=0
151   for infile in infiles:
152     # generate a temporary file name
153     namefile=os.path.basename(infile)
154     tmp_file="/tmp/%s_%s_i%s_%s" % (logname,os.getpid(),n,namefile)
155
156     #modify the salome script
157     script_text = re.sub(infile,tmp_file,script_text)
158
159     # copy the infile to the remote server (into /tmp)
160     cmd="scp %s %s@%s:%s" % (infile,user,machine,tmp_file)
161     print "[  SCP  ]",cmd
162     os.system(cmd)
163
164     list_infiles.append(tmp_file)
165     n=n+1
166
167   n=0
168   for outfile in outfiles:
169     # generate a temporary file name
170     namefile=os.path.basename(outfile)
171     tmp_file="/tmp/%s_%s_o%s_%s" % (logname,os.getpid(),n,namefile)
172
173     #modify the salome script
174     script_text = re.sub(outfile,tmp_file,script_text)
175
176     list_outfiles.append(tmp_file)
177     n=n+1
178
179   fscript=open(tmp_script,'w')
180   fscript.write(script_text)
181   fscript.close()
182
183   if directory:
184     #copy the salome script on the remote server
185     cmd="scp %s %s@%s:%s" % (tmp_script,user,machine,tmp_script)
186     print "[  SCP  ]",cmd
187     os.system(cmd)
188
189   return list_infiles, list_outfiles, tmp_script
190
191 def main():
192
193   mode,user,machine,port,directory,infiles,outfiles,script = parse_args()
194
195   tmp_script=script
196
197   print "mode:",mode
198
199   if mode == "remote":
200     list_infiles, list_outfiles, tmp_script = copy_files(user,machine,script,infiles,outfiles,directory)
201
202   #################################################
203   #          Execution                            #
204   #################################################
205   if directory:
206     print "[ REMOTE ]"
207
208     # execute runSession from the remote SALOME application
209     cmd="ssh %s@%s %s/runSession " % (user,machine,directory)
210     if port:
211       cmd=cmd+"-p %s "%port
212     cmd = cmd +"python " + tmp_script
213     print '[  SSH   ] ' + cmd
214     os.system(cmd)
215
216   else:
217     print "[ LOCAL ]"
218
219     # execute runSession from the local SALOME application
220     cmd="%s/runSession " % appli_local
221     if machine:
222       cmd=cmd+"-m %s "%machine
223     if port:
224       cmd=cmd+"-p %s "%port
225     cmd = cmd +"python " + tmp_script
226     print '[  SH   ] ' + cmd
227     os.system(cmd)
228
229   #################################################
230   #          Get remote files and clean           #
231   #################################################
232   if mode == "remote":
233     temp_files=list_infiles+list_outfiles
234
235     #get the outfiles
236     for outfile in outfiles:
237       remote_outfile=list_outfiles.pop(0)
238       cmd="scp %s@%s:%s %s" %(user,machine,remote_outfile,outfile)
239       print "[  SCP  ] "+cmd
240       os.system(cmd)
241
242     #clean temporary files
243     cmd="ssh %s@%s \\rm -f %s" % (user,machine," ".join(temp_files))
244     print '[  SSH   ] ' + cmd
245     os.system(cmd)
246     os.remove(tmp_script)
247
248 if __name__ == '__main__':
249   main()
250