Salome HOME
remove extra print() calls
[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   with open(script, 'r') as fscript:
144     script_text=fscript.read()
145
146   list_infiles=[]
147   list_outfiles=[]
148
149   n=0
150   for infile in infiles:
151     # generate a temporary file name
152     namefile=os.path.basename(infile)
153     tmp_file="/tmp/%s_%s_i%s_%s" % (logname,os.getpid(),n,namefile)
154
155     #modify the salome script
156     script_text = re.sub(infile,tmp_file,script_text)
157
158     # copy the infile to the remote server
159     cmd="scp %s %s@%s:%s" % (infile,user,machine,tmp_file)
160     print "[  SCP  ]",cmd
161     os.system(cmd)
162
163     list_infiles.append(tmp_file)
164     n=n+1
165
166   n=0
167   for outfile in outfiles:
168     # generate a temporary file name
169     namefile=os.path.basename(outfile)
170     tmp_file="/tmp/%s_%s_o%s_%s" % (logname,os.getpid(),n,namefile)
171
172     #modify the salome script
173     script_text = re.sub(outfile,tmp_file,script_text)
174
175     list_outfiles.append(tmp_file)
176     n=n+1
177
178   with open(tmp_script,'w') as fscript:
179     fscript.write(script_text)
180
181   if directory:
182     #copy the salome script on the remote server
183     cmd="scp %s %s@%s:%s" % (tmp_script,user,machine,tmp_script)
184     print "[  SCP  ]",cmd
185     os.system(cmd)
186
187   return list_infiles, list_outfiles, tmp_script
188
189 def main():
190
191   mode,user,machine,port,directory,infiles,outfiles,script = parse_args()
192
193   tmp_script=script
194
195   if mode == "remote":
196     list_infiles, list_outfiles, tmp_script = copy_files(user,machine,script,infiles,outfiles,directory)
197
198   #################################################
199   #          Execution                            #
200   #################################################
201   if mode == "remote":
202     print "[ REMOTE ]"
203
204     # execute runSession from the remote SALOME application
205     cmd="ssh %s@%s %s/runSession " % (user,machine,directory)
206     if port:
207       cmd=cmd+"-p %s "%port
208     cmd = cmd +"python " + tmp_script
209     print '[  SSH   ] ' + cmd
210     os.system(cmd)
211
212   else:
213     print "[ LOCAL ]"
214
215     # execute runSession from the local SALOME application
216     cmd="%s/runSession " % appli_local
217     if machine:
218       cmd=cmd+"-m %s "%machine
219     if port:
220       cmd=cmd+"-p %s "%port
221     cmd = cmd +"python " + tmp_script
222     print '[  SH   ] ' + cmd
223     os.system(cmd)
224
225   #################################################
226   #          Get remote files and clean           #
227   #################################################
228   if mode == "remote":
229     temp_files=list_infiles+list_outfiles+[tmp_script]
230
231     #get the outfiles
232     for outfile in outfiles:
233       remote_outfile=list_outfiles.pop(0)
234       cmd="scp %s@%s:%s %s" %(user,machine,remote_outfile,outfile)
235       print "[  SCP  ] "+cmd
236       os.system(cmd)
237
238     #clean temporary files
239     cmd="ssh %s@%s \\rm -f %s" % (user,machine," ".join(temp_files))
240     print '[  SSH   ] ' + cmd
241     os.system(cmd)
242     os.remove(tmp_script)
243
244 if __name__ == '__main__':
245   main()