Salome HOME
Fix remote directories in file transfer and merge some tests
[tools/libbatch.git] / src / CCC / Batch_BatchManager_eCCC.cxx
index ce521ab62f6f9abaa95469ee2c432fe55579d621..0d8f50986580647b9a32f0310c6cc5d03b28f51a 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//  Copyright (C) 2007-2012  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
 #include <libgen.h>
 #endif
 
+#include <Batch_Constants.hxx>
+#include <Batch_NotYetImplementedException.hxx>
+#include <Batch_Utils.hxx>
+
 #include "Batch_BatchManager_eCCC.hxx"
 #include "Batch_JobInfo_eCCC.hxx"
 
@@ -55,9 +59,9 @@ using namespace std;
 namespace Batch {
 
   BatchManager_eCCC::BatchManager_eCCC(const FactBatchManager * parent, const char * host,
+                                       const char * username,
                                        CommunicationProtocolType protocolType, const char * mpiImpl)
-  : BatchManager_eClient(parent, host, protocolType, mpiImpl),
-    BatchManager(parent, host)
+  : BatchManager(parent, host, username, protocolType, mpiImpl)
   {
     // Nothing to do
   }
@@ -71,7 +75,6 @@ namespace Batch {
   // Methode pour le controle des jobs : soumet un job au gestionnaire
   const JobId BatchManager_eCCC::submitJob(const Job & job)
   {
-    int status;
     Parametre params = job.getParametre();
     const std::string workDir = params[WORKDIR];
     const string fileToExecute = params[EXECUTABLE];
@@ -88,43 +91,39 @@ namespace Batch {
     buildBatchScript(job);
     cerr << "Script envoye" << endl;
 
-    // define name of log file (local)
-    string logFile = generateTemporaryFileName("CCC-submitlog");
-
     // define command to submit batch
-    string subCommand = string("cd ") + workDir + "; ccc_msub " + fileNameToExecute + "_Batch.sh";
+    string subCommand = string("bash -l -c \\\"cd ") + workDir + "; ccc_msub " + 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)
-    {
-      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());
+    // submit job
+    string output;
+    int status = Utils::getCommandOutput(command, output);
+    cout << output;
+    if (status != 0) throw RunTimeException("Can't submit job, error was: " + output);
+
+    // find id of submitted job in output
+    istringstream idfile(output);
     string sidj;
     idfile >> sidj;
     idfile >> sidj;
     idfile >> sidj;
     idfile >> sidj;
-    idfile.close();
     if (sidj.size() == 0)
-      throw EmulationException("Error in the submission of the job on the remote host");
+      throw RunTimeException("Error in the submission of the job on the remote host");
 
     JobId id(this, sidj);
     return id;
   }
 
+  // Ce manager permet de faire de la reprise
+  const Batch::JobId
+  BatchManager_eCCC::addJob(const Batch::Job & job, const std::string reference)
+  {
+    return JobId(this, reference);
+  }
+
   // Methode pour le controle des jobs : retire un job du gestionnaire
   void BatchManager_eCCC::deleteJob(const JobId & jobid)
   {
@@ -134,12 +133,12 @@ namespace Batch {
     iss >> ref;
 
     // define command to delete batch
-    string subCommand = string("ccc_mdel ") + iss.str();
+    string subCommand = string("bash -l -c \\\"ccc_mdel ") + iss.str() + string("\\\"");
     string command = _protocol.getExecCommand(subCommand, _hostname, _username);
     cerr << command.c_str() << endl;
     status = system(command.c_str());
     if (status)
-      throw EmulationException("Error of connection on remote host");
+      throw RunTimeException("Error of connection on remote host");
 
     cerr << "jobId = " << ref << "killed" << endl;
   }
@@ -147,20 +146,20 @@ namespace Batch {
   // Methode pour le controle des jobs : suspend un job en file d'attente
   void BatchManager_eCCC::holdJob(const JobId & jobid)
   {
-    throw EmulationException("Not yet implemented");
+    throw NotYetImplementedException("BatchManager_eCCC::holdJob");
   }
 
   // Methode pour le controle des jobs : relache un job suspendu
   void BatchManager_eCCC::releaseJob(const JobId & jobid)
   {
-    throw EmulationException("Not yet implemented");
+    throw NotYetImplementedException("BatchManager_eCCC::releaseJob");
   }
 
 
   // Methode pour le controle des jobs : modifie un job en file d'attente
   void BatchManager_eCCC::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env)
   {
-    throw EmulationException("Not yet implemented");
+    throw NotYetImplementedException("BatchManager_eCCC::alterJob");
   }
 
   // Methode pour le controle des jobs : modifie un job en file d'attente
@@ -182,20 +181,17 @@ namespace Batch {
     istringstream iss(jobid.getReference());
     iss >> id;
 
-    // define name of log file (local)
-    string logFile = generateTemporaryFileName(string("CCC-querylog-id") + jobid.getReference());
-
     // define command to query batch
-    string subCommand = string("bjobs ") + iss.str();
+    string subCommand = string("bash -l -c \\\"bjobs ") + iss.str() + string("\\\"");
     string command = _protocol.getExecCommand(subCommand, _hostname, _username);
-    command += " > ";
-    command += logFile;
     cerr << command.c_str() << endl;
-    int status = system(command.c_str());
+
+    string output;
+    int status = Utils::getCommandOutput(command, output);
     if (status)
-      throw EmulationException("Error of connection on remote host");
+      throw RunTimeException("Error of connection on remote host");
 
-    JobInfo_eCCC ji = JobInfo_eCCC(id,logFile);
+    JobInfo_eCCC ji = JobInfo_eCCC(id, output);
     return ji;
   }
 
@@ -204,7 +200,7 @@ namespace Batch {
   // Methode pour le controle des jobs : teste si un job est present en machine
   bool BatchManager_eCCC::isRunning(const JobId & jobid)
   {
-    throw EmulationException("Not yet implemented");
+    throw NotYetImplementedException("BatchManager_eCCC::isRunning");
   }
 
   void BatchManager_eCCC::buildBatchScript(const Job & job)
@@ -224,17 +220,17 @@ namespace Batch {
     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");
+      throw RunTimeException("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");
+      throw RunTimeException("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];
+      edt = (long)params[MAXWALLTIME] * 60;
     if (params.find(MAXRAMSIZE) != params.end()) 
       mem = params[MAXRAMSIZE];
     if (params.find(QUEUE) != params.end()) 
@@ -247,15 +243,15 @@ namespace Batch {
  
     // Create batch submit file
     ofstream tempOutputFile;
-    std::string TmpFileName = createAndOpenTemporaryFile("LSF-script", tempOutputFile);
+    std::string TmpFileName = Utils::createAndOpenTemporaryFile("LSF-script", tempOutputFile);
 
-    tempOutputFile << "#! /bin/sh -f" << endl ;
+    tempOutputFile << "#!/bin/bash" << endl ;
     if (queue != "")
       tempOutputFile << "#MSUB -q " << queue << endl;
     if( edt > 0 )
       tempOutputFile << "#MSUB -T " << edt << endl ;
     if( mem > 0 )
-      tempOutputFile << "#MSUB -M " << mem/1024 << endl ;
+      tempOutputFile << "#MSUB -M " << mem << endl ;
     tempOutputFile << "#MSUB -n " << nbproc << endl ;
     size_t pos = workDir.find("$HOME");
     string baseDir;
@@ -281,14 +277,17 @@ namespace Batch {
     tempOutputFile << "    bool=1" << endl;
     tempOutputFile << "  else" << endl;
     tempOutputFile << "    for ((j=0;j<$i;j++)); do" << endl;
-    tempOutputFile << "      echo $n >> nodesFile" << endl;
+    tempOutputFile << "      echo $n >> nodesFile." << rootNameToExecute << 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;
+    tempOutputFile << "export LIBBATCH_NODEFILE=nodesFile." << rootNameToExecute << endl;
+
+    // Allow resource sharing in CCRT nodes
+    tempOutputFile << "export OMPI_MCA_orte_process_binding=none" << endl;
 
     // Launch the executable
     tempOutputFile << "./" + fileNameToExecute << endl;
@@ -302,7 +301,7 @@ namespace Batch {
                                     workDir + "/" + rootNameToExecute + "_Batch.sh",
                                     _hostname, _username);
     if (status)
-      throw EmulationException("Error of connection on remote host");
+      throw RunTimeException("Error of connection on remote host");
 
 #endif
 
@@ -311,20 +310,20 @@ namespace Batch {
   std::string BatchManager_eCCC::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;
+    string subCommand = string("echo ");
+    subCommand += tmpdir;
+    string command = _protocol.getExecCommand(subCommand, _hostname, _username);
     cerr << command.c_str() << endl;
-    int status = system(command.c_str());
+
+    string output;
+    int status = Utils::getCommandOutput(command, output);
+
     if (status)
-      throw EmulationException("Error of launching home command on remote host");
+      throw RunTimeException("Error of launching home command on remote host");
 
-    std::ifstream file_home(filelogtemp.c_str());
+    std::istringstream file_home(output);
     std::getline(file_home, home);
-    file_home.close();
     return home;
   }