]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
Start New Version of SALOME Launcher
authorribes <ribes>
Tue, 10 Nov 2009 09:23:01 +0000 (09:23 +0000)
committerribes <ribes>
Tue, 10 Nov 2009 09:23:01 +0000 (09:23 +0000)
- New IDL API added
- Job Command works

15 files changed:
idl/SALOME_ContainerManager.idl
src/Launcher/Launcher.cxx
src/Launcher/Launcher.hxx
src/Launcher/Launcher_Job.cxx [new file with mode: 0644]
src/Launcher/Launcher_Job.hxx [new file with mode: 0644]
src/Launcher/Launcher_Job_Command.cxx [new file with mode: 0644]
src/Launcher/Launcher_Job_Command.hxx [new file with mode: 0644]
src/Launcher/Launcher_Job_YACSFile.cxx [new file with mode: 0644]
src/Launcher/Launcher_Job_YACSFile.hxx [new file with mode: 0644]
src/Launcher/Launcher_Utils.hxx [new file with mode: 0644]
src/Launcher/Makefile.am
src/Launcher/SALOME_Launcher.cxx
src/Launcher/SALOME_Launcher.hxx
src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx
src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx

index 16ffacd19b2c856c86d547c5f37d40486bda76d2..2dcff5b4decaa2c9ba9f7561b5f3b7cf3d8c95ef 100644 (file)
@@ -110,8 +110,9 @@ struct MachineDefinition
   string batch;
   long nb_component_nodes;
 };
+
 //! exception thrown if a computer is not found in the catalog
-  exception NotFound {};
+exception NotFound {};
 
 //!  Structure used for Salome Batch Job parameters
 struct BatchParameters
@@ -126,6 +127,37 @@ struct BatchParameters
   long nb_proc; 
 };
 
+struct JobParameters
+{
+  //! Job Type - Could be equal to "command" or "yacs_file"
+  string job_type;
+
+  //! YACS file
+  string yacs_file;
+
+  //! Command
+  string command;
+  string env_file; 
+
+  // Common values
+  FilesList in_files;
+  FilesList out_files;
+  string work_directory;
+  string local_directory;
+  string result_directory;
+  /*! Time for the batch (has to be like this : hh:mm) - Could be empty, in
+       this case, default value of the selected resource will be used.
+  */
+  string expected_during_time; 
+  MachineParameters resource_required;
+  // This two values are defined into MachineParameters
+  // Memory is expressed in megabytes
+  //long proc_nb;
+  //! Minimum of memory needed (has to be like : 32gb or 512mb)
+  //string mem; 
+
+};
+
 /*! \brief Interface of the %salomelauncher
     This interface is used for interaction with the unique instance
     of SalomeLauncher
@@ -146,9 +178,14 @@ struct BatchParameters
     boolean testBatch(in MachineParameters params) raises (SALOME::SALOME_Exception);
 
     void Shutdown();
-
     long getPID();
 
+    // New Launcher interface
+    long   createJob    (in Engines::JobParameters job_parameters) raises (SALOME::SALOME_Exception);
+    void   launchJob    (in long job_id)                           raises (SALOME::SALOME_Exception);
+    string getJobState  (in long job_id)                           raises (SALOME::SALOME_Exception);
+    void   getJobResults(in long job_id, in string directory)      raises (SALOME::SALOME_Exception);
+    void   removeJob    (in long job_id)                           raises (SALOME::SALOME_Exception);
   } ;
   
 /*! \brief Interface of the %containerManager
index 17dfdaa4b81dd3714b525702c9e1e5843221e287..941374355ceb40653072f3effb649395f31c6a6c 100644 (file)
@@ -26,6 +26,7 @@
 #include <Batch/Batch_FactBatchManager_ePBS.hxx>
 #include <Batch/Batch_BatchManager_eClient.hxx>
 #include <Batch/Batch_FactBatchManager_eSGE.hxx>
+#include <Batch/Batch_FactBatchManager_eSSH.hxx>
 #endif
 
 #include "SALOME_Launcher_Handler.hxx"
@@ -61,10 +62,7 @@ Launcher_cpp::Launcher_cpp()
 
 Launcher_cpp::~Launcher_cpp()
 {
-#if defined(_DEBUG_) || defined(_DEBUG)
-  cerr << "Launcher_cpp destructor" << endl;
-#endif
-
+  LAUNCHER_MESSAGE("Launcher_cpp destructor");
 #ifdef WITH_LIBBATCH
   std::map < string, Batch::BatchManager_eClient * >::const_iterator it1;
   for(it1=_batchmap.begin();it1!=_batchmap.end();it1++)
@@ -72,6 +70,10 @@ Launcher_cpp::~Launcher_cpp()
   std::map < std::pair<std::string,long> , Batch::Job* >::const_iterator it2;
   for(it2=_jobmap.begin();it2!=_jobmap.end();it2++)
     delete it2->second;
+
+  std::map<int, Launcher::Job *>::const_iterator it_job;
+  for(it_job = _launcher_job_map.begin(); it_job != _launcher_job_map.end(); it_job++)
+    delete it_job->second;
 #endif
 }
 
@@ -128,7 +130,7 @@ long Launcher_cpp::submitJob( const std::string xmlExecuteFile,
       _batchmap[cname] = FactoryBatchManager(p);
       // TODO: Add a test for the cluster !
     }
-    
+
   try{
 
     // directory on cluster to put files to execute
@@ -226,8 +228,21 @@ long Launcher_cpp::submitSalomeJob( const string fileToExecute ,
   if (aMachineList.size() == 0)
     throw LauncherException("No resources have been found with your parameters");
 
+  std::cerr << "Machine name is : " << aMachineList[0] << std::endl;
   ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
   string clustername(p.Alias);
+  if (clustername == "")
+  {
+    throw LauncherException("Alias is not defined in machine configuration, please correct your Resource File");
+  }
+  if (p.Batch == ssh_batch)
+  {
+    std::cerr << "p.batch value = " << p.Batch << std::endl;
+    std::cerr << "ssh_batch machine detected !" << std::endl;
+  }
+  else
+     std::cerr << "p.batch value = " << p.Batch << std::endl;
+    
 #if defined(_DEBUG_) || defined(_DEBUG)
   cerr << "Choose cluster: " <<  clustername << endl;
 #endif
@@ -236,7 +251,9 @@ long Launcher_cpp::submitSalomeJob( const string fileToExecute ,
   map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
   if(it == _batchmap.end())
     {
+      std::cerr << "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" << std::endl;
       _batchmap[clustername] = FactoryBatchManager(p);
+      std::cerr << "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" << std::endl;
       // TODO: Add a test for the cluster !
     }
     
@@ -248,21 +265,44 @@ long Launcher_cpp::submitSalomeJob( const string fileToExecute ,
     Batch::Parametre param;
     param[USER] = p.UserName;
     param[EXECUTABLE] = buildSalomeCouplingScript(fileToExecute,tmpdir,p);
-    param[INFILE] = Batch::Couple( fileToExecute, getRemoteFile(tmpdir,fileToExecute) );
+    param[INFILE] = Batch::Couple( "/tmp/" + param[EXECUTABLE].str(), getRemoteFile(tmpdir, param[EXECUTABLE].str()) );
+    param[INFILE] += Batch::Couple( fileToExecute, getRemoteFile(tmpdir,fileToExecute) );
     for(int i=0;i<filesToExport.size();i++)
       param[INFILE] += Batch::Couple( filesToExport[i], getRemoteFile(tmpdir,filesToExport[i]) );
 
     param[OUTFILE] = Batch::Couple( "", "~/" + tmpdir + "/" + "output.log*" );
     param[OUTFILE] += Batch::Couple( "", "~/" + tmpdir + "/" + "error.log*" );
     param[OUTFILE] += Batch::Couple( "", "~/" + tmpdir + "/" + "YACS_Server*" );
+    
     for(int i=0;i<filesToImport.size();i++)
-      param[OUTFILE] += Batch::Couple( "", "~/" + tmpdir + "/" + filesToImport[i] );
+    {
+      if (filesToImport[i].find("/") == std::string::npos)
+       param[OUTFILE] += Batch::Couple( "", "~/" + tmpdir + "/" + filesToImport[i] );
+      else
+       param[OUTFILE] += Batch::Couple( "", filesToImport[i] );
+    }
 
     param[NBPROC] = batch_params.nb_proc;
-    param[WORKDIR] = batch_params.batch_directory;
+    //param[WORKDIR] = batch_params.batch_directory;
+    param[WORKDIR] = "~";
     param[TMPDIR] = tmpdir;
-    param[MAXWALLTIME] = getWallTime(batch_params.expected_during_time);
-    param[MAXRAMSIZE] = getRamSize(batch_params.mem);
+    if (p.Batch == ssh_batch)
+    {
+      std::cerr << "WallTime == " << getWallTime(batch_params.expected_during_time)*60 << std::endl;
+      param[MAXWALLTIME] = getWallTime(batch_params.expected_during_time)*60;
+    }
+    else
+      param[MAXWALLTIME] = getWallTime(batch_params.expected_during_time);
+    if(getRamSize(batch_params.mem) != 0)
+    {
+      if (p.Batch == ssh_batch)
+      {
+       std::cerr << "RamSize in kbytes == " << getRamSize(batch_params.mem) * 1024 << std::endl;
+       param[MAXRAMSIZE] = getRamSize(batch_params.mem) * 1024;
+      }
+      else
+       param[MAXRAMSIZE] = getRamSize(batch_params.mem);
+    }
     param[HOMEDIR] = getHomeDir(p, tmpdir);
     param[QUEUE] = p.batchQueue;
 
@@ -433,7 +473,7 @@ void Launcher_cpp::getResultsJob( const std::string directory,
  */ 
 //=============================================================================
 
-Batch::BatchManager_eClient *Launcher_cpp::FactoryBatchManager( const ParserResourcesType& params ) throw(LauncherException)
+Batch::BatchManager_eClient *Launcher_cpp::FactoryBatchManager(ParserResourcesType& params ) throw(LauncherException)
 {
 #ifdef WITH_LIBBATCH
   std::string hostname, mpi;
@@ -472,7 +512,11 @@ Batch::BatchManager_eClient *Launcher_cpp::FactoryBatchManager( const ParserReso
     mpi = "prun";
     break;
   case nompi:
-    throw LauncherException("you must specified an mpi implementation for batch manager");
+    std::cerr << "No MPI detected - switch to single machine case" << std::endl;
+    if (protocol == Batch::SSH)
+      params.Batch = ssh_batch;
+    else
+      throw LauncherException("you must specified an mpi implementation for batch manager or a ssh computer");
     break;
   default:
     throw LauncherException("unknown mpi implementation");
@@ -500,6 +544,12 @@ Batch::BatchManager_eClient *Launcher_cpp::FactoryBatchManager( const ParserReso
 #endif
     fact = new Batch::FactBatchManager_eSGE;
     break;
+  case ssh_batch:
+#if defined(_DEBUG_) || defined(_DEBUG)
+    cout << "Instantiation of SSH batch manager" << endl;
+#endif
+    fact = new Batch::FactBatchManager_eSSH;
+    break;
   default:
 #if defined(_DEBUG_) || defined(_DEBUG)
     cerr << "BATCH = " << params.Batch << endl;
@@ -508,7 +558,7 @@ Batch::BatchManager_eClient *Launcher_cpp::FactoryBatchManager( const ParserReso
   }
   return (*fact)(hostname.c_str(), protocol, mpi.c_str());
 #else
-  throw LauncherException("Method Launcher_cpp::FactoryBatchManager is not available "
+M@M@  throw LauncherException("Method Launcher_cpp::FactoryBatchManager is not available "
                           "(libBatch was not present at compilation time)");
 #endif
 }
@@ -517,124 +567,155 @@ string Launcher_cpp::buildSalomeCouplingScript(const string fileToExecute, const
 {
 #ifdef WITH_LIBBATCH
 #ifndef WIN32 //TODO: need for porting on Windows
+
   int idx = dirForTmpFiles.find("Batch/");
   std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
   std::string dfilelogtemp = params.AppliPath + "/" + filelogtemp;
-
   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);
   std::string TmpFileName = "/tmp/runSalome_" + fileNameToExecute + ".sh";
-
-  MpiImpl* mpiImpl = FactoryMpiImpl(params.mpi);
-
   ofstream tempOutputFile;
   tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
 
-  // Begin
-  tempOutputFile << "#! /bin/sh -f" << endl ;
-  tempOutputFile << "cd ~/" ;
-  tempOutputFile << dirForTmpFiles << endl ;
-  tempOutputFile << "export SALOME_BATCH=1\n";
-  tempOutputFile << "export PYTHONPATH=~/" ;
-  tempOutputFile << dirForTmpFiles ;
-  tempOutputFile << ":$PYTHONPATH" << endl ;
-
-  // Adding user script
-  std::string script = params.userCommands;
-  if (script != "")
-    tempOutputFile << script << endl;
-  // Test node rank
-  tempOutputFile << "if test \"" ;
-  tempOutputFile << mpiImpl->rank() ;
-  tempOutputFile << "\" = \"0\"; then" << endl ;
-
-  // -----------------------------------------------
-  // Code for rank 0 : launch runAppli and a container
-  // RunAppli
-  if(params.ModulesList.size()>0)
-    tempOutputFile << "  " << params.AppliPath << "/runAppli --terminal --modules=" ;
+
+  if (params.Batch == ssh_batch)
+  {
+    tempOutputFile << "#! /bin/sh -f" << endl ;
+    tempOutputFile << "cd ~/" ;
+    tempOutputFile << dirForTmpFiles << endl ;
+    tempOutputFile << params.AppliPath << "/runAppli --terminal  --ns-port-log=" << filelogtemp << endl;
+    tempOutputFile << "current=0\n"
+                  << "stop=20\n" 
+                  << "while ! test -f " << dfilelogtemp << "\n"
+                  << "do\n"
+                  << "  sleep 2\n"
+                  << "  let current=current+1\n"
+                  << "  if [ \"$current\" -eq \"$stop\" ] ; then\n"
+                  << "    echo Error Naming Service failed ! >&2"
+                  << "    exit\n"
+                  << "  fi\n"
+                  << "done\n"
+                  << "port=`cat " << dfilelogtemp << "`\n";
+    tempOutputFile << params.AppliPath << "/runSession driver " << fileNameToExecute << ".xml" << endl;
+    tempOutputFile << params.AppliPath << "/runSession killSalomeWithPort.py $port" << endl;
+    tempOutputFile.flush();
+    tempOutputFile.close();
+    chmod(TmpFileName.c_str(), 0x1ED);
+#if defined(_DEBUG_) || defined(_DEBUG)
+    cerr << TmpFileName.c_str() << endl;
+#endif
+    return "runSalome_" + fileNameToExecute + ".sh";
+  }
   else
-    tempOutputFile << "  " << params.AppliPath << "/runAppli --terminal ";
-  for ( int i = 0 ; i < params.ModulesList.size() ; i++ ) {
-    tempOutputFile << params.ModulesList[i] ;
-    if ( i != params.ModulesList.size()-1 )
-      tempOutputFile << "," ;
-  }
-  tempOutputFile << " --standalone=registry,study,moduleCatalog --ns-port-log="
-                << filelogtemp 
-                << " &\n";
-
-  // Wait NamingService
-  tempOutputFile << "  current=0\n"
-                << "  stop=20\n" 
-                << "  while ! test -f " << dfilelogtemp << "\n"
-                << "  do\n"
-                << "    sleep 2\n"
-                << "    let current=current+1\n"
-                << "    if [ \"$current\" -eq \"$stop\" ] ; then\n"
-                << "      echo Error Naming Service failed ! >&2"
-                << "      exit\n"
-                << "    fi\n"
-                << "  done\n"
-                << "  port=`cat " << dfilelogtemp << "`\n";
-    
-  // Wait other containers
-  tempOutputFile << "  for ((ip=1; ip < ";
-  tempOutputFile << mpiImpl->size();
-  tempOutputFile << " ; ip++))" << endl;
-  tempOutputFile << "  do" << endl ;
-  tempOutputFile << "    arglist=\"$arglist YACS_Server_\"$ip" << endl ;
-  tempOutputFile << "  done" << endl ;
-  tempOutputFile << "  sleep 5" << endl ;
-  tempOutputFile << "  " << params.AppliPath << "/runSession waitContainers.py $arglist" << endl ;
-  
-  // Launch user script
-  tempOutputFile << "  " << params.AppliPath << "/runSession python ~/" << dirForTmpFiles << "/" << fileNameToExecute << ".py" << endl;
-
-  // Stop application
-  tempOutputFile << "  rm " << dfilelogtemp << "\n"
-                << "  " << params.AppliPath << "/runSession shutdownSalome.py" << endl;
-
-  // -------------------------------------
-  // Other nodes launch a container
-  tempOutputFile << "else" << endl ;
-
-  // Wait NamingService
-  tempOutputFile << "  current=0\n"
-                << "  stop=20\n" 
-                << "  while ! test -f " << dfilelogtemp << "\n"
-                << "  do\n"
-                << "    sleep 2\n"
-                << "    let current=current+1\n"
-                << "    if [ \"$current\" -eq \"$stop\" ] ; then\n"
-                << "      echo Error Naming Service failed ! >&2"
-                << "      exit\n"
-                << "    fi\n"
-                << "  done\n"
-                << "  port=`cat " << dfilelogtemp << "`\n";
-
-  // Launching container
-  tempOutputFile << "  " << params.AppliPath << "/runSession SALOME_Container YACS_Server_";
-  tempOutputFile << mpiImpl->rank()
-                << " > ~/" << dirForTmpFiles << "/YACS_Server_" 
-                << mpiImpl->rank() << "_container_log." << filelogtemp
-                << " 2>&1\n";
-  tempOutputFile << "fi" << endl ;
-  tempOutputFile.flush();
-  tempOutputFile.close();
-  chmod(TmpFileName.c_str(), 0x1ED);
+  {
+
+    MpiImpl* mpiImpl = FactoryMpiImpl(params.mpi);
+
+    // Begin
+    tempOutputFile << "#! /bin/sh -f" << endl ;
+    tempOutputFile << "cd ~/" ;
+    tempOutputFile << dirForTmpFiles << endl ;
+    tempOutputFile << "export SALOME_BATCH=1\n";
+    tempOutputFile << "export PYTHONPATH=~/" ;
+    tempOutputFile << dirForTmpFiles ;
+    tempOutputFile << ":$PYTHONPATH" << endl ;
+
+    // Adding user script
+    std::string script = params.userCommands;
+    if (script != "")
+      tempOutputFile << script << endl;
+    // Test node rank
+    tempOutputFile << "if test \"" ;
+    tempOutputFile << mpiImpl->rank() ;
+    tempOutputFile << "\" = \"0\"; then" << endl ;
+
+    // -----------------------------------------------
+    // Code for rank 0 : launch runAppli and a container
+    // RunAppli
+    if(params.ModulesList.size()>0)
+      tempOutputFile << "  " << params.AppliPath << "/runAppli --terminal --modules=" ;
+    else
+      tempOutputFile << "  " << params.AppliPath << "/runAppli --terminal ";
+    for ( int i = 0 ; i < params.ModulesList.size() ; i++ ) {
+      tempOutputFile << params.ModulesList[i] ;
+      if ( i != params.ModulesList.size()-1 )
+       tempOutputFile << "," ;
+    }
+    tempOutputFile << " --standalone=registry,study,moduleCatalog --ns-port-log="
+      << filelogtemp 
+      << " &\n";
+
+    // Wait NamingService
+    tempOutputFile << "  current=0\n"
+      << "  stop=20\n" 
+      << "  while ! test -f " << dfilelogtemp << "\n"
+      << "  do\n"
+      << "    sleep 2\n"
+      << "    let current=current+1\n"
+      << "    if [ \"$current\" -eq \"$stop\" ] ; then\n"
+      << "      echo Error Naming Service failed ! >&2"
+      << "      exit\n"
+      << "    fi\n"
+      << "  done\n"
+      << "  port=`cat " << dfilelogtemp << "`\n";
+
+    // Wait other containers
+    tempOutputFile << "  for ((ip=1; ip < ";
+    tempOutputFile << mpiImpl->size();
+    tempOutputFile << " ; ip++))" << endl;
+    tempOutputFile << "  do" << endl ;
+    tempOutputFile << "    arglist=\"$arglist YACS_Server_\"$ip" << endl ;
+    tempOutputFile << "  done" << endl ;
+    tempOutputFile << "  sleep 5" << endl ;
+    tempOutputFile << "  " << params.AppliPath << "/runSession waitContainers.py $arglist" << endl ;
+
+    // Launch user script
+    tempOutputFile << "  " << params.AppliPath << "/runSession python ~/" << dirForTmpFiles << "/" << fileNameToExecute << ".py" << endl;
+
+    // Stop application
+    tempOutputFile << "  rm " << dfilelogtemp << "\n"
+      << "  " << params.AppliPath << "/runSession shutdownSalome.py" << endl;
+
+    // -------------------------------------
+    // Other nodes launch a container
+    tempOutputFile << "else" << endl ;
+
+    // Wait NamingService
+    tempOutputFile << "  current=0\n"
+      << "  stop=20\n" 
+      << "  while ! test -f " << dfilelogtemp << "\n"
+      << "  do\n"
+      << "    sleep 2\n"
+      << "    let current=current+1\n"
+      << "    if [ \"$current\" -eq \"$stop\" ] ; then\n"
+      << "      echo Error Naming Service failed ! >&2"
+      << "      exit\n"
+      << "    fi\n"
+      << "  done\n"
+      << "  port=`cat " << dfilelogtemp << "`\n";
+
+    // Launching container
+    tempOutputFile << "  " << params.AppliPath << "/runSession SALOME_Container YACS_Server_";
+    tempOutputFile << mpiImpl->rank()
+      << " > ~/" << dirForTmpFiles << "/YACS_Server_" 
+      << mpiImpl->rank() << "_container_log." << filelogtemp
+      << " 2>&1\n";
+    tempOutputFile << "fi" << endl ;
+    tempOutputFile.flush();
+    tempOutputFile.close();
+    chmod(TmpFileName.c_str(), 0x1ED);
 #if defined(_DEBUG_) || defined(_DEBUG)
-  cerr << TmpFileName.c_str() << endl;
+    cerr << TmpFileName.c_str() << endl;
 #endif
 
-  delete mpiImpl;
+    delete mpiImpl;
 
-  return TmpFileName;
+    return TmpFileName;
+  }  
 #else
   return "";
 #endif
-    
 #else
   throw LauncherException("Method Launcher_cpp::buildSalomeCouplingScript is not available "
                           "(libBatch was not present at compilation time)");
@@ -753,7 +834,7 @@ bool Launcher_cpp::check(const batchParams& batch_params)
 #endif
 
   // check memory (check the format)
-  std::string mem_info;
+  std::string mem_info = batch_params.mem;
   std::string mem_value = batch_params.mem;
   if (mem_value != "") {
     std::string begin_mem_value = mem_value.substr(0, mem_value.length()-2);
@@ -907,3 +988,224 @@ std::string Launcher_cpp::getHomeDir(const ParserResourcesType& p, const std::st
   file_home.close();
   return home;
 }
+
+//=============================================================================
+/*!
+ * Add a job into the launcher - check resource and choose one 
+ */ 
+//=============================================================================
+void 
+Launcher_cpp::createJob(Launcher::Job * new_job)
+{
+  LAUNCHER_MESSAGE("Creating a new job");
+  
+  // First step take a resource
+  // Two cases: hostname is defined -> GetFittingResources will check if resource exists
+  //           hostname is not defined -> Try to find a good resource
+  // Note: We use Alias parameter to get the real name of the machine -> To change ????
+  std::vector<std::string> ResourceList;
+  machineParams params = new_job->getMachineRequiredParams();
+  try{
+    ResourceList = _ResManager->GetFittingResources(params);
+  }
+  catch(const ResourcesException &ex){
+    throw LauncherException(ex.msg.c_str());
+  }
+  if (ResourceList.size() == 0)
+  {
+    LAUNCHER_INFOS("No adequate resource found for the job, number " << new_job->getNumber() << " - deleting it");
+    delete new_job;
+    throw LauncherException("No resource found the job");
+  }
+
+  // Second step configure the job with the resource selected - the first of the list
+  ParserResourcesType machine_definition = _ResManager->GetResourcesList(ResourceList[0]);
+  if (machine_definition.Alias == "")
+  {
+    LAUNCHER_INFOS("Alias is not defined for the resource selected: " << machine_definition.HostName);
+    delete new_job;
+    std::string mess = "Alias is not defined for the resource selected: ";
+    mess += machine_definition.HostName;
+    throw LauncherException(mess);
+  }
+  new_job->setMachineDefinition(machine_definition);
+
+  // Part dependent of LIBBATCH - Without it we delete the job and send an exception
+#ifdef WITH_LIBBATCH
+  // Third step search batch manager for the resource into the map -> instanciate one if does not exist
+  std::string machine_name = machine_definition.Alias;
+  std::map<std::string, Batch::BatchManager_eClient *>::const_iterator it = _batchmap.find(machine_name);
+  if(it == _batchmap.end())
+  {
+    try 
+    {
+      _batchmap[machine_name] = FactoryBatchManager(machine_definition);
+    }
+    catch(const LauncherException &ex)
+    {
+      LAUNCHER_INFOS("Error during creation of the batch manager of the resource, mess: " << ex.msg);
+      delete new_job;
+      throw ex;
+    }
+  }
+
+  // Final step - add job to the jobs map
+  std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(new_job->getNumber());
+  if (it_job == _launcher_job_map.end())
+    _launcher_job_map[new_job->getNumber()] = new_job;
+  else
+  {
+    LAUNCHER_INFOS("A job as already the same id: " << new_job->getNumber());
+    delete new_job;
+    throw LauncherException("A job as already the same id - job is not created !");
+  }
+  LAUNCHER_MESSAGE("New Job created");
+#else  
+  LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot create a job !!!");
+  delete new_job;
+  throw LauncherException("Method Launcher_cpp::createJob is not available "
+                          "(libBatch was not present at compilation time)");
+#endif
+}
+
+//=============================================================================
+/*!
+ * Launch a job 
+ */ 
+//=============================================================================
+void 
+Launcher_cpp::launchJob(int job_id)
+{
+  LAUNCHER_MESSAGE("Launch a job");
+
+  // Check if job exist
+  std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
+  if (it_job == _launcher_job_map.end())
+  {
+    LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
+    throw LauncherException("Cannot find the job, is it created ?");
+  }
+
+  Launcher::Job * job = it_job->second;
+
+  // Check job state (cannot launch a job already launched...)
+  if (job->getState() != "CREATED")
+  {
+    LAUNCHER_INFOS("Bad state of the job: " << job->getState());
+    throw LauncherException("Bad state of the job: " + job->getState());
+  }
+
+  // Part dependent of LIBBATCH - Without it we delete the job and send an exception
+#ifdef WITH_LIBBATCH
+
+  std::string machine_name = job->getMachineDefinition().Alias;
+  try {
+    Batch::JobId batch_manager_job_id = _batchmap[machine_name]->submitJob(*(job->getBatchJob()));
+    job->setBatchManagerJobId(batch_manager_job_id);
+    job->setState("QUEUED");
+  }
+  catch(const Batch::EmulationException &ex)
+  {
+    LAUNCHER_INFOS("Job is not launched, exception in submitJob: " << ex.message);
+    throw LauncherException(ex.message.c_str());
+  }
+  LAUNCHER_MESSAGE("Job launched");
+
+#else  
+  LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot launch a job !!!");
+  throw LauncherException("Method Launcher_cpp::launchJob is not available "
+                          "(libBatch was not present at compilation time)");
+#endif
+}
+
+//=============================================================================
+/*!
+ * Get job state
+ */ 
+//=============================================================================
+const char *
+Launcher_cpp::getJobState(int job_id)
+{
+  LAUNCHER_MESSAGE("Get job state");
+
+  // Check if job exist
+  std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
+  if (it_job == _launcher_job_map.end())
+  {
+    LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
+    throw LauncherException("Cannot find the job, is it created ?");
+  }
+
+  Launcher::Job * job = it_job->second;
+  std::string state = job->updateJobState();
+
+  return state.c_str();
+}
+
+//=============================================================================
+/*!
+ * Get Job result - the result directory could be changed
+ */ 
+//=============================================================================
+void
+Launcher_cpp::getJobResults(int job_id, std::string directory)
+{
+  LAUNCHER_MESSAGE("Get Job results");
+
+  // Check if job exist
+  std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
+  if (it_job == _launcher_job_map.end())
+  {
+    LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
+    throw LauncherException("Cannot find the job, is it created ?");
+  }
+
+  Launcher::Job * job = it_job->second;
+
+  // Part dependent of LIBBATCH 
+  // We may have to check job state and only get files when job is fisnished or in error...
+  // We may also change default result directory...
+#ifdef WITH_LIBBATCH
+
+  std::string machine_name = job->getMachineDefinition().Alias;
+  try 
+  {
+    if (directory != "")
+      _batchmap[machine_name]->importOutputFiles(*(job->getBatchJob()), directory);
+    else
+      _batchmap[machine_name]->importOutputFiles(*(job->getBatchJob()), job->getResultDirectory());
+  }
+  catch(const Batch::EmulationException &ex)
+  {
+    LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
+    throw LauncherException(ex.message.c_str());
+  }
+  LAUNCHER_MESSAGE("getJobResult ended");
+
+#else  
+  LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job results!!!");
+  throw LauncherException("Method Launcher_cpp::getJobResults is not available "
+                          "(libBatch was not present at compilation time)");
+#endif
+}
+
+//=============================================================================
+/*!
+ * Remove the job - into the Launcher and its batch manager
+ */ 
+//=============================================================================
+void
+Launcher_cpp::removeJob(int job_id)
+{
+  LAUNCHER_MESSAGE("Remove Job");
+
+  // Check if job exist
+  std::map<int, Launcher::Job *>::iterator it_job = _launcher_job_map.find(job_id);
+  if (it_job == _launcher_job_map.end())
+  {
+    LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
+    throw LauncherException("Cannot find the job, is it created ?");
+  }
+
+  _launcher_job_map.erase(it_job); // Erase call delete on it_job->second
+}
index 279adbdc3e1c3db1a7a3afdd26596151bd832bcf..91b110939a32dcc185f9e239645fba83bb97ffc8 100644 (file)
 #ifndef __LAUNCHER_HXX__
 #define __LAUNCHER_HXX__
 
-#ifdef WIN32
-# if defined LAUNCHER_EXPORTS || defined Launcher_EXPORTS
-#  define LAUNCHER_EXPORT __declspec(dllexport)
-# else
-#  define LAUNCHER_EXPORT __declspec(dllimport)
-# endif
-#else
-# define LAUNCHER_EXPORT
-#endif
+#include "Launcher_Utils.hxx"
+#include "Launcher_Job.hxx"
 
-#include <SALOME_ResourcesCatalog_Parser.hxx>
 #include "ResourcesManager.hxx"
+#include <SALOME_ResourcesCatalog_Parser.hxx>
+
 #include "SALOME_Launcher_Parser.hxx"
 
 #include <string>
@@ -53,14 +47,6 @@ struct batchParams{
   unsigned long nb_proc;
 };
 
-class LAUNCHER_EXPORT LauncherException
-{
-public:
-  const std::string msg;
-
-  LauncherException(const std::string m) : msg(m) {}
-};
-
 class LAUNCHER_EXPORT Launcher_cpp
 {
 
@@ -86,17 +72,26 @@ public:
 
   void SetResourcesManager( ResourcesManager_cpp* rm ) { _ResManager = rm; }
 
+  // New interface
+  void createJob(Launcher::Job * new_job);
+  void launchJob(int job_id);
+  const char * getJobState(int job_id);
+  void getJobResults(int job_id, std::string directory);
+  void removeJob(int job_id);
+
 protected:
 
   std::string buildSalomeCouplingScript(const std::string fileToExecute, const std::string dirForTmpFiles, const ParserResourcesType& params);
   MpiImpl *FactoryMpiImpl(MpiImplType mpiImpl) throw(LauncherException);
-  Batch::BatchManager_eClient *FactoryBatchManager( const ParserResourcesType& params ) throw(LauncherException);
+  Batch::BatchManager_eClient *FactoryBatchManager(ParserResourcesType& params ) throw(LauncherException);
   std::string getTmpDirForBatchFiles();
   std::string getRemoteFile( std::string remoteDir, std::string localFile );
   std::string getHomeDir(const ParserResourcesType& p, const std::string & tmpdir);  
 
   std::map <std::string,Batch::BatchManager_eClient*> _batchmap;
   std::map < std::pair<std::string,long> , Batch::Job* > _jobmap;
+
+  std::map <int, Launcher::Job *> _launcher_job_map;
   ResourcesManager_cpp *_ResManager;
   bool check(const batchParams& batch_params);
   long getWallTime(std::string edt);
diff --git a/src/Launcher/Launcher_Job.cxx b/src/Launcher/Launcher_Job.cxx
new file mode 100644 (file)
index 0000000..4e59642
--- /dev/null
@@ -0,0 +1,395 @@
+//  Copyright (C) 2009 CEA/DEN, EDF R&D
+//
+//  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
+//
+// Author: André RIBES - EDF R&D
+
+#include "Launcher_Job.hxx"
+#include "Launcher.hxx"
+
+Launcher::Job::Job()
+{
+  _number = -1;
+  _state = "CREATED";
+
+  _work_directory = "";
+  _local_directory = "";
+  _result_directory = "";
+  _expected_during_time = "";
+  _expected_during_time_in_second = -1;
+  _machine_required_params.hostname = "";
+  _machine_required_params.OS = "";
+  _machine_required_params.nb_node = -1;
+  _machine_required_params.nb_proc_per_node = -1;
+  _machine_required_params.cpu_clock = -1;
+  _machine_required_params.mem_mb = -1;
+  _machine_required_params.parallelLib = "";
+  _machine_required_params.nb_component_nodes = -1;
+
+#ifdef WITH_LIBBATCH
+  _batch_job = new Batch::Job();
+#endif
+}
+
+Launcher::Job::~Job() 
+{
+  LAUNCHER_MESSAGE("Deleting job number: " << _number);
+#ifdef WITH_LIBBATCH
+  if (_batch_job_id.getReference() != "undefined")
+    _batch_job_id.deleteJob();
+  if (_batch_job)
+    delete _batch_job;
+#endif
+}
+
+void 
+Launcher::Job::setState(const std::string & state)
+{
+  // State of a Job: CREATED, QUEUED, RUNNING, FINISHED, ERROR
+  if (state != "CREATED" and
+      state != "QUEUED" and
+      state != "RUNNING" and
+      state != "FINISHED" and
+      state != "ERROR")
+  {
+    throw LauncherException("Bad state, this state does not exist: " + state);
+  }
+  _state = state;
+}
+
+std::string 
+Launcher::Job::getState()
+{
+  return _state;
+}
+
+void 
+Launcher::Job::setNumber(const int & number)
+{
+  if (_number != -1)
+    std::cerr << "Launcher::Job::setNumber -- Job number was already defined, before: " << _number << " now: " << number << std::endl;
+  _number = number;
+}
+
+int
+Launcher::Job::getNumber()
+{
+  return _number;
+}
+
+void 
+Launcher::Job::setMachineDefinition(const ParserResourcesType & machine_definition)
+{
+  _machine_definition = machine_definition;
+}
+
+ParserResourcesType 
+Launcher::Job::getMachineDefinition()
+{
+  return _machine_definition;
+}
+
+void 
+Launcher::Job::setWorkDirectory(const std::string & work_directory)
+{
+  _work_directory = work_directory;
+}
+
+void 
+Launcher::Job::setLocalDirectory(const std::string & local_directory)
+{
+  _local_directory = local_directory;
+}
+
+void 
+Launcher::Job::setResultDirectory(const std::string & result_directory)
+{
+  _result_directory = result_directory;
+}
+
+void 
+Launcher::Job::add_in_file(const std::string & file)
+{
+  std::list<std::string>::iterator it = std::find(_in_files.begin(), _in_files.end(), file);
+  if (it == _in_files.end())
+    _in_files.push_back(file);
+  else
+    std::cerr << "Launcher::Job::add_in_file -- Warning file was already entered in in_files: " << file << std::endl;
+}
+
+void 
+Launcher::Job::add_out_file(const std::string & file)
+{
+  std::list<std::string>::iterator it = std::find(_out_files.begin(), _out_files.end(), file);
+  if (it == _out_files.end())
+    _out_files.push_back(file);
+  else
+    std::cerr << "Launcher::Job::add_out_file -- Warning file was already entered in out_files: " << file << std::endl;
+}
+
+void 
+Launcher::Job::setExpectedDuringTime(const std::string & expected_during_time)
+{
+  checkExpectedDuringTime(expected_during_time);
+  _expected_during_time_in_second = convertExpectedDuringTime(expected_during_time);
+  _expected_during_time = expected_during_time;
+}
+
+void 
+Launcher::Job::setMachineRequiredParams(const machineParams & machine_required_params)
+{
+  checkMachineRequiredParams(machine_required_params);
+  _machine_required_params = machine_required_params;
+}
+
+std::string 
+Launcher::Job::getWorkDirectory()
+{
+  return _work_directory;
+}
+
+std::string 
+Launcher::Job::getLocalDirectory()
+{
+  return _local_directory;
+}
+
+std::string
+Launcher::Job::getResultDirectory()
+{
+  return _result_directory;
+}
+
+const std::list<std::string> & 
+Launcher::Job::get_in_files()
+{
+  return _in_files;
+}
+
+const std::list<std::string> & 
+Launcher::Job::get_out_files()
+{
+  return _out_files;
+}
+
+std::string 
+Launcher::Job::getExpectedDuringTime()
+{
+  return _expected_during_time;
+}
+
+machineParams 
+Launcher::Job::getMachineRequiredParams()
+{
+  return _machine_required_params;
+}
+
+void 
+Launcher::Job::checkExpectedDuringTime(const std::string & expected_during_time)
+{
+  std::string result("");
+  std::string edt_value = expected_during_time;
+  if (edt_value != "") {
+    std::string begin_edt_value = edt_value.substr(0, 2);
+    std::string mid_edt_value = edt_value.substr(2, 1);
+    std::string end_edt_value = edt_value.substr(3);
+  
+    long value;
+    std::istringstream iss(begin_edt_value);
+    if (!(iss >> value)) {
+      result = "[Launcher::Job::checkExpectedDuringTime] Error on definition ! : " + edt_value;
+    }
+    else if (value < 0) {
+      result = "[Launcher::Job::checkExpectedDuringTime] Error on definition time is negative ! : " + value;
+    }
+    std::istringstream iss_2(end_edt_value);
+    if (!(iss_2 >> value)) {
+      result = "[Launcher::Job::checkExpectedDuringTime] Error on definition ! : " + edt_value;
+    }
+    else if (value < 0) {
+      result = "[Launcher::Job::checkExpectedDuringTime] Error on definition time is negative ! : " + value;
+    }
+    if (mid_edt_value != ":") {
+      result = "[Launcher::Job::checkExpectedDuringTime] Error on definition ! :" + edt_value;
+    }
+  }
+  if (result != "")
+    throw LauncherException(result);
+}
+
+void 
+Launcher::Job::checkMachineRequiredParams(const machineParams & machine_required_params)
+{
+  // nb_node has be to > 0
+  if (machine_required_params.nb_node <= 0)
+  {
+    std::string message("[Launcher::Job::checkMachineRequiredParams] node number is not >0 ! ");
+    throw LauncherException(message);
+  }
+}
+
+long 
+Launcher::Job::convertExpectedDuringTime(const std::string & edt)
+{
+  long hh, mm, ret;
+
+  if( edt.size() == 0 )
+    return 0;
+
+  std::string::size_type pos = edt.find(":");
+  std::string h = edt.substr(0,pos);
+  std::string m = edt.substr(pos+1,edt.size()-pos+1);
+  std::istringstream issh(h);
+  issh >> hh;
+  std::istringstream issm(m);
+  issm >> mm;
+  ret = hh*60 + mm;
+  ret = ret * 60;
+
+  return ret;
+}
+
+std::string
+Launcher::Job::updateJobState()
+{
+#ifdef WITH_LIBBATCH
+  if (_batch_job_id.getReference() != "undefined")
+  {
+    // A batch manager has been affected to the job
+    Batch::JobInfo job_info = _batch_job_id.queryJob();
+    Batch::Parametre par = job_info.getParametre();
+
+    LAUNCHER_MESSAGE("State received is: " << par[STATE].str());
+
+    // Patch until new LIBBATCH version
+    // eSSH Client
+    if (par[STATE].str() == "Running")
+      _state = "RUNNING";
+    else if (par[STATE].str() == "Stopped")
+      _state = "PAUSED";
+    else if (par[STATE].str() == "Done")
+      _state = "FINISHED";
+    else if (par[STATE].str() == "Dead")
+      _state = "ERROR";
+  }
+#endif
+  return _state;
+}
+
+#ifdef WITH_LIBBATCH
+Batch::Job * 
+Launcher::Job::getBatchJob()
+{
+  update_job();
+  return _batch_job;
+}
+
+Batch::Parametre
+Launcher::Job::common_job_params()
+{
+  Batch::Parametre params;
+
+  params[USER] = _machine_definition.UserName;
+  params[NBPROC] = _machine_required_params.nb_node;
+
+  // Memory
+  if (_machine_required_params.mem_mb > 0)
+  {
+    // Memory is in kilobytes
+    params[MAXRAMSIZE] = _machine_required_params.mem_mb * 1024;
+  }
+
+  // We define a default directory based on user time
+  if (_work_directory == "")
+  {
+    std::string thedate;
+    Batch::Date date = Batch::Date(time(0));
+    thedate = date.str();
+    int lend = thedate.size() ;
+    int i = 0 ;
+    while ( i < lend ) {
+      if ( thedate[i] == '/' || thedate[i] == '-' || thedate[i] == ':' ) {
+       thedate[i] = '_' ;
+      }
+      i++ ;
+    }
+    _work_directory = std::string("Batch/");
+    _work_directory += thedate;
+  }
+  params[WORKDIR] = _work_directory;
+  params[TMPDIR] = _work_directory;
+
+  // _in_files
+  for(std::list<std::string>::iterator it = _in_files.begin(); it != _in_files.end(); it++)
+  {
+    std::string file = *it;
+
+    // local file -> If file is not an absolute path, we apply _local_directory
+    std::string local_file;
+    if (file.substr(0, 1) == std::string("/"))
+      local_file = file;
+    else
+      local_file = _local_directory + "/" + file;
+    
+    // remote file -> get only file name from _in_files
+    size_t found = file.find_last_of("/");
+    std::string remote_file = _work_directory + "/" + file.substr(found+1);
+
+    params[INFILE] += Batch::Couple(local_file, remote_file);
+  }
+   
+  // _out_files
+  for(std::list<std::string>::iterator it = _out_files.begin(); it != _out_files.end(); it++)
+  {
+    std::string file = *it;
+
+    // local file -> If result_directory is not defined, we use HOME environnement
+    std::string result_directory = _result_directory;
+    if (result_directory == "")
+      result_directory = getenv("HOME");
+    size_t found = file.find_last_of("/");
+    std::string local_file = result_directory +  "/" + file.substr(found+1);
+
+    // remote file -> If file is not an absolute path, we apply _work_directory
+    std::string remote_file;
+    if (file.substr(0, 1) == std::string("/"))
+      remote_file = file;
+    else
+      remote_file = _work_directory + "/" + file;
+
+    params[OUTFILE] += Batch::Couple(local_file, remote_file);
+  }
+
+  // Time
+  if (_expected_during_time_in_second != -1)
+    params[MAXWALLTIME] = _expected_during_time_in_second;
+
+  return params;
+}
+
+void 
+Launcher::Job::setBatchManagerJobId(Batch::JobId batch_manager_job_id)
+{
+  _batch_job_id = batch_manager_job_id;
+}
+
+Batch::JobId 
+Launcher::Job::getBatchManagerJobId()
+{
+  return _batch_job_id;
+}
+#endif
diff --git a/src/Launcher/Launcher_Job.hxx b/src/Launcher/Launcher_Job.hxx
new file mode 100644 (file)
index 0000000..f4b21a9
--- /dev/null
@@ -0,0 +1,122 @@
+//  Copyright (C) 2009 CEA/DEN, EDF R&D
+//
+//  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
+//
+// Author: André RIBES - EDF R&D
+
+#ifndef _LAUNCHER_JOB_HXX_
+#define _LAUNCHER_JOB_HXX_
+
+#include <SALOMEconfig.h>
+#include "ResourcesManager.hxx"
+
+#include <stdlib.h>
+
+#include <string>
+#include <list>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <exception>
+
+#ifdef WITH_LIBBATCH
+#include <Batch/Batch_Job.hxx>
+#include <Batch/Batch_Date.hxx>
+#include <Batch/Batch_JobId.hxx>
+#endif
+
+namespace Launcher
+{
+  class Job
+  {
+    public:
+      Job();
+      virtual ~Job();
+
+      // Launcher managing parameters
+      // State of a Job: CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR
+      void setState(const std::string & state);
+      std::string getState();
+
+      void setNumber(const int & number);
+      int getNumber();
+
+      void setMachineDefinition(const ParserResourcesType & machine_definition);
+      ParserResourcesType getMachineDefinition();
+      
+      // Common parameters
+      void setWorkDirectory(const std::string & work_directory);
+      void setLocalDirectory(const std::string & local_directory);
+      void setResultDirectory(const std::string & result_directory);
+      void add_in_file(const std::string & file);
+      void add_out_file(const std::string & file);
+      void setExpectedDuringTime(const std::string & expected_during_time);
+      void setMachineRequiredParams(const machineParams & machine_required_params);
+
+      std::string getWorkDirectory();
+      std::string getLocalDirectory();
+      std::string getResultDirectory();
+      const std::list<std::string> & get_in_files();
+      const std::list<std::string> & get_out_files();
+      std::string getExpectedDuringTime();
+      machineParams getMachineRequiredParams();
+      
+      std::string updateJobState();
+
+      // Checks
+      void checkExpectedDuringTime(const std::string & expected_during_time);
+      void checkMachineRequiredParams(const machineParams & machine_required_params);
+
+      // Helps
+      long convertExpectedDuringTime(const std::string & expected_during_time);
+
+      // Abstract class
+      virtual void update_job() = 0;
+
+    private:
+      int _number;
+
+      std::string _state;
+
+      ParserResourcesType _machine_definition;
+
+      std::string _work_directory;
+      std::string _local_directory;
+      std::string _result_directory;
+      std::list<std::string> _in_files;
+      std::list<std::string> _out_files;
+      std::string _expected_during_time;
+      long _expected_during_time_in_second;
+      machineParams _machine_required_params;
+
+#ifdef WITH_LIBBATCH
+    // Connection with LIBBATCH
+    public:      
+      Batch::Job * getBatchJob();
+      Batch::Parametre common_job_params();
+      void setBatchManagerJobId(Batch::JobId batch_manager_job_id);
+      Batch::JobId getBatchManagerJobId();
+
+    protected:
+      Batch::Job * _batch_job;
+      Batch::JobId _batch_job_id;
+#endif
+  };
+}
+
+#endif
+
diff --git a/src/Launcher/Launcher_Job_Command.cxx b/src/Launcher/Launcher_Job_Command.cxx
new file mode 100644 (file)
index 0000000..c66e0ec
--- /dev/null
@@ -0,0 +1,68 @@
+//  Copyright (C) 2009 CEA/DEN, EDF R&D
+//
+//  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
+//
+// Author: André RIBES - EDF R&D
+
+#include "Launcher_Job_Command.hxx"
+
+Launcher::Job_Command::Job_Command(const std::string & command)
+{
+  _command = command;
+  _env_file = "";
+}
+
+Launcher::Job_Command::~Job_Command() {}
+
+void 
+Launcher::Job_Command::setCommand(const std::string & command)
+{
+  _command = command;
+}
+
+std::string 
+Launcher::Job_Command::getCommand()
+{
+  return _command;
+}
+
+void 
+Launcher::Job_Command::setEnvFile(std::string & env_file)
+{
+  _env_file = env_file;
+}
+
+std::string
+Launcher::Job_Command::getEnvFile()
+{
+  return _env_file;
+}
+
+void
+Launcher::Job_Command::update_job()
+{
+#ifdef WITH_LIBBATCH
+  Batch::Parametre params = common_job_params();
+
+  std::string command = "";
+  if (_env_file != "")
+    command = "source " + _env_file + "\n";
+  command += _command;
+  params[EXECUTABLE] = command;
+  _batch_job->setParametre(params);
+#endif
+}
diff --git a/src/Launcher/Launcher_Job_Command.hxx b/src/Launcher/Launcher_Job_Command.hxx
new file mode 100644 (file)
index 0000000..c404af3
--- /dev/null
@@ -0,0 +1,54 @@
+//  Copyright (C) 2009 CEA/DEN, EDF R&D
+//
+//  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
+//
+// Author: André RIBES - EDF R&D
+
+#ifndef _LAUNCHER_JOB_COMMAND_HXX_
+#define _LAUNCHER_JOB_COMMAND_HXX_
+
+#include "Launcher_Job.hxx"
+#include "Launcher.hxx"
+
+#ifdef WITH_LIBBATCH
+#include <Batch/Batch_Job.hxx>
+#endif
+
+namespace Launcher
+{
+  class Job_Command : virtual public Launcher::Job
+  {
+    public:
+      Job_Command(const std::string & command);
+      virtual ~Job_Command();
+
+      // Specific parameters
+      void setCommand(const std::string & command);
+      std::string getCommand();
+      void setEnvFile(std::string & env_file);
+      std::string getEnvFile();
+
+      virtual void update_job();
+
+    private:
+      std::string _command;
+      std::string _env_file;
+  };
+}
+
+#endif
+
diff --git a/src/Launcher/Launcher_Job_YACSFile.cxx b/src/Launcher/Launcher_Job_YACSFile.cxx
new file mode 100644 (file)
index 0000000..c773e61
--- /dev/null
@@ -0,0 +1,56 @@
+//  Copyright (C) 2009 CEA/DEN, EDF R&D
+//
+//  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
+//
+// Author: André RIBES - EDF R&D
+
+#include "Launcher_Job_YACSFile.hxx"
+
+Launcher::Job_YACSFile::Job_YACSFile(const std::string & yacs_file)
+{
+  _yacs_file =  yacs_file;
+}
+
+Launcher::Job_YACSFile::~Job_YACSFile() {}
+
+
+void 
+Launcher::Job_YACSFile::setYACSFile(const std::string & yacs_file)
+{
+  _yacs_file = yacs_file;
+}
+
+std::string 
+Launcher::Job_YACSFile::getYACSFile()
+{
+  return _yacs_file;
+}
+void
+Launcher::Job_YACSFile::update_job()
+{
+#ifdef WITH_LIBBATCH
+  Batch::Parametre params = common_job_params();
+
+  params[EXECUTABLE] = buildSalomeCouplingScript();
+  _batch_job->setParametre(params);
+#endif
+}
+
+std::string 
+Launcher::Job_YACSFile::buildSalomeCouplingScript()
+{
+}
diff --git a/src/Launcher/Launcher_Job_YACSFile.hxx b/src/Launcher/Launcher_Job_YACSFile.hxx
new file mode 100644 (file)
index 0000000..bb61e9f
--- /dev/null
@@ -0,0 +1,54 @@
+//  Copyright (C) 2009 CEA/DEN, EDF R&D
+//
+//  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
+//
+// Author: André RIBES - EDF R&D
+
+#ifndef _LAUNCHER_JOB_YACSFILE_HXX_
+#define _LAUNCHER_JOB_YACSFILE_HXX_
+
+#include "Launcher_Job.hxx"
+#include "Launcher.hxx"
+
+#ifdef WITH_LIBBATCH
+#include <Batch/Batch_Job.hxx>
+#endif
+
+namespace Launcher
+{
+  class Job_YACSFile : virtual public Launcher::Job
+  {
+    public:
+      Job_YACSFile(const std::string & yacs_file);
+      virtual ~Job_YACSFile();
+
+      // Specific parameters
+      void setYACSFile(const std::string & yacs_file);
+      std::string getYACSFile();
+
+      virtual void update_job();
+
+    protected:
+      std::string buildSalomeCouplingScript();
+
+    private:
+      std::string _yacs_file;
+  };
+}
+
+#endif
+
diff --git a/src/Launcher/Launcher_Utils.hxx b/src/Launcher/Launcher_Utils.hxx
new file mode 100644 (file)
index 0000000..2aa8b95
--- /dev/null
@@ -0,0 +1,57 @@
+//  Copyright (C) 2009 CEA/DEN, EDF R&D
+//
+//  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
+//
+// Author: André RIBES - EDF R&D
+
+#ifndef __LAUNCHER_UTILS_HXX__
+#define __LAUNCHER_UTILS_HXX__
+
+#include <iostream>
+
+#ifdef WIN32
+# if defined LAUNCHER_EXPORTS || defined Launcher_EXPORTS
+#  define LAUNCHER_EXPORT __declspec(dllexport)
+# else
+#  define LAUNCHER_EXPORT __declspec(dllimport)
+# endif
+#else
+# define LAUNCHER_EXPORT
+#endif
+
+// MESSAGES
+#define LAUNCHER_MESS_INIT(deb) std::cerr << deb
+#define LAUNCHER_MESS_BEGIN(deb) LAUNCHER_MESS_INIT(deb)<<__FILE__ <<" ["<<__LINE__<<"] : "
+#define LAUNCHER_MESS_END std::endl;
+#define LAUNCHER_INFOS(msg) {LAUNCHER_MESS_BEGIN("- Trace ") << msg << LAUNCHER_MESS_END}
+
+#if defined(_DEBUG_) || defined(_DEBUG)
+#define LAUNCHER_MESSAGE(msg) {LAUNCHER_MESS_BEGIN("- Trace ") << msg << LAUNCHER_MESS_END}
+#else /* ifdef _DEBUG_*/
+#define LAUNCHER_MESSAGE(msg) {}
+#endif /* ifdef _DEBUG_*/
+
+class LAUNCHER_EXPORT LauncherException
+{
+public:
+  const std::string msg;
+
+  LauncherException(const std::string m) : msg(m) {}
+};
+
+
+#endif
index fc49e1121e3a75ce3349ee1418a31a0ce8bd622b..847d97aeaffa15b9a774f1c276a2348f084d5a59 100644 (file)
@@ -33,6 +33,10 @@ salomeinclude_HEADERS = \
   BatchTest.hxx \
   SALOME_Launcher_defs.hxx \
   SALOME_Launcher.hxx \
+  Launcher_Utils.hxx \
+  Launcher_Job.hxx \
+  Launcher_Job_Command.hxx \
+  Launcher_Job_YACSFile.hxx \
   Launcher.hxx
 
 # Scripts to be installed
@@ -112,6 +116,10 @@ libSalomeLauncher_la_LIBADD =\
 libLauncher_la_SOURCES=\
        SALOME_Launcher_Parser.cxx \
        SALOME_Launcher_Handler.cxx  \
+       Launcher_Utils.hxx \
+       Launcher_Job.cxx \
+       Launcher_Job_Command.cxx \
+       Launcher_Job_YACSFile.cxx \
        Launcher.cxx
 
 libLauncher_la_CPPFLAGS =\
index 9ec5bf1f992d6e5c4aae804b00f70d803bf6ed8d..9387f20ca8fb7ed515e266002dafe539df903e75 100644 (file)
 #include "SALOME_ContainerManager.hxx"
 #include "Utils_CorbaException.hxx"
 
+
+#include "Launcher_Job_Command.hxx"
+#include "Launcher_Job_YACSFile.hxx"
+
 #ifdef WIN32
 # include <process.h>
 #else
@@ -63,6 +67,8 @@ SALOME_Launcher::SALOME_Launcher(CORBA::ORB_ptr orb, PortableServer::POA_var poa
   Engines::SalomeLauncher_var refContMan = Engines::SalomeLauncher::_narrow(obj);
 
   _NS->Register(refContMan,_LauncherNameInNS);
+
+  _job_cpt = 0;
   MESSAGE("SALOME_Launcher constructor end");
 }
 
@@ -184,6 +190,162 @@ CORBA::Long SALOME_Launcher::submitSalomeJob( const char * fileToExecute ,
   return jobId;
 }
 
+CORBA::Long 
+SALOME_Launcher::createJob(const Engines::JobParameters & job_parameters)
+{
+  std::string job_type = job_parameters.job_type.in();
+  
+  if (job_type != "command" and job_type != "yacs_file")
+  {
+    std::string message("SALOME_Launcher::createJob: bad job type: ");
+    message += job_type;
+    THROW_SALOME_CORBA_EXCEPTION(message.c_str(), SALOME::INTERNAL_ERROR);
+  }
+
+  Launcher::Job * new_job; // It is Launcher_cpp that is going to destroy it
+
+  if (job_type == "command")
+  {
+    std::string command = job_parameters.command.in();
+    if (command == "")
+    {
+      std::string message("SALOME_Launcher::createJob: command is empty !");
+      THROW_SALOME_CORBA_EXCEPTION(message.c_str(), SALOME::INTERNAL_ERROR);
+    }
+    Launcher::Job_Command * job = new Launcher::Job_Command(command);
+    new_job = job;
+
+    std::string env_file = job_parameters.env_file.in();
+    job->setEnvFile(env_file);
+  }
+  else if (job_type == "yacs_file")
+  {
+    std::string yacs_file = job_parameters.yacs_file.in();
+    if (yacs_file == "")
+    {
+      std::string message("SALOME_Launcher::createJob: yacs_file is empty !");
+      THROW_SALOME_CORBA_EXCEPTION(message.c_str(), SALOME::INTERNAL_ERROR);
+    }
+    new_job = new Launcher::Job_YACSFile(yacs_file);
+  }
+
+  // Not thread safe... TODO !
+  new_job->setNumber(_job_cpt);
+  _job_cpt++;
+  // End Not thread safe
+  // Directories
+  std::string work_directory = job_parameters.work_directory.in();
+  std::string local_directory = job_parameters.local_directory.in();
+  std::string result_directory = job_parameters.result_directory.in();
+  new_job->setWorkDirectory(work_directory);
+  new_job->setLocalDirectory(local_directory);
+  new_job->setResultDirectory(result_directory);
+
+  // Files
+  for (CORBA::ULong i = 0; i < job_parameters.in_files.length(); i++)
+    new_job->add_in_file(job_parameters.in_files[i].in());
+  for (CORBA::ULong i = 0; i < job_parameters.out_files.length(); i++)
+    new_job->add_out_file(job_parameters.out_files[i].in());
+  
+  // Expected During Time
+  try
+  {
+    std::string expected_during_time = job_parameters.expected_during_time.in();
+    new_job->setExpectedDuringTime(expected_during_time);
+  }
+  catch(const LauncherException &ex){
+    INFOS(ex.msg.c_str());
+    THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
+  }
+   
+  // Resources requirements
+  try
+  {
+    machineParams p;
+    p.hostname = job_parameters.resource_required.hostname;
+    p.OS = job_parameters.resource_required.OS;
+    p.nb_node = job_parameters.resource_required.nb_node;
+    p.nb_proc_per_node = job_parameters.resource_required.nb_proc_per_node;
+    p.cpu_clock = job_parameters.resource_required.cpu_clock;
+    p.mem_mb = job_parameters.resource_required.mem_mb;
+    new_job->setMachineRequiredParams(p);
+  }
+  catch(const LauncherException &ex){
+    INFOS(ex.msg.c_str());
+    THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
+  }
+
+  try
+  {
+    _l.createJob(new_job);
+  }
+  catch(const LauncherException &ex)
+  {
+    INFOS(ex.msg.c_str());
+    THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
+  }
+  return new_job->getNumber();
+}
+
+void 
+SALOME_Launcher::launchJob(CORBA::Long job_id)
+{
+  try
+  {
+    _l.launchJob(job_id);
+  }
+  catch(const LauncherException &ex)
+  {
+    INFOS(ex.msg.c_str());
+    THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
+  }
+}
+
+char *
+SALOME_Launcher::getJobState(CORBA::Long job_id)
+{
+  std::string result;
+  try
+  {
+    result = _l.getJobState(job_id);
+  }
+  catch(const LauncherException &ex)
+  {
+    INFOS(ex.msg.c_str());
+    THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
+  }
+  return CORBA::string_dup(result.c_str());
+}
+
+void
+SALOME_Launcher::getJobResults(CORBA::Long job_id, const char * directory)
+{
+  try
+  {
+    _l.getJobResults(job_id, directory);
+  }
+  catch(const LauncherException &ex)
+  {
+    INFOS(ex.msg.c_str());
+    THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
+  }
+}
+
+void 
+SALOME_Launcher::removeJob(CORBA::Long job_id)
+{
+  try
+  {
+    _l.removeJob(job_id);
+  }
+  catch(const LauncherException &ex)
+  {
+    INFOS(ex.msg.c_str());
+    THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
+  }
+}
+
 //=============================================================================
 /*! CORBA Method:
  *  the test batch configuration 
@@ -302,4 +464,3 @@ void SALOME_Launcher::getResultsJob( const char *directory,
     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
   }
 }
-
index 9263d5c68394343a55fc6e158e12358f819164c5..b574b1681b73de5d6992fd93d3056cc830fa17db 100644 (file)
@@ -59,6 +59,12 @@ public:
   void deleteJob( CORBA::Long jobId, const Engines::MachineParameters& params);
   void getResultsJob( const char * directory, CORBA::Long jobId, const Engines::MachineParameters& params );
 
+  CORBA::Long createJob(const Engines::JobParameters & job_parameters);
+  void launchJob(CORBA::Long job_id);
+  char * getJobState(CORBA::Long job_id);
+  void getJobResults(CORBA::Long job_id, const char * directory);
+  void removeJob(CORBA::Long job_id);
+
   CORBA::Boolean testBatch(const Engines::MachineParameters& params);
 
   void Shutdown();
@@ -74,6 +80,8 @@ protected:
   SALOME_ResourcesManager *_ResManager;
   SALOME_NamingService *_NS;
 
+  int _job_cpt;
+
   Launcher_cpp _l;
 };
 
index 4234cda85e3162dacf7a25ce2f6c9518aac7d22f..c5e03db7d2dfd9d49c58d767276755805ea337f0 100755 (executable)
@@ -468,6 +468,7 @@ SALOME_ResourcesCatalog_Handler::ProcessMachine(xmlNodePtr machine_descr, Parser
 
   if (xmlHasProp(machine_descr, (const xmlChar*)test_batch))
   {
+    std::cerr << "COUCOU !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
     xmlChar* batch = xmlGetProp(machine_descr, (const xmlChar*)test_batch);
     std::string aBatch = (const char*)batch;
     xmlFree(batch);
@@ -477,6 +478,8 @@ SALOME_ResourcesCatalog_Handler::ProcessMachine(xmlNodePtr machine_descr, Parser
       resource.Batch = lsf;
     else if  (aBatch == "sge")
       resource.Batch = sge;
+    else if  (aBatch == "ssh_batch")
+      resource.Batch = ssh_batch;
     else
       resource.Batch = none;
   }
@@ -654,6 +657,9 @@ void SALOME_ResourcesCatalog_Handler::PrepareDocToXmlFile(xmlDocPtr theDoc)
        case sge:
          xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "sge");
           break;
+       case ssh_batch:
+         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "ssh_batch");
+          break;
         default:
          xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "");
         }
@@ -743,6 +749,9 @@ void SALOME_ResourcesCatalog_Handler::PrepareDocToXmlFile(xmlDocPtr theDoc)
        case sge:
          xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "sge");
           break;
+       case ssh_batch:
+         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "ssh_batch");
+          break;
         default:
          xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "");
         }
index e4ad2d55f1b80723e31b95667ed11e54361c0e8c..9c1cf39834c273dd577bc17bbbd8d9e970e108df 100755 (executable)
@@ -40,7 +40,7 @@ enum AccessProtocolType {rsh, ssh};
 
 enum AccessModeType {interactive, batch};
 
-enum BatchType {none, pbs, lsf, sge};
+enum BatchType {none, pbs, lsf, sge, ssh_batch};
 
 enum MpiImplType {nompi, lam, mpich1, mpich2, openmpi, slurm, prun};