]> SALOME platform Git repositories - tools/libbatch.git/commitdiff
Salome HOME
Merged from BR_AR
authorbarate <barate>
Mon, 14 Dec 2009 16:17:53 +0000 (16:17 +0000)
committerbarate <barate>
Mon, 14 Dec 2009 16:17:53 +0000 (16:17 +0000)
36 files changed:
src/CMakeLists.txt
src/Core/Batch_BatchManager_eClient.cxx
src/Core/Batch_BatchManager_eClient.hxx
src/Core/Batch_CommunicationProtocol.cxx
src/Core/Batch_CommunicationProtocolRSH.cxx
src/Core/Batch_CommunicationProtocolSH.cxx
src/Core/Batch_CommunicationProtocolSSH.cxx
src/Core/Batch_Defines.hxx
src/Core/Batch_FactBatchManager_eClient.hxx
src/Core/Batch_Versatile.hxx
src/Core/Test/SimpleParser.cxx
src/Core/Test/Test_SimpleParser.cxx
src/LSF/Batch_BatchManager_eLSF.cxx
src/LSF/Batch_BatchManager_eLSF.hxx
src/LSF/Batch_FactBatchManager_eLSF.cxx
src/LSF/Batch_FactBatchManager_eLSF.hxx
src/Local/Batch_BatchManager_Local.cxx
src/Local/Batch_BatchManager_Local.hxx
src/PBS/Batch_BatchManager_ePBS.cxx
src/PBS/Batch_BatchManager_ePBS.hxx
src/PBS/Batch_FactBatchManager_ePBS.cxx
src/PBS/Batch_FactBatchManager_ePBS.hxx
src/PBS/Test/CMakeLists.txt
src/PBS/Test/Test_PBS.cxx
src/PBS/Test/Test_ePBS.cxx [new file with mode: 0644]
src/PBS/Test/test-script.sh
src/SGE/Batch_BatchManager_eSGE.cxx
src/SGE/Batch_FactBatchManager_eSGE.cxx
src/SGE/Batch_FactBatchManager_eSGE.hxx
src/SSH/Batch_BatchManager_eSSH.cxx [new file with mode: 0644]
src/SSH/Batch_BatchManager_eSSH.hxx [new file with mode: 0644]
src/SSH/Batch_FactBatchManager_eSSH.cxx [new file with mode: 0644]
src/SSH/Batch_FactBatchManager_eSSH.hxx [new file with mode: 0644]
src/SSH/Batch_JobInfo_eSSH.cxx [new file with mode: 0644]
src/SSH/Batch_JobInfo_eSSH.hxx [new file with mode: 0644]
src/SSH/CMakeLists.txt [new file with mode: 0644]

index fe08a3caf0e6c02bae62a00155120e6dac0e66b4..3a5d9d5199d7db53857e78fb4d360ecd555fd880 100644 (file)
@@ -53,6 +53,7 @@ ENDIF (BUILD_LOCAL_SUBMISSION)
 add_subdirectory (LSF)
 add_subdirectory (PBS)
 add_subdirectory (SGE)
+add_subdirectory (SSH)
 
 # Make a copy of the built value and clear the built value for the next run of cmake
 SET(SRC_FILES ${SRC_FILES_BUILD} CACHE INTERNAL "")
@@ -65,6 +66,7 @@ SET(HDR_FILES_BUILD CACHE INTERNAL "")
 add_library (Batch SHARED ${SRC_FILES})
 
 include_directories(${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Core)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Local)
 target_link_libraries(Batch ${PTHREAD_LIBRARY})
 
 IF (WIN32)
index c386f2a5ce033aba7315f9d360474135349cb288..81f03a34ed54cc3a00659ef7b3b2907c880c5229 100644 (file)
@@ -37,6 +37,8 @@
 #include <fstream>
 #include <sstream>
 
+#include <stdlib.h>
+
 #ifdef WIN32
 #include <direct.h>
 #include <io.h>
@@ -69,7 +71,8 @@ namespace Batch {
   // Destructeur
   BatchManager_eClient::~BatchManager_eClient()
   {
-    delete _mpiImpl;
+    if (_mpiImpl)
+      delete _mpiImpl;
   }
 
   void BatchManager_eClient::exportInputFiles(const Job& job)
@@ -80,7 +83,7 @@ namespace Batch {
     Versatile::iterator Vit;
     _username = string(params[USER]);
 
-    string subCommand = string("mkdir -p ") + string(params[TMPDIR]);
+    string subCommand = string("mkdir -p ") + string(params[TMPDIR]) + string("/logs");
     string command = _protocol.getExecCommand(subCommand, _hostname, _username);
     cerr << command.c_str() << endl;
     status = system(command.c_str());
@@ -147,6 +150,7 @@ namespace Batch {
     Parametre params = job.getParametre();
     Versatile V = params[OUTFILE];
     Versatile::iterator Vit;
+    _username = string(params[USER]);
 
     for(Vit=V.begin(); Vit!=V.end(); Vit++) {
       CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
@@ -164,6 +168,17 @@ namespace Batch {
       }
     }
 
+    // Copy logs
+    int status = _protocol.copyFile(string(params[TMPDIR]) + string("/logs"), _hostname, _username,
+                                   directory, "", "");
+    if (status) {
+      std::string mess("Copy logs directory failed ! status is :");
+      ostringstream status_str;
+      status_str << status;
+      mess += status_str.str();
+      cerr << mess << endl;
+    }
+
   }
 
   MpiImpl *BatchManager_eClient::FactoryMpiImpl(string mpiImpl) throw(EmulationException)
@@ -181,7 +196,7 @@ namespace Batch {
     else if(mpiImpl == "prun")
       return new MpiImpl_PRUN();
     else if(mpiImpl == "nompi")
-      throw EmulationException("you must specify an mpi implementation for batch manager");
+      return NULL;
     else{
       ostringstream oss;
       oss << mpiImpl << " : not yet implemented";
index 74e8cbc02032070c817eab5db51263eb8f86c932..9a043b9a3a6ee55ec2b772829c69a10c7a5694bf 100644 (file)
@@ -44,7 +44,7 @@ namespace Batch {
 
   class Job;
 
-  class BATCH_EXPORT BatchManager_eClient : public BatchManager
+  class BATCH_EXPORT BatchManager_eClient : virtual public BatchManager
   {
   public:
     // Constructeur et destructeur
index da4d49ce7d7f91d79a46077a497166a08467a1ab..530a5f3765495e98246f67c089a82dd2eb4340f1 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <stdlib.h>
 #include <iostream>
+#include <stdlib.h>
 
 #include <Batch_config.h>
 
@@ -126,9 +127,9 @@ namespace Batch {
     for (unsigned int i=0 ; i<commandArgs.size() ; i++) {
       if (i != 0) commandStr += " ";
 
-      // if the argument contains spaces, we surround it with double quotes
+      // if the argument contains spaces, we surround it with quotes
       if (commandArgs[i].find(' ') != string::npos) {
-        commandStr += string("\"") + commandArgs[i] + "\"";
+        commandStr += string("\'") + commandArgs[i] + "\'";
       } else {
         commandStr += commandArgs[i];
       }
index 5fabe63fe5a940260dc4d5641d9389d40182b620..e2927f4c54afef7e5fd0538ff77c5581096accfa 100644 (file)
@@ -102,6 +102,7 @@ namespace Batch {
     fullDestination += destinationPath;
 
     cmd.push_back(RCP_COMMAND);
+    cmd.push_back("-r");
     cmd.push_back(fullSource);
     cmd.push_back(fullDestination);
 
index 2c5bfd01472d1c3918584ad0a4949ae6f23b0bd6..965c627642d75aaaf07e6c05fbb144f8d7711e2f 100644 (file)
@@ -75,6 +75,9 @@ namespace Batch {
   {
     vector<string> cmd;
     cmd.push_back(CP_COMMAND);
+#ifndef WIN32
+    cmd.push_back("-r");
+#endif
     cmd.push_back(fixPath(sourcePath));
     cmd.push_back(fixPath(destinationPath));
     return cmd;
index a9c65903e0ac2bd5a16be4e7534e3324aff69a4d..e6b4198106337b288e20efadf2a079e9624f39dd 100644 (file)
@@ -67,23 +67,28 @@ namespace Batch {
       if (sourceUser.size() != 0) {
         fullSource += sourceUser + "@";
       }
-      fullSource += sourceHost + ":";
+      fullSource += sourceHost + ":'";
     }
     fullSource += sourcePath;
+    if (sourceHost.size() != 0)
+      fullSource += "'";
 
     string fullDestination;
     if (destinationHost.size() != 0) {
       if (destinationUser.size() != 0) {
         fullDestination += destinationUser + "@";
       }
-      fullDestination += destinationHost + ":";
+      fullDestination += destinationHost + ":'";
     }
     fullDestination += destinationPath;
+    if (destinationHost.size() != 0)
+      fullDestination += "'";
 
     // Option -p is used to keep the same permissions for the destination file
     // (particularly useful to keep scripts executable when copying them)
     cmd.push_back(SCP_COMMAND);
     cmd.push_back("-p");
+    cmd.push_back("-r");
     cmd.push_back(fullSource);
     cmd.push_back(fullDestination);
 
index ab2a23716a7d82dee9cd6bf48297555b3f73f929..587e7d78759652b6bef5c9404a93bf1cc2c1556b 100644 (file)
 # define BATCH_EXPORT
 #endif
 
+#ifdef WIN32
+#define BATCH_CHMOD(name, mode) _chmod(name, mode)
+#else
+#define BATCH_CHMOD(name, mode) chmod(name, mode)
+#endif
+
 #endif
index d047f559f33022b256063f3753f3d7eb29ec8c30..0e4274f014bb44d87373de9f630f532913c3f42f 100644 (file)
@@ -49,7 +49,8 @@ namespace Batch {
 
     virtual Batch::BatchManager_eClient * operator() (const char * hostname,
                                                       CommunicationProtocolType protocolType,
-                                                      const char * mpi) const = 0;
+                                                      const char * mpi,
+                                                     int nb_proc_per_node = 1) const = 0;
 
   protected:
 
index 6a3a9459423b89e944e388f8630949e59270bbe6..2f9f944a672f3651cba57655ca799edfe44df987 100644 (file)
@@ -105,9 +105,9 @@ namespace Batch {
     std::string getName() const;
     void setName(const std::string & name);
 
-  protected:
                // Efface tous les elements internes de l'objet
     virtual void eraseAll();
+  protected:
 
     DiscriminatorType _discriminator; // type de l'element interne
     size_type _maxsize; // nombre max d'elements internes
index 83f647854d8c1c30c4af07ae2fbf13958735b427..9942576de54aff206f1b9cf21cf8190b24e9ca9c 100644 (file)
@@ -141,7 +141,6 @@ int SimpleParser::getValueAsInt(const string & key) const throw(ParserException)
 
 ostream & operator <<(ostream & os, const SimpleParser & parser) throw()
 {
-  os << "Configuration map:" << endl;
   if (parser._configmap.empty()) {
     os << "Empty map" << endl;
   } else {
index bb446ef565d4a631fab2e0178fc7f443d9b01daa..6e60fbcdd89b7744e5443893bd5f29336b2729c0 100644 (file)
@@ -55,6 +55,7 @@ int main(int argc, char** argv)
   }
 
   // Print the configuration
+  cout << "Configuration map:" << endl;
   cout << parser << endl;
 
   return 0;
index a74a4b249a247e67af145957d2be35d4a1025225..2f34d04299460e999afa2a708e4b48cba156d60a 100644 (file)
@@ -38,6 +38,9 @@
 #include <string>
 #include <sys/stat.h>
 
+#include <stdlib.h>
+#include <string.h>
+
 #ifdef WIN32
 #include <io.h>
 #else
@@ -53,7 +56,8 @@ namespace Batch {
 
   BatchManager_eLSF::BatchManager_eLSF(const FactBatchManager * parent, const char * host,
                                        CommunicationProtocolType protocolType, const char * mpiImpl)
-  : BatchManager_eClient(parent, host, protocolType, mpiImpl)
+  : BatchManager_eClient(parent, host, protocolType, mpiImpl),
+    BatchManager(parent, host)
   {
     // Nothing to do
   }
@@ -69,36 +73,42 @@ namespace Batch {
   {
     int status;
     Parametre params = job.getParametre();
-    const std::string dirForTmpFiles = params[TMPDIR];
+    const std::string workDir = params[WORKDIR];
     const string fileToExecute = params[EXECUTABLE];
-    std::string fileNameToExecute;
-    if( fileToExecute.size() > 0 ){
-      string::size_type p1 = fileToExecute.find_last_of("/");
-      string::size_type p2 = fileToExecute.find_last_of(".");
-      fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
-    }
-    else
-      fileNameToExecute = "command";
+    string::size_type p1 = fileToExecute.find_last_of("/");
+    string::size_type p2 = fileToExecute.find_last_of(".");
+    std::string fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
 
     // export input files on cluster
+    cerr << "Export des fichiers en entree" << endl;
     exportInputFiles(job);
 
     // build batch script for job
+    cerr << "Construction du script de batch" << endl;
     buildBatchScript(job);
+    cerr << "Script envoye" << endl;
 
     // define name of log file (local)
     string logFile = generateTemporaryFileName("LSF-submitlog");
 
     // define command to submit batch
-    string subCommand = string("cd ") + dirForTmpFiles + "; bsub < " +
-                        fileNameToExecute + "_Batch.sh";
+    string subCommand = string("cd ") + workDir + "; bsub < " + fileNameToExecute + "_Batch.sh";
     string command = _protocol.getExecCommand(subCommand, _hostname, _username);
     command += " > ";
     command += logFile;
+    command += " 2>&1";
     cerr << command.c_str() << endl;
     status = system(command.c_str());
     if(status)
-      throw EmulationException("Error of connection on remote host");
+    {
+      ifstream error_message(logFile.c_str());
+      std::string mess;
+      std::string temp;
+      while(std::getline(error_message, temp))
+       mess += temp;
+      error_message.close();
+      throw EmulationException("Error of connection on remote host, error was: " + mess);
+    }
 
     // read id of submitted job in log file
     char line[128];
@@ -201,33 +211,41 @@ namespace Batch {
   {
 #ifndef WIN32 //TODO: need for porting on Windows
     Parametre params = job.getParametre();
-    Environnement env = job.getEnvironnement();
-    const int nbproc = params[NBPROC];
-    const long edt = params[MAXWALLTIME];
-    const long mem = params[MAXRAMSIZE];
-    const string workDir = params[WORKDIR];
-    const std::string dirForTmpFiles = params[TMPDIR];
-    const string fileToExecute = params[EXECUTABLE];
-    const string home = params[HOMEDIR];
-    const std::string queue = params[QUEUE];
-    std::string rootNameToExecute;
-    std::string fileNameToExecute;
-    std::string filelogtemp;
-    if( fileToExecute.size() > 0 ){
-      string::size_type p1 = fileToExecute.find_last_of("/");
-      string::size_type p2 = fileToExecute.find_last_of(".");
-      rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
-      char* basec=strdup(fileToExecute.c_str());
-      fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(basec));
-      free(basec);
-
-      int idx = dirForTmpFiles.find("Batch/");
-      filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
-    }
-    else{
-      rootNameToExecute = "command";
-    }
 
+    // Job Parameters
+    string workDir       = "";
+    string fileToExecute = "";
+    int nbproc          = 0;
+    int edt             = 0;
+    int mem              = 0;
+    string queue         = "";
+
+    // Mandatory parameters
+    if (params.find(WORKDIR) != params.end()) 
+      workDir = params[WORKDIR].str();
+    else 
+      throw EmulationException("params[WORKDIR] is not defined ! Please defined it, cannot submit this job");
+    if (params.find(EXECUTABLE) != params.end()) 
+      fileToExecute = params[EXECUTABLE].str();
+    else 
+      throw EmulationException("params[EXECUTABLE] is not defined ! Please defined it, cannot submit this job");
+
+    // Optional parameters
+    if (params.find(NBPROC) != params.end()) 
+      nbproc = params[NBPROC];
+    if (params.find(MAXWALLTIME) != params.end()) 
+      edt = params[MAXWALLTIME];
+    if (params.find(MAXRAMSIZE) != params.end()) 
+      mem = params[MAXRAMSIZE];
+    if (params.find(QUEUE) != params.end()) 
+      queue = params[QUEUE].str();
+
+    string::size_type p1 = fileToExecute.find_last_of("/");
+    string::size_type p2 = fileToExecute.find_last_of(".");
+    string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+    string fileNameToExecute = fileToExecute.substr(p1+1);
+    // Create batch submit file
     ofstream tempOutputFile;
     std::string TmpFileName = createAndOpenTemporaryFile("LSF-script", tempOutputFile);
 
@@ -239,43 +257,53 @@ namespace Batch {
     if( mem > 0 )
       tempOutputFile << "#BSUB -M " << mem*1024 << endl ;
     tempOutputFile << "#BSUB -n " << nbproc << endl ;
-    if( fileToExecute.size() > 0 ){
-      tempOutputFile << "#BSUB -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ;
-      tempOutputFile << "#BSUB -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ;
-    }
-    else{
-      tempOutputFile << "#BSUB -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ;
-      tempOutputFile << "#BSUB -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ;
-    }
-    if( workDir.size() > 0 )
-      tempOutputFile << "cd " << workDir << endl ;
-    if( fileToExecute.size() > 0 ){
-      tempOutputFile << _mpiImpl->boot("",nbproc);
-      tempOutputFile << _mpiImpl->run("",nbproc,fileNameToExecute);
-      tempOutputFile << _mpiImpl->halt();
-    }
+    size_t pos = workDir.find("$HOME");
+    string baseDir;
+    if( pos != string::npos )
+      baseDir = getHomeDir(workDir) + workDir.substr(pos+5,workDir.length()-5);
     else{
-      tempOutputFile << "source " << env["SOURCEFILE"] << endl ;
-      tempOutputFile << env["COMMAND"];
+      pos = workDir.find("~");
+      if( pos != string::npos )
+       baseDir = getHomeDir(workDir) + workDir.substr(pos+1,workDir.length()-1);
+      else
+       baseDir = workDir;
     }
-
+    tempOutputFile << "#BSUB -o " << baseDir << "/logs/output.log." << rootNameToExecute << endl ;
+    tempOutputFile << "#BSUB -e " << baseDir << "/logs/error.log." << rootNameToExecute << endl ;
+
+    tempOutputFile << "cd " << workDir << endl ;
+
+    // generate nodes file
+    tempOutputFile << "bool=0" << endl;
+    tempOutputFile << "for i in $LSB_MCPU_HOSTS; do" << endl;
+    tempOutputFile << "  if test $bool = 0; then" << endl;
+    tempOutputFile << "    n=$i" << endl;
+    tempOutputFile << "    bool=1" << endl;
+    tempOutputFile << "  else" << endl;
+    tempOutputFile << "    for ((j=0;j<$i;j++)); do" << endl;
+    tempOutputFile << "      echo $n >> nodesFile" << endl;
+    tempOutputFile << "    done" << endl;
+    tempOutputFile << "    bool=0" << endl;
+    tempOutputFile << "  fi" << endl;
+    tempOutputFile << "done" << endl;
+
+    // Abstraction of PBS_NODEFILE - TODO
+    tempOutputFile << "export LIBBATCH_NODEFILE=nodesFile" << endl;
+
+    // Launch the executable
+    tempOutputFile << "./" + fileNameToExecute << endl;
     tempOutputFile.flush();
     tempOutputFile.close();
-#ifdef WIN32
-    _chmod(
-#else
-    chmod(
-#endif
-      TmpFileName.c_str(), 0x1ED);
-    cerr << TmpFileName.c_str() << endl;
+
+    BATCH_CHMOD(TmpFileName.c_str(), 0x1ED);
+    cerr << "Batch script file generated is: " << TmpFileName.c_str() << endl;
 
     int status = _protocol.copyFile(TmpFileName, "", "",
-                                    dirForTmpFiles + "/" + rootNameToExecute + "_Batch.sh",
+                                    workDir + "/" + rootNameToExecute + "_Batch.sh",
                                     _hostname, _username);
     if (status)
       throw EmulationException("Error of connection on remote host");
 
-    remove(TmpFileName.c_str());
 #endif
 
   }
@@ -293,4 +321,24 @@ namespace Batch {
     return oss.str();
   }
 
+  std::string BatchManager_eLSF::getHomeDir(std::string tmpdir)
+  {
+    std::string home;
+    int idx = tmpdir.find("Batch/");
+    std::string filelogtemp = tmpdir.substr(idx+6, tmpdir.length());
+    filelogtemp = "/tmp/logs" + filelogtemp + "_home";
+
+    string subCommand = string("echo $HOME");
+    string command = _protocol.getExecCommand(subCommand, _hostname, _username) + " > " + filelogtemp;
+    cerr << command.c_str() << endl;
+    int status = system(command.c_str());
+    if (status)
+      throw EmulationException("Error of launching home command on remote host");
+
+    std::ifstream file_home(filelogtemp.c_str());
+    std::getline(file_home, home);
+    file_home.close();
+    return home;
+  }
+
 }
index 09a7f1c3bf424aa434d8bf1a192fd1af88deabda..6d48a0eb5065572f58815fefe27129979b545a2d 100644 (file)
@@ -72,6 +72,8 @@ namespace Batch {
 
   private:
 
+    std::string getHomeDir(std::string tmpdir);
+
 #ifdef SWIG
   public:
     // Recupere le l'identifiant d'un job deja soumis au BatchManager
index f79992225f822b3595ed24465979939efe0232a5..afece453c4d98fd85ebc9773086d41fd8c4126c5 100644 (file)
@@ -54,7 +54,8 @@ namespace Batch {
 
   BatchManager_eClient * FactBatchManager_eLSF::operator() (const char * hostname,
                                                             CommunicationProtocolType protocolType,
-                                                            const char * mpiImpl) const
+                                                            const char * mpiImpl,
+                                                           int nb_proc_per_node) const
   {
     // MESSAGE("Building new BatchManager_LSF on host '" << hostname << "'");
     return new BatchManager_eLSF(this, hostname, protocolType, mpiImpl);
index 9144f649f5d289ccec555d66feca8b56885e4e22..3f3c604e4261b8189634f78a42e196c3f6d6fce0 100644 (file)
@@ -47,7 +47,8 @@ namespace Batch {
     virtual BatchManager * operator() (const char * hostname) const;
     virtual BatchManager_eClient * operator() (const char * hostname,
                                                CommunicationProtocolType protocolType,
-                                               const char * mpiImpl) const;
+                                               const char * mpiImpl,
+                                              int nb_proc_per_node = 1) const;
 
   protected:
 
index 4166e3f80a2e5bcfced8ef3c4ad15a50de93dd5c..aadbcdce76ddb81e0e0b0565526b1ee68f330873 100644 (file)
@@ -443,6 +443,9 @@ namespace Batch {
         string local    = cp.getLocal();
         string remote   = cp.getRemote();
 
+       std::cerr << workdir << std::endl;
+       std::cerr << remote << std::endl;
+
         int status = p_ta->getBatchManager().getProtocol().copyFile(local, "", "",
                                                                     workdir + "/" + remote,
                                                                     executionhost, user);
@@ -463,6 +466,8 @@ namespace Batch {
     // On forke/exec un nouveau process pour pouvoir controler le fils
     // (plus finement qu'avec un appel system)
     // int rc = system(commande.c_str());
+    //char *const parmList[] = {"/usr/bin/ssh", "localhost", "-l", "aribes", "sleep 10 && echo end", NULL};
+    //execv("/usr/bin/ssh", parmList);
 #ifdef WIN32
     child = p_ta->launchWin32ChildProcess();
     p_ta->pere(child);
@@ -594,6 +599,14 @@ namespace Batch {
       int child_rc = 0;
       pid_t child_wait_rc = waitpid(child, &child_rc, WNOHANG /* | WUNTRACED */);
       if (child_wait_rc > 0) {
+        UNDER_LOCK( cout << "Status is: " << WIFEXITED( child_rc) << endl);
+        UNDER_LOCK( cout << "Status is: " << WEXITSTATUS( child_rc) << endl);
+        UNDER_LOCK( cout << "Status is: " << WIFSIGNALED( child_rc) << endl);
+        UNDER_LOCK( cout << "Status is: " << WTERMSIG( child_rc) << endl);
+        UNDER_LOCK( cout << "Status is: " << WCOREDUMP( child_rc) << endl);
+        UNDER_LOCK( cout << "Status is: " << WIFSTOPPED( child_rc) << endl);
+        UNDER_LOCK( cout << "Status is: " << WSTOPSIG( child_rc) << endl);
+        UNDER_LOCK( cout << "Status is: " << WIFCONTINUED( child_rc) << endl);
         if (WIFSTOPPED(child_rc)) {
           // NOTA : pour rentrer dans cette section, il faut que le flag WUNTRACED
           // soit positionne dans l'appel a waitpid ci-dessus. Ce flag est couramment
@@ -740,6 +753,10 @@ namespace Batch {
     Parametre param = _job.getParametre();
     Parametre::iterator it;
 
+      //char *const parmList[] = {"/usr/bin/ssh", "localhost", "-l", "aribes", "sleep 1 && echo end", NULL};
+      //int result = execv("/usr/bin/ssh", parmList);
+      //UNDER_LOCK( cout << "*** debug_command = " << result << endl );
+      //UNDER_LOCK( cout << "*** debug_command = " << strerror(errno) << endl );
     try {
 
       // EXECUTABLE is MANDATORY, if missing, we exit with failure notification
@@ -761,6 +778,7 @@ namespace Batch {
       argv[command.size()] = NULL;
 
       UNDER_LOCK( cout << "*** debug_command = " << comstr << endl );
+      UNDER_LOCK( cout << "*** debug_command = " << argv[0] << endl );
 
       // Create the environment for the new process. Note (RB): Here we change the environment for
       // the process launched in local. It would seem more logical to set the environment for the
@@ -784,6 +802,10 @@ namespace Batch {
         envp[i] = NULL;
       }
 
+      //char *const parmList[] = {"/usr/bin/ssh", "localhost", "-l", "aribes", "sleep 1 && echo end", NULL};
+      //int result = execv("/usr/bin/ssh", parmList);
+      //UNDER_LOCK( cout << "*** debug_command = " << result << endl );
+      //UNDER_LOCK( cout << "*** debug_command = " << strerror(errno) << endl );
 
 
 
@@ -813,6 +835,10 @@ namespace Batch {
       }
 
 
+      //char *const parmList[] = {"/usr/bin/ssh", "localhost", "-l", "aribes", "sleep 1 && echo end", NULL};
+      //int result = execv("/usr/bin/ssh", parmList);
+      //UNDER_LOCK( cout << "*** debug_command = " << result << endl );
+      //UNDER_LOCK( cout << "*** debug_command = " << strerror(errno) << endl );
 
       // On cree une session pour le fils de facon a ce qu'il ne soit pas
       // detruit lorsque le shell se termine (le shell ouvre une session et
@@ -827,8 +853,8 @@ namespace Batch {
 
 
       // On execute la commande du fils
-      execve(argv[0], argv, envp);
-
+      int result = execve(argv[0], argv, envp);
+      UNDER_LOCK( cout << "*** debug_command = " << strerror(errno) << endl );
       // No need to deallocate since nothing happens after a successful exec
 
       // Normalement on ne devrait jamais arriver ici
index d6fc0f75fd1b54ba71126e969697c0cb55b39908..bae659200f33e9c03703d48475c95563d96a0864 100644 (file)
@@ -58,7 +58,7 @@ namespace Batch {
 
   class FactBatchManager;
 
-  class BATCH_EXPORT BatchManager_Local : public BatchManager
+  class BATCH_EXPORT BatchManager_Local : virtual public BatchManager
   {
   private:
 #ifdef WIN32
index 38593b32c1f093150a57d57a1e7b0e484e0c4d91..fd01bc0a205fb8d34f4f3ade5cd7c2638d9b36a4 100644 (file)
@@ -22,7 +22,7 @@
 /*
  * BatchManager_ePBS.cxx : emulation of PBS client
  *
- * Auteur : Bernard SECHER - CEA DEN
+ * Auteur : Bernard SECHER - CEA DEN, André RIBES - EDF R&D
  * Mail   : mailto:bernard.secher@cea.fr
  * Date   : Thu Apr 24 10:17:22 2008
  * Projet : PAL Salome
@@ -37,6 +37,8 @@
 #include <sstream>
 #include <sys/stat.h>
 
+#include <stdlib.h>
+#include <string.h>
 #include <Batch_config.h>
 
 #ifdef MSVC
@@ -53,10 +55,13 @@ using namespace std;
 namespace Batch {
 
   BatchManager_ePBS::BatchManager_ePBS(const FactBatchManager * parent, const char * host,
-                                       CommunicationProtocolType protocolType, const char * mpiImpl)
-    : BatchManager_eClient(parent, host, protocolType, mpiImpl)
+                                       CommunicationProtocolType protocolType, const char * mpiImpl, 
+                                      int nb_proc_per_node)
+    : BatchManager_eClient(parent, host, protocolType, mpiImpl),
+    BatchManager(parent, host)
   {
     // Nothing to do
+    _nb_proc_per_node = nb_proc_per_node;
   }
 
   // Destructeur
@@ -70,7 +75,7 @@ namespace Batch {
   {
     int status;
     Parametre params = job.getParametre();
-    const std::string dirForTmpFiles = params[TMPDIR];
+    const std::string workDir = params[WORKDIR];
     const string fileToExecute = params[EXECUTABLE];
     string::size_type p1 = fileToExecute.find_last_of("/");
     string::size_type p2 = fileToExecute.find_last_of(".");
@@ -86,15 +91,23 @@ namespace Batch {
     string logFile = generateTemporaryFileName("PBS-submitlog");
 
     // define command to submit batch
-    string subCommand = string("cd ") + dirForTmpFiles + "; qsub " +
-                        fileNameToExecute + "_Batch.sh";
+    string subCommand = string("cd ") + workDir + "; qsub " + fileNameToExecute + "_Batch.sh";
     string command = _protocol.getExecCommand(subCommand, _hostname, _username);
     command += " > ";
     command += logFile;
+    command += " 2>&1";
     cerr << command.c_str() << endl;
     status = system(command.c_str());
     if(status)
-      throw EmulationException("Error of connection on remote host");
+    {
+      ifstream error_message(logFile.c_str());
+      std::string mess;
+      std::string temp;
+      while(std::getline(error_message, temp))
+       mess += temp;
+      error_message.close();
+      throw EmulationException("Error of connection on remote host, error was: " + mess);
+    }
 
     // read id of submitted job in log file
     ifstream idfile(logFile.c_str());
@@ -197,91 +210,89 @@ namespace Batch {
 
   void BatchManager_ePBS::buildBatchScript(const Job & job)
   {
+    std::cerr << "BuildBatchScript" << std::endl;
     Parametre params = job.getParametre();
     Environnement env = job.getEnvironnement();
-    const long nbproc = params[NBPROC];
-    const long edt = params[MAXWALLTIME];
-    const long mem = params[MAXRAMSIZE];
-    const string workDir = params[WORKDIR];
-    const std::string dirForTmpFiles = params[TMPDIR];
-    const string fileToExecute = params[EXECUTABLE];
-    const string home = params[HOMEDIR];
-    const std::string queue = params[QUEUE];
-    std::string rootNameToExecute;
-    std::string fileNameToExecute;
-    std::string filelogtemp;
-    if( fileToExecute.size() > 0 ){
-      string::size_type p1 = fileToExecute.find_last_of("/");
-      string::size_type p2 = fileToExecute.find_last_of(".");
-      rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
-
-#ifdef MSVC
-      char fname[_MAX_FNAME];
-      char ext[_MAX_EXT];
-      _splitpath_s(fileToExecute.c_str(), NULL, 0, NULL, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
-      string execBaseName = string(fname) + ext;
-#else
-      char* basec=strdup(fileToExecute.c_str());
-      string execBaseName = string(basename(basec));
-      free(basec);
-#endif
 
-      fileNameToExecute = "~/" + dirForTmpFiles + "/" + execBaseName;
+    // Job Parameters
+    string workDir       = "";
+    string fileToExecute = "";
+    int nbproc          = 0;
+    int edt             = 0;
+    int mem              = 0;
+    string queue         = "";
+
+    // Mandatory parameters
+    if (params.find(WORKDIR) != params.end()) 
+      workDir = params[WORKDIR].str();
+    else 
+      throw EmulationException("params[WORKDIR] is not defined ! Please defined it, cannot submit this job");
+    if (params.find(EXECUTABLE) != params.end()) 
+      fileToExecute = params[EXECUTABLE].str();
+    else 
+      throw EmulationException("params[EXECUTABLE] is not defined ! Please defined it, cannot submit this job");
+
+    // Optional parameters
+    if (params.find(NBPROC) != params.end()) 
+      nbproc = params[NBPROC];
+    if (params.find(MAXWALLTIME) != params.end()) 
+      edt = params[MAXWALLTIME];
+    if (params.find(MAXRAMSIZE) != params.end()) 
+      mem = params[MAXRAMSIZE];
+    if (params.find(QUEUE) != params.end()) 
+      queue = params[QUEUE].str();
 
-      int idx = dirForTmpFiles.find("Batch/");
-      filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
-    }
-    else{
-      rootNameToExecute = "command";
-    }
+    string::size_type p1 = fileToExecute.find_last_of("/");
+    string::size_type p2 = fileToExecute.find_last_of(".");
+    string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+    string fileNameToExecute = fileToExecute.substr(p1+1);
 
+    // Create batch submit file
     ofstream tempOutputFile;
     std::string TmpFileName = createAndOpenTemporaryFile("PBS-script", tempOutputFile);
 
     tempOutputFile << "#! /bin/sh -f" << endl;
+    if (nbproc > 0)
+    {
+      // Division - arrondi supérieur
+      int nodes_requested = (nbproc + _nb_proc_per_node -1) / _nb_proc_per_node;
+      tempOutputFile << "#PBS -l nodes=" << nodes_requested << ":ppn=" << _nb_proc_per_node << endl;
+    }
     if (queue != "")
-      tempOutputFile << "#BSUB -q " << queue << endl;
+      tempOutputFile << "#PBS -q " << queue << endl;
     if( edt > 0 )
-      tempOutputFile << "#PBS -l walltime=" << edt*60 << endl ;
+      tempOutputFile << "#PBS -l walltime=" << edt*60 << endl;
     if( mem > 0 )
-      tempOutputFile << "#PBS -l mem=" << mem << "mb" << endl ;
-    if( fileToExecute.size() > 0 ){
-      tempOutputFile << "#PBS -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ;
-      tempOutputFile << "#PBS -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ;
-    }
-    else{
-      tempOutputFile << "#PBS -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ;
-      tempOutputFile << "#PBS -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ;
-    }
-    if( workDir.size() > 0 )
-      tempOutputFile << "cd " << workDir << endl ;
-    if( fileToExecute.size() > 0 ){
-      tempOutputFile << _mpiImpl->boot("${PBS_NODEFILE}",nbproc);
-      tempOutputFile << _mpiImpl->run("${PBS_NODEFILE}",nbproc,fileNameToExecute);
-      tempOutputFile << _mpiImpl->halt();
-    }
-    else{
-      tempOutputFile << "source " << env["SOURCEFILE"] << endl ;
-      tempOutputFile << env["COMMAND"];
+      tempOutputFile << "#PBS -l mem=" << mem << "kb" << endl;
+    tempOutputFile << "#PBS -o " << workDir << "/logs/output.log." << rootNameToExecute << endl;
+    tempOutputFile << "#PBS -e " << workDir << "/logs/error.log."  << rootNameToExecute << endl;
+
+    // Define environment for the job
+    if (!env.empty()) {
+      tempOutputFile << "#PBS -v ";
+      Environnement::const_iterator iter;
+      for (iter = env.begin() ; iter != env.end() ; ++iter) {
+        tempOutputFile << iter->first << "=" << iter->second << ",";
+      }
+      tempOutputFile << endl;
     }
 
+    // Abstraction of PBS_NODEFILE - TODO
+    tempOutputFile << "export LIBBATCH_NODEFILE=$PBS_NODEFILE" << endl;
+
+    // Launch the executable
+    tempOutputFile << "cd " << workDir << endl;
+    tempOutputFile << "./" + fileNameToExecute << endl;
     tempOutputFile.flush();
     tempOutputFile.close();
-#ifdef WIN32
-    _chmod(
-#else
-    chmod(
-#endif
-      TmpFileName.c_str(), 0x1ED);
-    cerr << TmpFileName.c_str() << endl;
+
+    BATCH_CHMOD(TmpFileName.c_str(), 0x1ED);
+    cerr << "Batch script file generated is: " << TmpFileName.c_str() << endl;
 
     int status = _protocol.copyFile(TmpFileName, "", "",
-                                    dirForTmpFiles + "/" + rootNameToExecute + "_Batch.sh",
+                                    workDir + "/" + rootNameToExecute + "_Batch.sh",
                                     _hostname, _username);
     if (status)
-      throw EmulationException("Error of connection on remote host");
-
-    remove(TmpFileName.c_str());
+      throw EmulationException("Error of connection on remote host, cannot copy batch submission file");
   }
-
 }
index a2f94576a8f42e1264b5b952d3f590bf6d6de13f..9d7e8ce913971899e78a85266a37b1c7e839020d 100644 (file)
@@ -45,7 +45,8 @@ namespace Batch {
   public:
     // Constructeur et destructeur
     BatchManager_ePBS(const FactBatchManager * parent, const char * host="localhost",
-                      CommunicationProtocolType protocolType = SSH, const char * mpiImpl="nompi"); // connexion a la machine host
+                      CommunicationProtocolType protocolType = SSH, const char * mpiImpl="nompi",
+                     int nb_proc_per_node=1); // connexion a la machine host
     virtual ~BatchManager_ePBS();
 
     // Recupere le nom du serveur par defaut
@@ -70,6 +71,7 @@ namespace Batch {
     void buildBatchScript(const Job & job);
 
   private:
+    int _nb_proc_per_node;
 
 #ifdef SWIG
   public:
index 2984a3c077bf6066f55b605ce7f80e9330a1e4b3..e017f2fff4565046431ecccd61b4b59cbd85b83f 100644 (file)
@@ -58,10 +58,11 @@ namespace Batch {
 
   BatchManager_eClient * FactBatchManager_ePBS::operator() (const char * hostname,
                                                             CommunicationProtocolType protocolType,
-                                                            const char * mpiImpl) const
+                                                            const char * mpiImpl,
+                                                           int nb_proc_per_node) const
   {
     // MESSAGE("Building new BatchManager_PBS on host '" << hostname << "'");
-    return new BatchManager_ePBS(this, hostname, protocolType, mpiImpl);
+    return new BatchManager_ePBS(this, hostname, protocolType, mpiImpl, nb_proc_per_node);
   }
 
 
index 930552d9c3fb3c6e7db5c65e5de1524e3b811aef..3cf5d3a492aa951d3d91b323962a39da4edcbd4a 100644 (file)
@@ -52,7 +52,8 @@ namespace Batch {
     virtual BatchManager * operator() (const char * hostname) const;
     virtual BatchManager_eClient * operator() (const char * hostname,
                                                CommunicationProtocolType protocolType,
-                                               const char * mpiImpl) const;
+                                               const char * mpiImpl,
+                                              int nb_proc_per_node = 1) const;
 
   protected:
 
index f58426531f27cb47aaf8bf353a1f3b2890a4b0bc..a96946a408c246e41911e1a992e83756414eb653 100644 (file)
@@ -32,16 +32,15 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # Build the test programs and add the tests
+add_executable(Test_ePBS Test_ePBS.cxx)
+target_link_libraries(Test_ePBS Batch SimpleParser)
+
 IF (HAS_SSH)
-    add_executable(Test_ePBS_SSH Test_ePBS_SSH.cxx)
-    target_link_libraries(Test_ePBS_SSH Batch SimpleParser)
-    ADD_TEST(ePBS_SSH Test_ePBS_SSH)
+    ADD_TEST(ePBS_SSH Test_ePBS SSH)
 ENDIF (HAS_SSH)
 
 IF (HAS_RSH)
-    add_executable(Test_ePBS_RSH Test_ePBS_RSH.cxx)
-    target_link_libraries(Test_ePBS_RSH Batch SimpleParser)
-    ADD_TEST(ePBS_RSH Test_ePBS_RSH)
+    ADD_TEST(ePBS_RSH Test_ePBS RSH)
 ENDIF (HAS_RSH)
 
 IF (BUILD_PBS_INTERFACE AND PBS_FOUND)
index e58278d1134865e52fc34f7d4ac5f3ae61709389..5ceb09ff68825ce68c756438ce0320dab290bbdf 100644 (file)
@@ -47,6 +47,8 @@
 using namespace std;
 using namespace Batch;
 
+const int MAX_SLEEP_TIME = 600;
+
 int main(int argc, char** argv)
 {
   cout << "*******************************************************************************************" << endl;
@@ -92,6 +94,7 @@ int main(int argc, char** argv)
     job.setParametre(p);
     // ... and its environment
     Environnement e;
+    e["MYENVVAR"] = "MYVALUE";
     job.setEnvironnement(e);
     cout << job << endl;
 
@@ -107,13 +110,28 @@ int main(int argc, char** argv)
     cout << jobid.__repr__() << endl;
 
     // Wait for the end of the job
-    string state = "Undefined";
-    for (int i=0 ; i<timeout/2 && state != "U" && state != "C"; i++) {
-      sleep(2);
-      JobInfo jinfo = jobid.queryJob();
+    int time = 0;
+    int sleeptime = 1;
+    bool testTimeout = (timeout > -1);
+    bool timeoutReached = (testTimeout && time >= timeout);
+    JobInfo jinfo = jobid.queryJob();
+    string state = jinfo.getParametre()["STATE"].str();
+    cout << "State is \"" << state << "\"";
+    while (!timeoutReached && state != "U" && state != "C") {
+      cout << ", sleeping " << sleeptime << "s..." << endl;
+      sleep(sleeptime);
+      time += sleeptime;
+      timeoutReached = (testTimeout && time >= timeout);
+      sleeptime *= 2;
+      if (testTimeout && sleeptime > timeout - time)
+        sleeptime = timeout - time;
+      if (sleeptime > MAX_SLEEP_TIME)
+        sleeptime = MAX_SLEEP_TIME;
+      jinfo = jobid.queryJob();
       state = jinfo.getParametre()["STATE"].str();
-      cout << "State is \"" << state << "\"" << endl;
+      cout << "State is \"" << state << "\"";
     }
+    cout << endl;
 
     if (state == "U" || state == "C") {
       cout << "Job " << jobid.__repr__() << " is done" << endl;
@@ -131,16 +149,21 @@ int main(int argc, char** argv)
   }
 
   // test the result file
-  string exp = "c = 12";
-  string res;
-  ifstream f("result.txt");
-  getline(f, res);
-  f.close();
-
-  cout << "result found : " << res << ", expected : " << exp << endl;
-
-  if (res == exp)
-    return 0;
-  else
+  try {
+    SimpleParser resultParser;
+    resultParser.parse("result.txt");
+    cout << "Result:" << endl << resultParser;
+    const string & envvar = resultParser.getValue("MYENVVAR");
+    int result = resultParser.getValueAsInt("c");
+    if (envvar == "MYVALUE" && result == 12) {
+      cout << "OK, Expected result found." << endl;
+      return 0;
+    } else {
+      cerr << "Error, result is not the expected one (MYENVVAR = MYVALUE, c = 12)." << endl;
+      return 1;
+    }
+  } catch (ParserException e) {
+    cerr << "Parser error on result file: " << e.what() << endl;
     return 1;
+  }
 }
diff --git a/src/PBS/Test/Test_ePBS.cxx b/src/PBS/Test/Test_ePBS.cxx
new file mode 100644 (file)
index 0000000..b603d75
--- /dev/null
@@ -0,0 +1,188 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * Test_ePBS.cxx :
+ *
+ * Author : Renaud BARATE - EDF R&D
+ * Date   : April 2009
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+
+#include <Batch_Job.hxx>
+#include <Batch_BatchManagerCatalog.hxx>
+#include <Batch_FactBatchManager.hxx>
+#include <Batch_FactBatchManager_eClient.hxx>
+#include <Batch_BatchManager.hxx>
+#include <Batch_BatchManager_eClient.hxx>
+
+#include <SimpleParser.hxx>
+
+#ifdef WIN32
+#include <Windows.h>
+#define sleep(seconds) Sleep((seconds)*1000)
+#define usleep(useconds) Sleep((useconds)/1000)
+#endif
+
+using namespace std;
+using namespace Batch;
+
+const int MAX_SLEEP_TIME = 600;
+
+void print_usage()
+{
+  cout << "usage: Test_ePBS PROTOCOL" << endl;
+  cout << "    PROTOCOL      \"SSH\" or \"RSH\"" << endl;
+}
+
+int main(int argc, char** argv)
+{
+  // Parse argument
+  if (argc != 2) {
+    print_usage();
+    return 1;
+  }
+  CommunicationProtocolType protocol;
+  if (strcmp(argv[1], "SSH") == 0)
+    protocol = SSH;
+  else if (strcmp(argv[1], "RSH") == 0)
+    protocol = RSH;
+  else {
+    print_usage();
+    return 1;
+  }
+
+  cout << "*******************************************************************************************" << endl;
+  cout << "This program tests the batch submission based on PBS emulation. Passwordless authentication" << endl;
+  cout << "must be used for this test to pass. For SSH, this can be configured with ssh-agent for" << endl;
+  cout << "instance. For RSH, this can be configured with the .rhosts file." << endl;
+  cout << "*******************************************************************************************" << endl;
+
+  // eventually remove any previous result
+  remove("result.txt");
+
+  try {
+    // Parse the test configuration file
+    SimpleParser parser;
+    parser.parseTestConfigFile();
+    const string & homedir = parser.getValue("TEST_EPBS_HOMEDIR");
+    const string & host = parser.getValue("TEST_EPBS_HOST");
+    const string & user = parser.getValue("TEST_EPBS_USER");
+    const string & queue = parser.getValue("TEST_EPBS_QUEUE");
+    int timeout = parser.getValueAsInt("TEST_EPBS_TIMEOUT");
+
+    // Define the job...
+    Job job;
+    // ... and its parameters ...
+    Parametre p;
+    p["EXECUTABLE"]    = "./test-script.sh";
+    p["NAME"]          = string("Test_ePBS_") + argv[1];
+    p["WORKDIR"]       = homedir + "/tmp/Batch";
+    p["INFILE"]        = Couple("seta.sh", "tmp/Batch/seta.sh");
+    p["INFILE"]       += Couple("setb.sh", "tmp/Batch/setb.sh");
+    p["OUTFILE"]       = Couple("result.txt", "tmp/Batch/result.txt");
+    p["TMPDIR"]        = "tmp/Batch/";
+    p["USER"]          = user;
+    p["NBPROC"]        = 1;
+    p["MAXWALLTIME"]   = 1;
+    p["MAXRAMSIZE"]    = 1000;
+    p["HOMEDIR"]       = homedir;
+    p["QUEUE"]         = queue;
+    job.setParametre(p);
+    // ... and its environment
+    Environnement e;
+    e["MYENVVAR"] = "MYVALUE";
+    job.setEnvironnement(e);
+    cout << job << endl;
+
+    // Get the catalog
+    BatchManagerCatalog& c = BatchManagerCatalog::getInstance();
+
+    // Create a BatchManager of type ePBS on localhost
+    FactBatchManager_eClient * fbm = (FactBatchManager_eClient *)(c("ePBS"));
+    BatchManager_eClient * bm = (*fbm)(host.c_str(), protocol, "lam");
+
+    // Submit the job to the BatchManager
+    JobId jobid = bm->submitJob(job);
+    cout << jobid.__repr__() << endl;
+
+    // Wait for the end of the job
+    int time = 0;
+    int sleeptime = 1;
+    bool testTimeout = (timeout > -1);
+    bool timeoutReached = (testTimeout && time >= timeout);
+    JobInfo jinfo = jobid.queryJob();
+    string state = jinfo.getParametre()["STATE"].str();
+    cout << "State is \"" << state << "\"";
+    while (!timeoutReached && state != "U" && state != "C") {
+      cout << ", sleeping " << sleeptime << "s..." << endl;
+      sleep(sleeptime);
+      time += sleeptime;
+      timeoutReached = (testTimeout && time >= timeout);
+      sleeptime *= 2;
+      if (testTimeout && sleeptime > timeout - time)
+        sleeptime = timeout - time;
+      if (sleeptime > MAX_SLEEP_TIME)
+        sleeptime = MAX_SLEEP_TIME;
+      jinfo = jobid.queryJob();
+      state = jinfo.getParametre()["STATE"].str();
+      cout << "State is \"" << state << "\"";
+    }
+    cout << endl;
+
+    if (state == "U" || state == "C") {
+      cout << "Job " << jobid.__repr__() << " is done" << endl;
+      bm->importOutputFiles(job, ".");
+    } else {
+      cerr << "Timeout while executing job" << endl;
+      return 1;
+    }
+
+  } catch (GenericException e) {
+    cerr << "Error: " << e << endl;
+    return 1;
+  } catch (ParserException e) {
+    cerr << "Parser error: " << e.what() << endl;
+    return 1;
+  }
+
+  // test the result file
+  try {
+    SimpleParser resultParser;
+    resultParser.parse("result.txt");
+    cout << "Result:" << endl << resultParser;
+    const string & envvar = resultParser.getValue("MYENVVAR");
+    int result = resultParser.getValueAsInt("c");
+    if (envvar == "MYVALUE" && result == 12) {
+      cout << "OK, Expected result found." << endl;
+      return 0;
+    } else {
+      cerr << "Error, result is not the expected one (MYENVVAR = MYVALUE, c = 12)." << endl;
+      return 1;
+    }
+  } catch (ParserException e) {
+    cerr << "Parser error on result file: " << e.what() << endl;
+    return 1;
+  }
+}
index 64eb2facee310eb6ccfa6aa8cc6747f8955540ad..ae952c89ca110b5a8eb2623dc5a270663c009c11 100755 (executable)
@@ -5,4 +5,5 @@ source setb.sh
 
 c=`expr $a "*" $b`
 
-echo "c = $c" > result.txt
+echo "MYENVVAR = $MYENVVAR" > result.txt
+echo "c = $c" >> result.txt
index dc7845e43a6bf755dfda2740340ab291930abbc5..98d9085a0fbb0334cc3765af957a7e82efcf5c26 100644 (file)
 #include <fstream>
 #include <sstream>
 #include <sys/stat.h>
+
+#include <stdlib.h>
+#include <string.h>
+
 #ifdef WIN32
 #include <io.h>
 #else
@@ -51,7 +55,8 @@ namespace Batch {
 
   BatchManager_eSGE::BatchManager_eSGE(const FactBatchManager * parent, const char * host,
                                        CommunicationProtocolType protocolType, const char * mpiImpl)
-  : BatchManager_eClient(parent, host, protocolType, mpiImpl)
+  : BatchManager_eClient(parent, host, protocolType, mpiImpl),
+    BatchManager(parent, host)
   {
     // Nothing to do
   }
@@ -67,7 +72,7 @@ namespace Batch {
   {
     int status;
     Parametre params = job.getParametre();
-    const std::string dirForTmpFiles = params[TMPDIR];
+    const std::string workDir = params[WORKDIR];
     const string fileToExecute = params[EXECUTABLE];
     string::size_type p1 = fileToExecute.find_last_of("/");
     string::size_type p2 = fileToExecute.find_last_of(".");
@@ -83,15 +88,23 @@ namespace Batch {
     string logFile = generateTemporaryFileName("SGE-submitlog");
 
     // define command to submit batch
-    string subCommand = string("cd ") + dirForTmpFiles + "; qsub " +
-                        fileNameToExecute + "_Batch.sh";
+    string subCommand = string("cd ") + workDir + "; qsub " + fileNameToExecute + "_Batch.sh";
     string command = _protocol.getExecCommand(subCommand, _hostname, _username);
     command += " > ";
     command += logFile;
+    command += " 2>&1";
     cerr << command.c_str() << endl;
     status = system(command.c_str());
     if(status)
-      throw EmulationException("Error of connection on remote host");
+    {
+      ifstream error_message(logFile.c_str());
+      std::string mess;
+      std::string temp;
+      while(std::getline(error_message, temp))
+       mess += temp;
+      error_message.close();
+      throw EmulationException("Error of connection on remote host, error was: " + mess);
+    }
 
     // read id of submitted job in log file
     char line[128];
@@ -191,32 +204,43 @@ namespace Batch {
   {
 #ifndef WIN32
     //TODO porting on Win32 platform
+    std::cerr << "BuildBatchScript" << std::endl;
     Parametre params = job.getParametre();
-    Environnement env = job.getEnvironnement();
-    const long nbproc = params[NBPROC];
-    const long edt = params[MAXWALLTIME];
-    const long mem = params[MAXRAMSIZE];
-    const string workDir = params[WORKDIR];
-    const std::string dirForTmpFiles = params[TMPDIR];
-    const string fileToExecute = params[EXECUTABLE];
-    const string home = params[HOMEDIR];
-    const std::string queue = params[QUEUE];
-    std::string rootNameToExecute;
-    std::string fileNameToExecute;
-    std::string filelogtemp;
-    if( fileToExecute.size() > 0 ){
-      string::size_type p1 = fileToExecute.find_last_of("/");
-      string::size_type p2 = fileToExecute.find_last_of(".");
-      rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
-      fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename((char *) fileToExecute.c_str()));
-
-      int idx = dirForTmpFiles.find("Batch/");
-      filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
-    }
-    else{
-      rootNameToExecute = "command";
-    }
 
+    // Job Parameters
+    string workDir       = "";
+    string fileToExecute = "";
+    int nbproc          = 0;
+    int edt             = 0;
+    int mem              = 0;
+    string queue         = "";
+
+    // Mandatory parameters
+    if (params.find(WORKDIR) != params.end()) 
+      workDir = params[WORKDIR].str();
+    else 
+      throw EmulationException("params[WORKDIR] is not defined ! Please defined it, cannot submit this job");
+    if (params.find(EXECUTABLE) != params.end()) 
+      fileToExecute = params[EXECUTABLE].str();
+    else 
+      throw EmulationException("params[EXECUTABLE] is not defined ! Please defined it, cannot submit this job");
+
+    // Optional parameters
+    if (params.find(NBPROC) != params.end()) 
+      nbproc = params[NBPROC];
+    if (params.find(MAXWALLTIME) != params.end()) 
+      edt = params[MAXWALLTIME];
+    if (params.find(MAXRAMSIZE) != params.end()) 
+      mem = params[MAXRAMSIZE];
+    if (params.find(QUEUE) != params.end()) 
+      queue = params[QUEUE].str();
+
+    string::size_type p1 = fileToExecute.find_last_of("/");
+    string::size_type p2 = fileToExecute.find_last_of(".");
+    string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+    string fileNameToExecute = fileToExecute.substr(p1+1);
+
+    // Create batch submit file
     ofstream tempOutputFile;
     std::string TmpFileName = createAndOpenTemporaryFile("SGE-script", tempOutputFile);
 
@@ -228,38 +252,27 @@ namespace Batch {
       tempOutputFile << "#$ -l h_rt=" << getWallTime(edt) << endl ;
     if( mem > 0 )
       tempOutputFile << "#$ -l h_vmem=" << mem << "M" << endl ;
-    if( fileToExecute.size() > 0 ){
-      tempOutputFile << "#$ -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ;
-      tempOutputFile << "#$ -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ;
-    }
-    else{
-      tempOutputFile << "#$ -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ;
-      tempOutputFile << "#$ -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ;
-    }
-    if( workDir.size() > 0 )
-      tempOutputFile << "cd " << workDir << endl ;
-    if( fileToExecute.size() > 0 ){
-      tempOutputFile << _mpiImpl->boot("",nbproc);
-      tempOutputFile << _mpiImpl->run("${TMPDIR}/machines",nbproc,fileNameToExecute);
-      tempOutputFile << _mpiImpl->halt();
-    }
-    else{
-      tempOutputFile << "source " << env["SOURCEFILE"] << endl ;
-      tempOutputFile << env["COMMAND"];
-    }
+    tempOutputFile << "#$ -o " << workDir << "/logs/output.log." << rootNameToExecute << endl ;
+    tempOutputFile << "#$ -e " << workDir << "/logs/error.log." << rootNameToExecute << endl ;
 
+    // Abstraction of PBS_NODEFILE - TODO
+    tempOutputFile << "export LIBBATCH_NODEFILE=$TMPDIR/machines" << endl;
+
+    // Launch the executable
+    tempOutputFile << "cd " << workDir << endl ;
+    tempOutputFile << "./" + fileNameToExecute << endl;
     tempOutputFile.flush();
     tempOutputFile.close();
-    chmod(TmpFileName.c_str(), 0x1ED);
-    cerr << TmpFileName.c_str() << endl;
+
+    BATCH_CHMOD(TmpFileName.c_str(), 0x1ED);
+    cerr << "Batch script file generated is: " << TmpFileName.c_str() << endl;
 
     int status = _protocol.copyFile(TmpFileName, "", "",
-                                    dirForTmpFiles + "/" + rootNameToExecute + "_Batch.sh",
+                                    workDir + "/" + rootNameToExecute + "_Batch.sh",
                                     _hostname, _username);
     if (status)
       throw EmulationException("Error of connection on remote host");
 
-    remove(TmpFileName.c_str());
 #endif //WIN32
   }
 
index 7bc44c02d50610839ab489777868351ceca9e22b..a1bdcc28b65472b4365792f052303f3ad4db796c 100644 (file)
@@ -56,7 +56,8 @@ namespace Batch {
 
   BatchManager_eClient * FactBatchManager_eSGE::operator() (const char * hostname,
                                                             CommunicationProtocolType protocolType,
-                                                            const char * mpiImpl) const
+                                                            const char * mpiImpl,
+                                                           int nb_proc_per_node) const
   {
     // MESSAGE("Building new BatchManager_SGE on host '" << hostname << "'");
     return new BatchManager_eSGE(this, hostname, protocolType, mpiImpl);
index 6dae360b09f7220f628d611569d981e9c972d211..509220ad039e2e74fae23b1c419d901b789d2451 100644 (file)
@@ -48,7 +48,8 @@ namespace Batch {
     virtual BatchManager * operator() (const char * hostname) const;
     virtual BatchManager_eClient * operator() (const char * hostname,
                                                CommunicationProtocolType protocolType,
-                                               const char * mpiImpl) const;
+                                               const char * mpiImpl,
+                                              int nb_proc_per_node = 1) const;
 
   protected:
 
diff --git a/src/SSH/Batch_BatchManager_eSSH.cxx b/src/SSH/Batch_BatchManager_eSSH.cxx
new file mode 100644 (file)
index 0000000..11784b3
--- /dev/null
@@ -0,0 +1,226 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eSSH.cxx : emulation of SSH client
+ *
+ * Auteur : André RIBES - EDF R&D
+ * Date   : Octobre 2009
+ */
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <Batch_config.h>
+
+#ifdef MSVC
+#include <io.h>
+#else
+#include <libgen.h>
+#endif
+
+#include "Batch_BatchManager_eSSH.hxx"
+#include "Batch_JobInfo_eSSH.hxx"
+
+using namespace std;
+
+namespace Batch {
+
+  BatchManager_eSSH::BatchManager_eSSH(const FactBatchManager * parent, const char * host,
+                                       CommunicationProtocolType protocolType, const char * mpiImpl)
+    : BatchManager_eClient(parent, host, protocolType, mpiImpl),
+      BatchManager_Local(parent, host, protocolType),
+      BatchManager(parent, host)
+  {
+    // Nothing to do
+  }
+
+  // Destructeur
+  BatchManager_eSSH::~BatchManager_eSSH()
+  {
+    // Nothing to do
+  }
+
+  // Methode pour le controle des jobs : soumet un job au gestionnaire
+  const JobId BatchManager_eSSH::submitJob(const Job & job)
+  {
+    // export input files on cluster
+    std::cerr << "BatchManager_eSSH::submitJob exportInputFiles" << std::endl;
+    Parametre param = job.getParametre();
+
+    // Input files copy
+    exportInputFiles(job);
+
+    // Launch job
+    // Patch until Local Manager is patched
+    std::string executable = param[EXECUTABLE].str();
+    std::string::size_type p1 = executable.find_last_of("/");
+    std::string fileNameToExecute = "./" + executable.substr(p1+1);
+    Parametre new_param(param);
+    new_param[INFILE].eraseAll(); 
+    new_param[OUTFILE].eraseAll();
+    new_param[EXECUTABLE] = fileNameToExecute;
+    new_param[EXECUTIONHOST] = _hostname;
+    Job * j = new Job(new_param);
+
+
+    std::cerr << "BatchManager_eSSH::submitJob Local submitJob" << std::endl;
+    JobId id = BatchManager_Local::submitJob(*j);
+    delete j;
+    return id;
+  }
+
+  // Methode pour le controle des jobs : retire un job du gestionnaire
+  void BatchManager_eSSH::deleteJob(const JobId & jobid)
+  {
+    BatchManager_Local::deleteJob(jobid);
+  }
+  
+  // Methode pour le controle des jobs : renvoie l'etat du job
+  JobInfo BatchManager_eSSH::queryJob(const JobId & jobid)
+  {
+    return BatchManager_Local::queryJob(jobid);
+  }
+
+  // Methode pour le controle des jobs : suspend un job en file d'attente
+  void BatchManager_eSSH::holdJob(const JobId & jobid)
+  {
+    BatchManager_Local::holdJob(jobid);
+  }
+
+  // Methode pour le controle des jobs : relache un job suspendu
+  void BatchManager_eSSH::releaseJob(const JobId & jobid)
+  {
+    BatchManager_Local::releaseJob(jobid);
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_eSSH::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env)
+  {
+    BatchManager_Local::alterJob(jobid, param, env);
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_eSSH::alterJob(const JobId & jobid, const Parametre & param)
+  {
+    BatchManager_Local::alterJob(jobid, param);
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_eSSH::alterJob(const JobId & jobid, const Environnement & env)
+  {
+    BatchManager_Local::alterJob(jobid, env); 
+  }
+
+  void BatchManager_eSSH::buildBatchScript(const Job & job)
+  {
+    Parametre params = job.getParametre();
+    Environnement env = job.getEnvironnement();
+    const long nbproc = params[NBPROC];
+    const long edt = params[MAXWALLTIME];
+    const long mem = params[MAXRAMSIZE];
+    const string workDir = params[WORKDIR];
+    const std::string dirForTmpFiles = params[TMPDIR];
+    const string fileToExecute = params[EXECUTABLE];
+    const string home = params[HOMEDIR];
+    const std::string queue = params[QUEUE];
+    std::string rootNameToExecute;
+    std::string fileNameToExecute;
+    std::string filelogtemp;
+    if( fileToExecute.size() > 0 ){
+      string::size_type p1 = fileToExecute.find_last_of("/");
+      string::size_type p2 = fileToExecute.find_last_of(".");
+      rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+
+#ifdef MSVC
+      char fname[_MAX_FNAME];
+      char ext[_MAX_EXT];
+      _splitpath_s(fileToExecute.c_str(), NULL, 0, NULL, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
+      string execBaseName = string(fname) + ext;
+#else
+      char* basec=strdup(fileToExecute.c_str());
+      string execBaseName = string(basename(basec));
+      free(basec);
+#endif
+
+      fileNameToExecute = "~/" + dirForTmpFiles + "/" + execBaseName;
+
+      int idx = dirForTmpFiles.find("Batch/");
+      filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
+    }
+    else{
+      rootNameToExecute = "command";
+    }
+
+    ofstream tempOutputFile;
+    std::string TmpFileName = createAndOpenTemporaryFile("SSH-script", tempOutputFile);
+
+    tempOutputFile << "#! /bin/sh -f" << endl;
+    if (queue != "")
+      tempOutputFile << "#BSUB -q " << queue << endl;
+    if( edt > 0 )
+      tempOutputFile << "#SSH -l walltime=" << edt*60 << endl ;
+    if( mem > 0 )
+      tempOutputFile << "#SSH -l mem=" << mem << "mb" << endl ;
+    if( fileToExecute.size() > 0 ){
+      tempOutputFile << "#SSH -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ;
+      tempOutputFile << "#SSH -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ;
+    }
+    else{
+      tempOutputFile << "#SSH -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ;
+      tempOutputFile << "#SSH -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ;
+    }
+    if( workDir.size() > 0 )
+      tempOutputFile << "cd " << workDir << endl ;
+    if( fileToExecute.size() > 0 ){
+      tempOutputFile << _mpiImpl->boot("${SSH_NODEFILE}",nbproc);
+      tempOutputFile << _mpiImpl->run("${SSH_NODEFILE}",nbproc,fileNameToExecute);
+      tempOutputFile << _mpiImpl->halt();
+    }
+    else{
+      tempOutputFile << "source " << env["SOURCEFILE"] << endl ;
+      tempOutputFile << env["COMMAND"];
+    }
+
+    tempOutputFile.flush();
+    tempOutputFile.close();
+#ifdef WIN32
+    _chmod(
+#else
+    chmod(
+#endif
+      TmpFileName.c_str(), 0x1ED);
+    cerr << TmpFileName.c_str() << endl;
+
+    int status = Batch::BatchManager_eClient::_protocol.copyFile(TmpFileName, "", "",
+                                    dirForTmpFiles + "/" + rootNameToExecute + "_Batch.sh",
+                                    _hostname, _username);
+    if (status)
+      throw EmulationException("Error of connection on remote host");
+
+    remove(TmpFileName.c_str());
+  }
+
+}
diff --git a/src/SSH/Batch_BatchManager_eSSH.hxx b/src/SSH/Batch_BatchManager_eSSH.hxx
new file mode 100644 (file)
index 0000000..a95f2aa
--- /dev/null
@@ -0,0 +1,81 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eSSH.hxx : emulation of SSH client
+ *
+ * Auteur : André RIBES - EDF R&D
+ * Date   : Octobre 2009
+ */
+
+#ifndef _BATCHMANAGER_ESSH_H_
+#define _BATCHMANAGER_ESSH_H_
+
+#include "Batch_Defines.hxx"
+#include "Batch_JobId.hxx"
+#include "Batch_JobInfo.hxx"
+#include "Batch_FactBatchManager.hxx"
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_BatchManager_Local.hxx"
+
+namespace Batch {
+
+  class BATCH_EXPORT BatchManager_eSSH : 
+    virtual public BatchManager_eClient,
+    virtual public BatchManager_Local
+  {
+  public:
+    // Constructeur et destructeur
+    BatchManager_eSSH(const FactBatchManager * parent, const char * host="localhost",
+                      CommunicationProtocolType protocolType = SSH, const char * mpiImpl="nompi"); // connexion a la machine host
+    virtual ~BatchManager_eSSH();
+
+    // Recupere le nom du serveur par defaut
+    // static string BatchManager_LSF::getDefaultServer();
+
+    // Methodes pour le controle des jobs
+    virtual const JobId submitJob(const Job & job); // soumet un job au gestionnaire
+    virtual void deleteJob(const JobId & jobid);    // retire un job du gestionnaire
+    virtual JobInfo queryJob(const JobId & jobid);  // renvoie l'etat du job
+
+    // Non implanté...
+    virtual void holdJob(const JobId & jobid); // suspend un job en file d'attente
+    virtual void releaseJob(const JobId & jobid); // relache un job suspendu
+    virtual void alterJob(const JobId & jobid, const Parametre & param, const Environnement & env); // modifie un job en file d'attente
+    virtual void alterJob(const JobId & jobid, const Parametre & param); // modifie un job en file d'attente
+    virtual void alterJob(const JobId & jobid, const Environnement & env); // modifie un job en file d'attente
+
+
+  protected:
+    void buildBatchScript(const Job & job);
+
+  private:
+
+#ifdef SWIG
+  public:
+    // Recupere le l'identifiant d'un job deja soumis au BatchManager
+    //virtual const JobId getJobIdByReference(const string & ref) { return BatchManager::getJobIdByReference(ref); }
+    virtual const JobId getJobIdByReference(const char * ref) { return BatchManager::getJobIdByReference(ref); }
+#endif
+  };
+}
+
+#endif
diff --git a/src/SSH/Batch_FactBatchManager_eSSH.cxx b/src/SSH/Batch_FactBatchManager_eSSH.cxx
new file mode 100644 (file)
index 0000000..0c8d153
--- /dev/null
@@ -0,0 +1,53 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eSSH.cxx :
+ *
+ * Auteur : André RIBES : EDF R&D 
+ * Date   : Octobre 2009
+ */
+
+#include <string>
+#include "Batch_BatchManager_eSSH.hxx"
+#include "Batch_FactBatchManager_eSSH.hxx"
+
+Batch::FactBatchManager_eSSH::FactBatchManager_eSSH() : FactBatchManager_eClient("eSSH") {}
+
+Batch::FactBatchManager_eSSH::~FactBatchManager_eSSH() {}
+
+Batch::BatchManager * 
+Batch::FactBatchManager_eSSH::operator() (const char * hostname) const
+{
+  return new Batch::BatchManager_eSSH(this, hostname);
+}
+
+Batch::BatchManager_eClient * 
+Batch::FactBatchManager_eSSH::operator() (const char * hostname,
+                                  CommunicationProtocolType protocolType,
+                                  const char * mpiImpl,
+                                  int nb_proc_per_node) const
+{
+  //protocolType and mpiImpl are ignored.
+  std::cerr << "[Batch::FactBatchManager_eSSH] creating new Batch::BatchManager_eSSH with hostname = " << hostname << std::endl;
+
+  return new Batch::BatchManager_eSSH(this, hostname);
+}
diff --git a/src/SSH/Batch_FactBatchManager_eSSH.hxx b/src/SSH/Batch_FactBatchManager_eSSH.hxx
new file mode 100644 (file)
index 0000000..f3210e6
--- /dev/null
@@ -0,0 +1,57 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eSSH.hxx : 
+ *
+ * Auteur : André RIBES : EDF R&D
+ * Date   : Octobre 2009
+ */
+
+#ifndef _FACTBATCHMANAGER_eSSH_H_
+#define _FACTBATCHMANAGER_eSSH_H_
+
+#include "Batch_Defines.hxx"
+
+#include <string>
+#include <map>
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_FactBatchManager_eClient.hxx"
+
+namespace Batch {
+  
+  class BatchManager_eSSH;
+
+  class BATCH_EXPORT FactBatchManager_eSSH : public FactBatchManager_eClient
+  {
+  public:
+    FactBatchManager_eSSH();
+    virtual ~FactBatchManager_eSSH();
+
+    virtual BatchManager * operator() (const char * hostname) const; // From FactBacthManager
+    virtual BatchManager_eClient * operator() (const char * hostname,
+                                               CommunicationProtocolType protocolType,
+                                               const char * mpiImpl,
+                                              int nb_proc_per_node = 1) const; // From FactBatchManager_eClient
+  };
+}
+
+#endif
diff --git a/src/SSH/Batch_JobInfo_eSSH.cxx b/src/SSH/Batch_JobInfo_eSSH.cxx
new file mode 100644 (file)
index 0000000..fd899de
--- /dev/null
@@ -0,0 +1,71 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_eSSH.cxx :  emulation of SSH client
+ *
+ * Auteur : André RIBES - EDF R&D
+ * Date   : Octobre 2009
+ */
+
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "Batch_Parametre.hxx"
+#include "Batch_Environnement.hxx"
+#include "Batch_RunTimeException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_JobInfo_eSSH.hxx"
+
+using namespace std;
+
+namespace Batch {
+
+  // Constructeurs
+  JobInfo_eSSH::JobInfo_eSSH(int id, string status) : JobInfo()
+  {
+    // On remplit les membres _param et _env
+    ostringstream oss;
+    oss << id;
+    _param[ID] = oss.str();
+    _param[STATE] = status;
+  }
+
+  // Destructeur
+  JobInfo_eSSH::~JobInfo_eSSH()
+  {
+    // Nothing to do
+  }
+
+  // Methode pour l'interfacage avec Python (SWIG) : affichage en Python
+  string JobInfo_eSSH::__str__() const
+  {
+    ostringstream sst;
+    sst << "<JobInfo_eSSH (" << this << ") :" << endl;
+    sst << " ID = " <<_param[ID] << endl;
+    sst << " STATE = " <<_param[STATE] << endl;
+
+    return sst.str();
+  }
+
+
+}
diff --git a/src/SSH/Batch_JobInfo_eSSH.hxx b/src/SSH/Batch_JobInfo_eSSH.hxx
new file mode 100644 (file)
index 0000000..574c014
--- /dev/null
@@ -0,0 +1,54 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_eSSH.hxx :  emulation of SSH client
+ *
+ * Auteur : André RIBES - EDF R&D
+ * Date   : Octobre 2009
+ */
+
+#ifndef _JOBINFO_SSH_H_
+#define _JOBINFO_SSH_H_
+
+#include <string>
+#include "Batch_RunTimeException.hxx"
+#include "Batch_JobInfo.hxx"
+
+namespace Batch {
+
+  class JobInfo_eSSH : public JobInfo
+  {
+  public:
+    // Constructeurs et destructeur
+    JobInfo_eSSH(int id, std::string status);
+    virtual ~JobInfo_eSSH();
+
+    // Methodes pour l'interfacage avec Python (SWIG)
+    // TODO : supprimer ces methodes et transferer leur definitions dans SWIG
+    std::string  __str__() const; // SWIG : affichage en Python
+    std::string  __repr__() const { return __str__(); }; // SWIG : affichage en Python
+
+  };
+
+}
+
+#endif
diff --git a/src/SSH/CMakeLists.txt b/src/SSH/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e2d921d
--- /dev/null
@@ -0,0 +1,33 @@
+#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+SET(CLASS_LIST SSH/Batch_FactBatchManager_eSSH
+              SSH/Batch_BatchManager_eSSH
+              SSH/Batch_JobInfo_eSSH
+   )
+
+APPEND_CLASSES_TO_SRC_FILES(${CLASS_LIST})
+APPEND_CLASSES_TO_HDR_FILES(${CLASS_LIST})
+
+#IF (TEST_ENABLED)
+#    add_subdirectory(Test)
+#ENDIF (TEST_ENABLED)