-// Copyright (C) 2007-2008 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 "Batch_BatchManager_eClient.hxx"
-#include "Batch_RunTimeException.hxx"
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctime>
#include <iostream>
#include <fstream>
#include <sstream>
+#include <stdlib.h>
+
#ifdef WIN32
#include <direct.h>
+#include <io.h>
#endif
-#include "Batch_config.h"
+#include <Batch_config.h>
+
+#include "Batch_Constants.hxx"
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_RunTimeException.hxx"
+
+#ifdef MSVC
+#define EXISTS(path) _access_s(path, 0) == 0
+#else
+#define EXISTS(path) access(path, F_OK) == 0
+#endif
using namespace std;
namespace Batch {
BatchManager_eClient::BatchManager_eClient(const Batch::FactBatchManager * parent, const char* host,
- const char* protocol, const char* mpiImpl)
- : BatchManager(parent, host), _protocol(protocol), _username("")
+ const char * username,
+ CommunicationProtocolType protocolType, const char* mpiImpl)
+ : BatchManager(parent, host), _protocol(CommunicationProtocol::getInstance(protocolType)),
+ _username(username)
{
// instanciation of mpi implementation needed to launch executable in batch script
_mpiImpl = FactoryMpiImpl(mpiImpl);
// Destructeur
BatchManager_eClient::~BatchManager_eClient()
{
- // Nothing to do
- delete _mpiImpl;
+ if (_mpiImpl)
+ delete _mpiImpl;
}
void BatchManager_eClient::exportInputFiles(const Job& job)
{
int status;
Parametre params = job.getParametre();
- Versatile V = params[INFILE];
- Versatile::iterator Vit;
- _username = string(params[USER]);
-
- string command = "\"";
- string copy_command = "\"";
-
- // Test protocol
- if( _protocol == "rsh" ) {
- command += RSH;
- copy_command += RCP;
- } else if( _protocol == "ssh" ) {
- command += SSH;
- copy_command += SCP;
- } else
- throw EmulationException("Unknown protocol : only rsh and ssh are known !");
-
- command += "\" ";
- copy_command += "\" ";
-
- // First step : creating batch tmp files directory
- if(_username != ""){
- command += _username + "@";
- }
- command += _hostname;
- command += " mkdir -p ";
- command += string(params[TMPDIR]);
- cerr << command.c_str() << endl;
- status = system(command.c_str());
+ const Versatile & V = params[INFILE];
+ Versatile::const_iterator Vit;
+
+ status = _protocol.makeDirectory(string(params[TMPDIR]) + "/logs", _hostname, _username);
if(status) {
std::ostringstream oss;
oss << status;
// Second step : copy fileToExecute into
// batch tmp files directory
string executeFile = params[EXECUTABLE];
- if( executeFile.size() > 0 ){
- command = copy_command;
- command += string(params[EXECUTABLE]);
- command += " ";
- if(_username != ""){
- command += _username;
- command += "@";
- }
- command += _hostname;
- command += ":";
- command += string(params[TMPDIR]);
- cerr << command.c_str() << endl;
- status = system(command.c_str());
+ if (executeFile.size() != 0) {
+ status = _protocol.copyFile(executeFile, "", "",
+ params[TMPDIR], _hostname, _username);
if(status) {
std::ostringstream oss;
oss << status;
}
#ifdef WIN32
- // On Windows, we make the remote file executable afterward because pscp does not preserve
- // access permissions on files
- command = "\"";
- if( _protocol == "rsh" ) {
- command += RSH;
- } else if( _protocol == "ssh" ) {
- command += SSH;
- } else
- throw EmulationException("Unknown protocol : only rsh and ssh are known !");
-
- command += "\" ";
- if(_username != ""){
- command += _username + "@";
- }
- command += _hostname;
- command += " chmod u+x ";
- command += string(params[TMPDIR]) + "/" + string(params[EXECUTABLE]);
+ // On Windows, we make the remote file executable afterward because
+ // pscp does not preserve access permissions on files
+ string subCommand = string("chmod u+x ") + string(params[TMPDIR]) + "/" +
+ string(params[EXECUTABLE]);
+ string command = _protocol.getExecCommand(subCommand, _hostname, _username);
cerr << command.c_str() << endl;
status = system(command.c_str());
if(status) {
for(Vit=V.begin(); Vit!=V.end(); Vit++) {
CoupleType cpt = *static_cast< CoupleType * >(*Vit);
Couple inputFile = cpt;
- command = copy_command;
- command += inputFile.getLocal();
- command += " ";
- if(_username != ""){
- command += _username;
- command += "@";
- }
- command += _hostname;
- command += ":";
- command += inputFile.getRemote();
- cerr << command.c_str() << endl;
- status = system(command.c_str());
+ status = _protocol.copyFile(inputFile.getLocal(), "", "",
+ inputFile.getRemote(), _hostname, _username);
if(status) {
std::ostringstream oss;
oss << status;
}
- void BatchManager_eClient::importOutputFiles( const Job & job, const string directory ) throw(EmulationException)
+ void BatchManager_eClient::importOutputFiles( const Job & job, const string directory )
{
- int status;
-
Parametre params = job.getParametre();
- Versatile V = params[OUTFILE];
- Versatile::iterator Vit;
+ const Versatile & V = params[OUTFILE];
+ Versatile::const_iterator Vit;
+
+ // Create local result directory
+ int status = CommunicationProtocol::getInstance(SH).makeDirectory(directory, "", "");
+ if (status) {
+ string mess("Directory creation failed. Status is :");
+ ostringstream status_str;
+ status_str << status;
+ mess += status_str.str();
+ cerr << mess << endl;
+ }
for(Vit=V.begin(); Vit!=V.end(); Vit++) {
CoupleType cpt = *static_cast< CoupleType * >(*Vit);
Couple outputFile = cpt;
-
- string command = "\"";
-
- // Test protocol
- if( _protocol == "rsh" ) {
- command += RCP;
- } else if( _protocol == "ssh" ) {
- command += SCP;
- } else
- throw EmulationException("Unknown protocol : only rsh and ssh are known !");
-
- command += "\" ";
-
- if (_username != ""){
- command += _username;
- command += "@";
- }
- command += _hostname;
- command += ":";
- command += outputFile.getRemote();
- command += " ";
- command += directory;
- cerr << command.c_str() << endl;
- status = system(command.c_str());
- if(status)
- {
+ status = _protocol.copyFile(outputFile.getRemote(), _hostname, _username,
+ directory, "", "");
+ if (status) {
// Try to get what we can (logs files)
// throw BatchException("Error of connection on remote host");
std::string mess("Copy command failed ! status is :");
}
}
+ // Copy logs
+ 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;
+ }
+
+ }
+
+ bool BatchManager_eClient::importDumpStateFile( const Job & job, const string directory )
+ {
+ Parametre params = job.getParametre();
+
+ // Create local result directory
+ int status = CommunicationProtocol::getInstance(SH).makeDirectory(directory, "", "");
+ if (status) {
+ string mess("Directory creation failed. Status is :");
+ ostringstream status_str;
+ status_str << status;
+ mess += status_str.str();
+ cerr << mess << endl;
+ }
+
+ bool ret = true;
+ status = _protocol.copyFile(string(params[TMPDIR]) + string("/dumpState*.xml"), _hostname, _username,
+ directory, "", "");
+ if (status) {
+ // Try to get what we can (logs files)
+ // throw BatchException("Error of connection on remote host");
+ std::string mess("Copy command failed ! status is :");
+ ostringstream status_str;
+ status_str << status;
+ mess += status_str.str();
+ cerr << mess << endl;
+ ret = false;
+ }
+ return ret;
}
- MpiImpl *BatchManager_eClient::FactoryMpiImpl(string mpiImpl) throw(EmulationException)
+ MpiImpl *BatchManager_eClient::FactoryMpiImpl(string mpiImpl)
{
if(mpiImpl == "lam")
return new MpiImpl_LAM();
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";
do {
sprintf(randstr, "%06d", rand() % 1000000);
fileName.replace(fileName.size()-6, 6, randstr);
- } while (access(fileName.c_str(), F_OK) == 0);
+ } while (EXISTS(fileName.c_str()));
return fileName;
}
#ifdef WIN32
string fileName = generateTemporaryFileName(prefix);
- outputStream.open(fileName.c_str());
+ // Open the file as binary to avoid problems with Windows newlines
+ outputStream.open(fileName.c_str(), ios_base::binary | ios_base::out);
#else
string fileName = getTmpDir() + "/" + prefix + "-XXXXXX";
- char buf[fileName.size()+1];
+ char * buf = new char[fileName.size()+1];
fileName.copy(buf, fileName.size());
buf[fileName.size()] = '\0';
int fd = mkstemp(buf);
- if (fd == -1)
+ if (fd == -1) {
+ delete[] buf;
throw RunTimeException(string("Can't create temporary file ") + fileName);
+ }
fileName = buf;
+ delete[] buf;
outputStream.open(fileName.c_str());
close(fd); // Close the file descriptor so that the file is not opened twice
const std::string & BatchManager_eClient::getTmpDir()
{
if (tmpDirName.empty()) {
- char * baseDir = getenv("TEMP");
+ const char * baseDir = getenv("TEMP");
if (baseDir == NULL) baseDir = getenv("TMP");
if (baseDir == NULL) baseDir = getenv("TEMPDIR");
if (baseDir == NULL) baseDir = getenv("TMPDIR");
if (baseDir == NULL) baseDir = "/tmp";
- char * userName = getenv("USER");
+ const char * userName = getenv("USER");
if (userName == NULL) userName = getenv("USERNAME");
if (userName == NULL) userName = "unknown";
do {
sprintf(randstr, "%06d", rand() % 1000000);
baseName.replace(baseName.size()-6, 6, randstr);
- } while (access(baseName.c_str(), F_OK) == 0);
+ } while (EXISTS(baseName.c_str()));
if (_mkdir(baseName.c_str()) != 0)
throw RunTimeException(string("Can't create temporary directory ") + baseName);
tmpDirName = baseName;
#else
- char buf[baseName.size()+1];
+ char * buf = new char[baseName.size() + 1];
baseName.copy(buf, baseName.size());
buf[baseName.size()] = '\0';
- if (mkdtemp(buf) == NULL)
+ if (mkdtemp(buf) == NULL) {
+ delete[] buf;
throw RunTimeException(string("Can't create temporary directory ") + baseName);
+ }
tmpDirName = buf;
+ delete[] buf;
#endif