From: caremoli Date: Fri, 1 Oct 2010 08:38:46 +0000 (+0000) Subject: CCAR: add a new script (runSalomeScript) in SALOME application X-Git-Tag: V5_1_5a1~3 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=33a5767dc4a07a32f1a60b520d286834e14325e4;p=modules%2Fkernel.git CCAR: add a new script (runSalomeScript) in SALOME application This script can be used to execute a SALOME script on a server when the client has no SALOME installation. It copies local files on the server and execute runSession python script on the server --- diff --git a/bin/appli_gen.py b/bin/appli_gen.py index 9ee543a27..f6e5bcc7e 100644 --- a/bin/appli_gen.py +++ b/bin/appli_gen.py @@ -190,6 +190,7 @@ def install(prefix,config_file,verbose=0): 'runAppli', 'runConsole', 'runSession', + 'runSalomeScript', 'runTests', 'update_catalogs.py', '.bashrc', diff --git a/bin/appliskel/runSalomeScript b/bin/appliskel/runSalomeScript new file mode 100755 index 000000000..752f42074 --- /dev/null +++ b/bin/appliskel/runSalomeScript @@ -0,0 +1,228 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os,sys,optparse +import socket,shutil +import re + +usage=""" + Connect to a SALOME session (local or remote) and execute a Python script with data files in argument (optional) + + Usage: %prog [ options ] script + + script : The Python script to execute in the SALOME session + + SALOME SESSION + -------------- + If PORT and MACHINE are not given, try to connect to the last active session on the local machine + If PORT and MACHINE are given, try to connect to the remote session associated with PORT on MACHINE + If MACHINE is not given, try to connect to the session associated to PORT on the local machine + If PORT is not given, try to connect to the remote session associated to port 2810 on MACHINE + + If MACHINE isn't localhost or hostname, USER is needed + + If Salome isn't installed on the local machine, use APPLI_DIST to execute a distant session + + + INPUTS AND OUPUTS + ----------------- + script is needed in all case + INPUT and OUTPUT are used only when Salome isn't on local machine. It defines a list of script (full path, blank separated) + Actions done with these two lists are : + - adjustment of path in a temporary script file + - copy of the input files and script file on the distant machine + +""" + +appli_local=os.path.realpath(os.path.dirname(__file__)) + +def get_hostname(): + return socket.gethostname().split('.')[0] + +def vararg_callback(option, opt_str, value, parser): + """optparse callback for variable length arguments""" + assert value is None + + done = 0 + value = [] + rargs = parser.rargs + while rargs: + arg = rargs[0] + + # Stop if we hit an arg like "--foo", "-a", "-fx", "--file=f", + # etc. Note that this also stops on "-3" or "-3.0", so if + # your option takes numeric values, you will need to handle this. + if ((arg[:2] == "--" and len(arg) > 2) or + (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")): + break + else: + value.append(arg) + del rargs[0] + + setattr(parser.values, option.dest, value) + +def parse_args(): + """parse arguments, check validity and set defaults""" + parser = optparse.OptionParser(usage=usage) + parser.add_option('-p','--port', dest="port", default='', help="The port to connect to") + parser.add_option('-m','--machine', dest="machine", default='', help="The computer to connect to") + 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)") + parser.add_option('-u','--user', dest="user", default='', help="[Distant Mode] The user on the computer to connect to") + parser.add_option('-i','--infiles', dest="infiles", default=[], action="callback", callback=vararg_callback, + help="[Distant Mode] The list of input files (blank separated) used in the Python script") + parser.add_option('-o','--outfiles', dest="outfiles", default=[], action="callback", callback=vararg_callback, + help="[Distant Mode] The list of output files (blank separated) generated by the Python script") + + args=sys.argv[1:] + + script="" + if args: + script=args.pop() + + options, args = parser.parse_args(args) + + #check the arguments + if not os.path.exists(script): + print "ERROR: the script file is mandatory" + sys.exit(1) + + machine=options.machine + port=options.port + user=options.user + infiles = options.infiles + outfiles = options.outfiles + directory=options.directory + + mode="local" + + if machine: + here=get_hostname() + if machine != here and machine != "localhost": + #SALOME server is on a remote computer + mode="remote" + + if not user: + print "ERROR: the remote execution needs -u user argument" + sys.exit(1) + + if not os.path.exists(os.path.join(appli_local,"runSession")): + if not directory: + print "ERROR: the remote execution without SALOME installation needs -d directory argument" + sys.exit(1) + + return mode,user,machine,port,directory,infiles,outfiles,script + +def copy_files(user,machine,script,infiles,outfiles,directory): + """modify script, copy files to remote computer and return lists of copied files""" + + namescript=os.path.basename(script) + logname=os.getenv("LOGNAME",user) + tmp_script="/tmp/%s_%s_%s" % (logname,os.getpid(),namescript) + fscript=open(script) + script_text=fscript.read() + fscript.close() + + list_infiles=[] + list_outfiles=[] + + n=0 + for infile in infiles: + # generate a temporary file name + namefile=os.path.basename(infile) + tmp_file="/tmp/%s_%s_i%s_%s" % (logname,os.getpid(),n,namefile) + + #modify the salome script + script_text = re.sub(infile,tmp_file,script_text) + + # copy the infile to the remote server (into /tmp) + cmd="scp %s %s@%s:%s" % (infile,user,machine,tmp_file) + print "[ SCP ]",cmd + os.system(cmd) + + list_infiles.append(tmp_file) + n=n+1 + + n=0 + for outfile in outfiles: + # generate a temporary file name + namefile=os.path.basename(outfile) + tmp_file="/tmp/%s_%s_o%s_%s" % (logname,os.getpid(),n,namefile) + + #modify the salome script + script_text = re.sub(outfile,tmp_file,script_text) + + list_outfiles.append(tmp_file) + n=n+1 + + fscript=open(tmp_script,'w') + fscript.write(script_text) + fscript.close() + + if directory: + #copy the salome script on the remote server + cmd="scp %s %s@%s:%s" % (tmp_script,user,machine,tmp_script) + print "[ SCP ]",cmd + os.system(cmd) + + return list_infiles, list_outfiles, tmp_script + +def main(): + + mode,user,machine,port,directory,infiles,outfiles,script = parse_args() + + tmp_script=script + + print "mode:",mode + + if mode == "remote": + list_infiles, list_outfiles, tmp_script = copy_files(user,machine,script,infiles,outfiles,directory) + + ################################################# + # Execution # + ################################################# + if directory: + print "[ REMOTE ]" + + # execute runSession from the remote SALOME application + cmd="ssh %s@%s %s/runSession " % (user,machine,directory) + if port: + cmd=cmd+"-p %s "%port + cmd = cmd +"python " + tmp_script + print '[ SSH ] ' + cmd + os.system(cmd) + + else: + print "[ LOCAL ]" + + # execute runSession from the local SALOME application + cmd="%s/runSession " % appli_local + if machine: + cmd=cmd+"-m %s "%machine + if port: + cmd=cmd+"-p %s "%port + cmd = cmd +"python " + tmp_script + print '[ SH ] ' + cmd + os.system(cmd) + + ################################################# + # Get remote files and clean # + ################################################# + if mode == "remote": + temp_files=list_infiles+list_outfiles + + #get the outfiles + for outfile in outfiles: + remote_outfile=list_outfiles.pop(0) + cmd="scp %s@%s:%s %s" %(user,machine,remote_outfile,outfile) + print "[ SCP ] "+cmd + os.system(cmd) + + #clean temporary files + cmd="ssh %s@%s \\rm -f %s" % (user,machine," ".join(temp_files)) + print '[ SSH ] ' + cmd + os.system(cmd) + os.remove(tmp_script) + +if __name__ == '__main__': + main() +