2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2013 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.
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
25 import os,sys,optparse
30 Connect to a SALOME session (local or remote) and execute a Python script with data files in argument (optional)
32 Usage: %prog [ options ] script
34 script : The Python script to execute in the SALOME session
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
43 If MACHINE isn't localhost or hostname, USER is needed
45 If Salome isn't installed on the local machine, use APPLI_DIST to execute a distant session
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
58 appli_local=os.path.realpath(os.path.dirname(__file__))
61 return socket.gethostname().split('.')[0]
63 def vararg_callback(option, opt_str, value, parser):
64 """optparse callback for variable length arguments"""
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] != "-")):
83 setattr(parser.values, option.dest, value)
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")
103 options, args = parser.parse_args(args)
106 if not os.path.exists(script):
107 print "ERROR: the script file is mandatory"
110 machine=options.machine
113 infiles = options.infiles
114 outfiles = options.outfiles
115 directory=options.directory
121 if machine != here and machine != "localhost":
122 #SALOME server is on a remote computer
126 print "ERROR: the remote execution needs -u user argument"
129 if not os.path.exists(os.path.join(appli_local,"runSession")):
131 print "ERROR: the remote execution without SALOME installation needs -d directory argument"
134 return mode,user,machine,port,directory,infiles,outfiles,script
136 def copy_files(user,machine,script,infiles,outfiles,directory):
137 """modify script, copy files to remote computer and return lists of copied files"""
139 namescript=os.path.basename(script)
140 logname=os.getenv("LOGNAME",user)
141 tmp_script="/tmp/%s_%s_%s" % (logname,os.getpid(),namescript)
143 script_text=fscript.read()
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)
155 #modify the salome script
156 script_text = re.sub(infile,tmp_file,script_text)
158 # copy the infile to the remote server (into /tmp)
159 cmd="scp %s %s@%s:%s" % (infile,user,machine,tmp_file)
163 list_infiles.append(tmp_file)
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)
172 #modify the salome script
173 script_text = re.sub(outfile,tmp_file,script_text)
175 list_outfiles.append(tmp_file)
178 fscript=open(tmp_script,'w')
179 fscript.write(script_text)
183 #copy the salome script on the remote server
184 cmd="scp %s %s@%s:%s" % (tmp_script,user,machine,tmp_script)
188 return list_infiles, list_outfiles, tmp_script
192 mode,user,machine,port,directory,infiles,outfiles,script = parse_args()
199 list_infiles, list_outfiles, tmp_script = copy_files(user,machine,script,infiles,outfiles,directory)
201 #################################################
203 #################################################
207 # execute runSession from the remote SALOME application
208 cmd="ssh %s@%s %s/runSession " % (user,machine,directory)
210 cmd=cmd+"-p %s "%port
211 cmd = cmd +"python " + tmp_script
212 print '[ SSH ] ' + cmd
218 # execute runSession from the local SALOME application
219 cmd="%s/runSession " % appli_local
221 cmd=cmd+"-m %s "%machine
223 cmd=cmd+"-p %s "%port
224 cmd = cmd +"python " + tmp_script
225 print '[ SH ] ' + cmd
228 #################################################
229 # Get remote files and clean #
230 #################################################
232 temp_files=list_infiles+list_outfiles
235 for outfile in outfiles:
236 remote_outfile=list_outfiles.pop(0)
237 cmd="scp %s@%s:%s %s" %(user,machine,remote_outfile,outfile)
241 #clean temporary files
242 cmd="ssh %s@%s \\rm -f %s" % (user,machine," ".join(temp_files))
243 print '[ SSH ] ' + cmd
245 os.remove(tmp_script)
247 if __name__ == '__main__':