From: ribes Date: Tue, 10 Nov 2009 09:23:01 +0000 (+0000) Subject: Start New Version of SALOME Launcher X-Git-Tag: new_launcher_alpha_091119~11 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=dbabf3431299516e6e7e05e6c5a79ed90960dd88;p=modules%2Fkernel.git Start New Version of SALOME Launcher - New IDL API added - Job Command works --- diff --git a/idl/SALOME_ContainerManager.idl b/idl/SALOME_ContainerManager.idl index 16ffacd19..2dcff5b4d 100644 --- a/idl/SALOME_ContainerManager.idl +++ b/idl/SALOME_ContainerManager.idl @@ -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 diff --git a/src/Launcher/Launcher.cxx b/src/Launcher/Launcher.cxx index 17dfdaa4b..941374355 100644 --- a/src/Launcher/Launcher.cxx +++ b/src/Launcher/Launcher.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #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 , Batch::Job* >::const_iterator it2; for(it2=_jobmap.begin();it2!=_jobmap.end();it2++) delete it2->second; + + std::map::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;irank() ; - 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 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::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::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::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::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::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::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 +} diff --git a/src/Launcher/Launcher.hxx b/src/Launcher/Launcher.hxx index 279adbdc3..91b110939 100644 --- a/src/Launcher/Launcher.hxx +++ b/src/Launcher/Launcher.hxx @@ -22,18 +22,12 @@ #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 #include "ResourcesManager.hxx" +#include + #include "SALOME_Launcher_Parser.hxx" #include @@ -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 _batchmap; std::map < std::pair , Batch::Job* > _jobmap; + + std::map _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 index 000000000..4e596425e --- /dev/null +++ b/src/Launcher/Launcher_Job.cxx @@ -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::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::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 & +Launcher::Job::get_in_files() +{ + return _in_files; +} + +const std::list & +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::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::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 index 000000000..f4b21a9ad --- /dev/null +++ b/src/Launcher/Launcher_Job.hxx @@ -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 +#include "ResourcesManager.hxx" + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef WITH_LIBBATCH +#include +#include +#include +#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 & get_in_files(); + const std::list & 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 _in_files; + std::list _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 index 000000000..c66e0ec12 --- /dev/null +++ b/src/Launcher/Launcher_Job_Command.cxx @@ -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 index 000000000..c404af3aa --- /dev/null +++ b/src/Launcher/Launcher_Job_Command.hxx @@ -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 +#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 index 000000000..c773e6154 --- /dev/null +++ b/src/Launcher/Launcher_Job_YACSFile.cxx @@ -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 index 000000000..bb61e9f4f --- /dev/null +++ b/src/Launcher/Launcher_Job_YACSFile.hxx @@ -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 +#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 index 000000000..2aa8b950f --- /dev/null +++ b/src/Launcher/Launcher_Utils.hxx @@ -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 + +#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 diff --git a/src/Launcher/Makefile.am b/src/Launcher/Makefile.am index fc49e1121..847d97aea 100644 --- a/src/Launcher/Makefile.am +++ b/src/Launcher/Makefile.am @@ -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 =\ diff --git a/src/Launcher/SALOME_Launcher.cxx b/src/Launcher/SALOME_Launcher.cxx index 9ec5bf1f9..9387f20ca 100644 --- a/src/Launcher/SALOME_Launcher.cxx +++ b/src/Launcher/SALOME_Launcher.cxx @@ -25,6 +25,10 @@ #include "SALOME_ContainerManager.hxx" #include "Utils_CorbaException.hxx" + +#include "Launcher_Job_Command.hxx" +#include "Launcher_Job_YACSFile.hxx" + #ifdef WIN32 # include #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); } } - diff --git a/src/Launcher/SALOME_Launcher.hxx b/src/Launcher/SALOME_Launcher.hxx index 9263d5c68..b574b1681 100644 --- a/src/Launcher/SALOME_Launcher.hxx +++ b/src/Launcher/SALOME_Launcher.hxx @@ -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; }; diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx index 4234cda85..c5e03db7d 100755 --- a/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx @@ -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 ""); } diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx index e4ad2d55f..9c1cf3983 100755 --- a/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx @@ -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};