Salome HOME
CCAR: add a new script (runSalomeScript) in SALOME application
authorcaremoli <caremoli>
Fri, 1 Oct 2010 08:38:46 +0000 (08:38 +0000)
committercaremoli <caremoli>
Fri, 1 Oct 2010 08:38:46 +0000 (08:38 +0000)
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

bin/appli_gen.py
bin/appliskel/runSalomeScript [new file with mode: 0755]

index 9ee543a27f155d51c3a2d3a3acf0e071bc38146d..f6e5bcc7e70062fcafd384ef826ba0b93a69b11b 100644 (file)
@@ -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 (executable)
index 0000000..752f420
--- /dev/null
@@ -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()
+