From e6e0742b10ec3772c51efb373c1c2f9849315d2a Mon Sep 17 00:00:00 2001 From: secher Date: Thu, 5 Jun 2008 11:47:44 +0000 Subject: [PATCH] after merge with V4_1_3rc1 --- bin/runSalome.py | 1 + configure.ac | 4 +- idl/SALOME_ContainerManager.idl | 2 + idl/SALOME_ModuleCatalog.idl | 3 +- salome_adm/unix/config_files/check_lsf.m4 | 2 +- src/Batch/Batch_BatchManager_eLSF.cxx | 9 +- src/Batch/Batch_BatchManager_ePBS.cxx | 47 +- src/Batch/Batch_JobInfo_LSF.cxx | 2 +- src/Batch/Batch_Parametre.cxx | 4 + src/Batch/Batch_Parametre.hxx | 2 + src/Batch/Makefile.am | 2 +- src/Container/Component_i.cxx | 55 +- src/Container/Container_i.cxx | 176 ++++- src/Container/SALOME_Component_i.hxx | 8 + src/Container/SALOME_ContainerManager.cxx | 77 +- src/Container/SALOME_ContainerManager.hxx | 9 +- src/Container/SALOME_ContainerPy.py | 9 + src/DSC/DSC_Basic/DSC_i.cxx | 13 + src/DSC/DSC_Basic/DSC_i.hxx | 6 + .../DSC_User/Datastream/Calcium/Calcium.cxx | 2 +- .../Calcium/CalciumCouplingPolicy.cxx | 12 + .../Calcium/CalciumCouplingPolicy.hxx | 6 + src/DSC/DSC_User/Superv_Component_i.cxx | 14 + src/DSC/DSC_User/Superv_Component_i.hxx | 6 + src/Launcher/BatchTest.cxx | 689 ++++++++++++++++++ src/Launcher/BatchTest.hxx | 60 ++ src/Launcher/Launcher.cxx | 60 +- src/Launcher/Launcher.hxx | 1 + src/Launcher/Makefile.am | 2 + src/Launcher/SALOME_Launcher.cxx | 35 + src/Launcher/SALOME_Launcher.hxx | 3 + .../SALOME_ModuleCatalog_Acomponent_impl.hxx | 2 +- .../SALOME_ModuleCatalog_Handler.cxx | 2 + .../SALOME_ModuleCatalog_impl.cxx | 2 + src/NOTIFICATION_SWIG/Makefile.am | 2 - src/ResourcesManager/ResourcesManager.cxx | 15 +- src/ResourcesManager/ResourcesManager.hxx | 3 + .../SALOME_ResourcesCatalog_Handler.cxx | 127 +++- .../SALOME_ResourcesCatalog_Handler.hxx | 4 +- .../SALOME_ResourcesCatalog_Parser.cxx | 3 +- .../SALOME_ResourcesCatalog_Parser.hxx | 1 + .../SALOME_ResourcesManager.cxx | 8 +- .../SALOME_ResourcesManager.hxx | 4 + 43 files changed, 1413 insertions(+), 81 deletions(-) create mode 100644 src/Launcher/BatchTest.cxx create mode 100644 src/Launcher/BatchTest.hxx diff --git a/bin/runSalome.py b/bin/runSalome.py index f20b50794..dc256253e 100755 --- a/bin/runSalome.py +++ b/bin/runSalome.py @@ -597,6 +597,7 @@ def startSalome(args, modules_list, modules_root_dir): # set PYTHONINSPECT variable if args['pinter']: os.environ["PYTHONINSPECT"]="1" + import readline return clt diff --git a/configure.ac b/configure.ac index 96e62e718..46c0db90a 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ # ================================================================ # #AC_PREREQ(2.59) -AC_INIT([Salome2 Project], [4.1.2], [paul.rascle@edf.fr], [SalomeKer]) +AC_INIT([Salome2 Project], [4.1.3], [paul.rascle@edf.fr], [SalomeKer]) # AC_CONFIG_AUX_DIR defines an alternative directory where to find the auxiliary # scripts such as config.guess, install-sh, ... @@ -14,7 +14,7 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([tar-pax]) #AC_CONFIG_HEADER([config.h]) -XVERSION=0x040102 +XVERSION=0x040103 AC_SUBST(XVERSION) # set up MODULE_NAME variable for dynamic construction of directories (resources, etc.) diff --git a/idl/SALOME_ContainerManager.idl b/idl/SALOME_ContainerManager.idl index 9acf9a708..01942e44a 100644 --- a/idl/SALOME_ContainerManager.idl +++ b/idl/SALOME_ContainerManager.idl @@ -100,6 +100,8 @@ struct BatchParameters void deleteJob( in long jobId, in MachineParameters params ) raises (SALOME::SALOME_Exception); void getResultsJob( in string directory, in long jobId, in MachineParameters params ) raises (SALOME::SALOME_Exception); + boolean testBatch(in MachineParameters params) raises (SALOME::SALOME_Exception); + void Shutdown(); long getPID(); diff --git a/idl/SALOME_ModuleCatalog.idl b/idl/SALOME_ModuleCatalog.idl index dfc8764f6..9231f7e39 100644 --- a/idl/SALOME_ModuleCatalog.idl +++ b/idl/SALOME_ModuleCatalog.idl @@ -171,7 +171,8 @@ Implementation type enum ImplType { SO, /* component implemented as a dynamic library loadable with dlopen */ PY, /* component implemented as a python module loadable with import */ - EXE /* component implemented as an executable */ + EXE, /* component implemented as an executable */ + CEXE /* component to be loaded by a container which executable is given in the catalog */ } ; /*! diff --git a/salome_adm/unix/config_files/check_lsf.m4 b/salome_adm/unix/config_files/check_lsf.m4 index a4faddb3c..7f140f7cd 100755 --- a/salome_adm/unix/config_files/check_lsf.m4 +++ b/salome_adm/unix/config_files/check_lsf.m4 @@ -49,7 +49,7 @@ AC_DEFUN([CHECK_LSF], else LSF_LDFLAGS="-L${LSF_LIBDIR}" fi - LSF_LIBS="" + LSF_LIBS="-lbat -llsf" saved_LDFLAGS=${LDFLAGS} saved_LIBS=${LIBS} LDFLAGS="${LDFLAGS} ${LSF_LDFLAGS}" diff --git a/src/Batch/Batch_BatchManager_eLSF.cxx b/src/Batch/Batch_BatchManager_eLSF.cxx index 15eb740a3..7e5443f2b 100644 --- a/src/Batch/Batch_BatchManager_eLSF.cxx +++ b/src/Batch/Batch_BatchManager_eLSF.cxx @@ -242,6 +242,7 @@ namespace Batch { const string workDir = params[WORKDIR]; const std::string dirForTmpFiles = params[TMPDIR]; const string fileToExecute = params[EXECUTABLE]; + const string home = params[HOMEDIR]; std::string rootNameToExecute; std::string fileNameToExecute; std::string filelogtemp; @@ -269,12 +270,12 @@ namespace Batch { tempOutputFile << "#BSUB -M " << mem*1024 << endl ; tempOutputFile << "#BSUB -n " << nbproc << endl ; if( fileToExecute.size() > 0 ){ - tempOutputFile << "#BSUB -o output.log." << filelogtemp << endl ; - tempOutputFile << "#BSUB -e error.log." << filelogtemp << endl ; + tempOutputFile << "#BSUB -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ; + tempOutputFile << "#BSUB -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ; } else{ - tempOutputFile << "#BSUB -o " << env["LOGFILE"] << ".output.log" << endl ; - tempOutputFile << "#BSUB -e " << env["LOGFILE"] << ".error.log" << endl ; + tempOutputFile << "#BSUB -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ; + tempOutputFile << "#BSUB -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ; } if( workDir.size() > 0 ) tempOutputFile << "cd " << workDir << endl ; diff --git a/src/Batch/Batch_BatchManager_ePBS.cxx b/src/Batch/Batch_BatchManager_ePBS.cxx index d17081640..cf5fb3eeb 100644 --- a/src/Batch/Batch_BatchManager_ePBS.cxx +++ b/src/Batch/Batch_BatchManager_ePBS.cxx @@ -229,19 +229,29 @@ namespace Batch { { int status; Parametre params = job.getParametre(); + Environnement env = job.getEnvironnement(); const long nbproc = params[NBPROC]; const long edt = params[MAXWALLTIME]; const long mem = params[MAXRAMSIZE]; const string workDir = params[WORKDIR]; const std::string dirForTmpFiles = params[TMPDIR]; const string fileToExecute = params[EXECUTABLE]; - string::size_type p1 = fileToExecute.find_last_of("/"); - string::size_type p2 = fileToExecute.find_last_of("."); - std::string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1); - std::string fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(fileToExecute.c_str())); - - int idx = dirForTmpFiles.find("Batch/"); - std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length()); + const string home = params[HOMEDIR]; + std::string rootNameToExecute; + std::string fileNameToExecute; + std::string filelogtemp; + if( fileToExecute.size() > 0 ){ + string::size_type p1 = fileToExecute.find_last_of("/"); + string::size_type p2 = fileToExecute.find_last_of("."); + rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1); + fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(fileToExecute.c_str())); + + int idx = dirForTmpFiles.find("Batch/"); + filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length()); + } + else{ + rootNameToExecute = "command"; + } std::string TmpFileName = BuildTemporaryFileName(); ofstream tempOutputFile; @@ -252,13 +262,26 @@ namespace Batch { tempOutputFile << "#PBS -l walltime=" << edt*60 << endl ; if( mem > 0 ) tempOutputFile << "#PBS -l mem=" << mem << "mb" << endl ; - tempOutputFile << "#PBS -o runSalome.output.log." << filelogtemp << endl ; - tempOutputFile << "#PBS -e runSalome.error.log." << filelogtemp << endl ; + if( fileToExecute.size() > 0 ){ + tempOutputFile << "#PBS -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ; + tempOutputFile << "#PBS -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ; + } + else{ + tempOutputFile << "#PBS -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ; + tempOutputFile << "#PBS -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ; + } if( workDir.size() > 0 ) tempOutputFile << "cd " << workDir << endl ; - tempOutputFile << _mpiImpl->boot("${PBS_NODEFILE}",nbproc); - tempOutputFile << _mpiImpl->run("${PBS_NODEFILE}",nbproc,fileNameToExecute); - tempOutputFile << _mpiImpl->halt(); + if( fileToExecute.size() > 0 ){ + tempOutputFile << _mpiImpl->boot("${PBS_NODEFILE}",nbproc); + tempOutputFile << _mpiImpl->run("${PBS_NODEFILE}",nbproc,fileNameToExecute); + tempOutputFile << _mpiImpl->halt(); + } + else{ + tempOutputFile << "source " << env["SOURCEFILE"] << endl ; + tempOutputFile << env["COMMAND"]; + } + tempOutputFile.flush(); tempOutputFile.close(); chmod(TmpFileName.c_str(), 0x1ED); diff --git a/src/Batch/Batch_JobInfo_LSF.cxx b/src/Batch/Batch_JobInfo_LSF.cxx index 0e4715af7..2ae986cd0 100644 --- a/src/Batch/Batch_JobInfo_LSF.cxx +++ b/src/Batch/Batch_JobInfo_LSF.cxx @@ -84,7 +84,7 @@ namespace Batch { _param[TEXT] = jobInfo.numReasons ? lsb_pendreason(jobInfo.numReasons, jobInfo.reasonTb, p_jInfoHead, - p_ld) : ""; + p_ld,0) : ""; // _param[TMPDIR] = jobInfo.; _param[USEDCPUTIME] = static_cast(jobInfo.cpuTime); // _param[USEDDISKSIZE] = jobInfo.; diff --git a/src/Batch/Batch_Parametre.cxx b/src/Batch/Batch_Parametre.cxx index d7cfd076b..b218cc443 100644 --- a/src/Batch/Batch_Parametre.cxx +++ b/src/Batch/Batch_Parametre.cxx @@ -72,6 +72,7 @@ def_static_MapKey(USEDRAMSIZE); def_static_MapKey(USEDWALLTIME); def_static_MapKey(USER); def_static_MapKey(WORKDIR); +def_static_MapKey(HOMEDIR); namespace Batch { @@ -195,6 +196,9 @@ namespace Batch { TypeMap[WORKDIR].type = STRING; TypeMap[WORKDIR].maxelem = 1; + + TypeMap[HOMEDIR].type = STRING; + TypeMap[HOMEDIR].maxelem = 1; } // Operateur de recherche dans la map diff --git a/src/Batch/Batch_Parametre.hxx b/src/Batch/Batch_Parametre.hxx index bd9a9f294..ce88da4f9 100644 --- a/src/Batch/Batch_Parametre.hxx +++ b/src/Batch/Batch_Parametre.hxx @@ -103,6 +103,7 @@ namespace Batch { static const string USEDWALLTIME; static const string USER; static const string WORKDIR; + static const string HOMEDIR; protected: map< string, TypeParam > TypeMap; // map interne servant a controler le type de la valeur associee a chaque clef @@ -151,5 +152,6 @@ def_extern_MapKey(USEDRAMSIZE); def_extern_MapKey(USEDWALLTIME); def_extern_MapKey(USER); def_extern_MapKey(WORKDIR); +def_extern_MapKey(HOMEDIR); #endif diff --git a/src/Batch/Makefile.am b/src/Batch/Makefile.am index e00d64868..0a44180b9 100644 --- a/src/Batch/Makefile.am +++ b/src/Batch/Makefile.am @@ -210,7 +210,7 @@ LIB_SRC += \ Batch_Job_LSF.cxx LIB_CPPFLAGS += ${LSF_INCLUDES} -LIB_LIBADD += ${LSF_LIBDIR} ${LSF_LIBS} +LIB_LIBADD += ${LSF_LDFLAGS} ${LSF_LIBS} endif diff --git a/src/Container/Component_i.cxx b/src/Container/Component_i.cxx index cfeeefc9b..867411196 100644 --- a/src/Container/Component_i.cxx +++ b/src/Container/Component_i.cxx @@ -106,6 +106,7 @@ Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, _poa = PortableServer::POA::_duplicate(poa); _contId = contId ; CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior... + _container=Engines::Container::_narrow(o); const CORBA::String_var ior = _orb->object_to_string(o); _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession", _instanceName.c_str()); @@ -114,6 +115,56 @@ Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, //SCRUTE(pd_refCount); } +//============================================================================= +/*! + * Standard Constructor for standalone Component, used in derived class + * Connection to Registry and Notification + * \param orb Object Request broker given by Container + * \param poa Portable Object Adapter from Container (normally root_poa) + * \param container container CORBA reference + * \param instanceName unique instance name for this object (see Container_i) + * \param interfaceName component class name + * \param notif use of notification + */ +//============================================================================= + +Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : + _instanceName(instanceName), + _interfaceName(interfaceName), + _myConnexionToRegistry(0), + _notifSupplier(0), + _ThreadId(0) , + _ThreadCpuUsed(0) , + _Executed(false) , + _graphName("") , + _nodeName(""), + _studyId(-1), + _CanceledThread(false) +{ + MESSAGE("Component constructor with instanceName "<< _instanceName); + _orb = CORBA::ORB::_duplicate(orb); + _poa = PortableServer::POA::_duplicate(poa); + _container=Engines::Container::_duplicate(container); + try + { + _contId=_poa->reference_to_id(container); + } + catch(PortableServer::POA::WrongAdapter) + { + //not created by this poa + _contId = 0; + } + const CORBA::String_var ior = _orb->object_to_string(_container); + _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession", _instanceName.c_str()); + _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif); +} + + //============================================================================= /*! * Standard constructor for parallel component @@ -261,9 +312,7 @@ void Engines_Component_i::destroy() Engines::Container_ptr Engines_Component_i::GetContainerRef() { - // MESSAGE("Engines_Component_i::GetContainerRef"); - CORBA::Object_var o = _poa->id_to_reference(*_contId) ; - return Engines::Container::_narrow(o); + return Engines::Container::_duplicate(_container); } //============================================================================= diff --git a/src/Container/Container_i.cxx b/src/Container/Container_i.cxx index 41e2b5b61..0095b0bc5 100644 --- a/src/Container/Container_i.cxx +++ b/src/Container/Container_i.cxx @@ -337,6 +337,78 @@ void Engines_Container_i::Shutdown() } } +/* int checkifexecutable(const char *filename) + * + * Return non-zero if the name is an executable file, and + * zero if it is not executable, or if it does not exist. + */ + +int checkifexecutable(const char *filename) +{ + int result; + struct stat statinfo; + + result = stat(filename, &statinfo); + if (result < 0) return 0; + if (!S_ISREG(statinfo.st_mode)) return 0; + + if (statinfo.st_uid == geteuid()) return statinfo.st_mode & S_IXUSR; + if (statinfo.st_gid == getegid()) return statinfo.st_mode & S_IXGRP; + return statinfo.st_mode & S_IXOTH; +} + + +/* int findpathof(char *pth, const char *exe) + * + * Find executable by searching the PATH environment variable. + * + * const char *exe - executable name to search for. + * char *pth - the path found is stored here, space + * needs to be available. + * + * If a path is found, returns non-zero, and the path is stored + * in pth. If exe is not found returns 0, with pth undefined. + */ + +int findpathof(char *pth, const char *exe) +{ + char *searchpath; + char *beg, *end; + int stop, found; + int len; + + if (strchr(exe, '/') != NULL) { + if (realpath(exe, pth) == NULL) return 0; + return checkifexecutable(pth); + } + + searchpath = getenv("PATH"); + if (searchpath == NULL) return 0; + if (strlen(searchpath) <= 0) return 0; + + beg = searchpath; + stop = 0; found = 0; + do { + end = strchr(beg, ':'); + if (end == NULL) { + stop = 1; + strncpy(pth, beg, PATH_MAX); + len = strlen(pth); + } else { + strncpy(pth, beg, end - beg); + pth[end - beg] = '\0'; + len = end - beg; + } + if (pth[len - 1] != '/') strncat(pth, "/", 1); + strncat(pth, exe, PATH_MAX - len); + found = checkifexecutable(pth); + if (!stop) beg = end + 1; + } while (!stop && !found); + + return found; +} + + //============================================================================= /*! @@ -424,9 +496,16 @@ Engines_Container_i::load_component_Library(const char* componentName) return true; } } + // Try to find an executable + std::string executable=aCompName+".exe"; + char path[PATH_MAX+1]; + if (findpathof(path, executable.c_str())) + return true; + INFOS( "Impossible to load component: " << componentName ); INFOS( "Can't load shared library: " << impl_name ); INFOS( "Can't import Python module: " << componentName ); + INFOS( "Can't execute program: " << executable ); return false; } @@ -504,12 +583,7 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName, #else string impl_name = genericRegisterName +string("Engine.dll"); #endif - if (_library_map.count(impl_name) == 0) - { - INFOS("shared library " << impl_name <<" must be loaded before creating instance"); - return Engines::Component::_nil() ; - } - else + if (_library_map.count(impl_name) != 0) // C++ component { void* handle = _library_map[impl_name]; iobject = createInstance(genericRegisterName, @@ -517,6 +591,96 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName, studyId); return iobject._retn(); } + + // If it's not a Python or a C++ component try to launch a standalone component + // in a sub directory + // This component is implemented in an executable with name genericRegisterName.exe + // It must register itself in Naming Service. The container waits some time (10 s max) + // it's registration. + + _numInstanceMutex.lock() ; // lock on the instance number + _numInstance++ ; + int numInstance = _numInstance ; + _numInstanceMutex.unlock() ; + + char aNumI[12]; + sprintf( aNumI , "%d" , numInstance ) ; + string instanceName = aCompName + "_inst_" + aNumI ; + string component_registerName = _containerName + "/" + instanceName; + + //check if an entry exist in naming service + CORBA::Object_var nsobj = _NS->Resolve(component_registerName.c_str()); + if ( !CORBA::is_nil(nsobj) ) + { + // unregister the registered component + _NS->Destroy_Name(component_registerName.c_str()); + //kill or shutdown it ??? + } + + // first arg container ior string + // second arg container name + // third arg instance name + + Engines::Container_var pCont= _this(); + CORBA::String_var sior = _orb->object_to_string(pCont); + + std::string command; + command="mkdir -p "; + command+=instanceName; + command+=";cd "; + command+=instanceName; + command+=";"; + command+=genericRegisterName ; + command+=".exe"; + command+=" "; + command+= sior; // container ior string + command+=" "; + command+=_containerName; //container name + command+=" "; + command+=instanceName; //instance name + command+=" &"; + MESSAGE("SALOME_Container::create_component_instance command=" << command); + // launch component with a system call + int status=system(command.c_str()); + + if (status == -1) + { + MESSAGE("SALOME_Container::create_component_instance system failed " << "(system command status -1)"); + return Engines::Component::_nil(); + } + else if (WEXITSTATUS(status) == 217) + { + MESSAGE("SALOME_Container::create_component_instance system failed " << "(system command status 217)"); + return Engines::Component::_nil(); + } + else + { + int count=10; + CORBA::Object_var obj = CORBA::Object::_nil() ; + while ( CORBA::is_nil(obj) && count ) + { +#ifndef WNT + sleep( 1 ) ; +#else + Sleep(1000); +#endif + count-- ; + MESSAGE( count << ". Waiting for component " << genericRegisterName); + obj = _NS->Resolve(component_registerName.c_str()); + } + + if(CORBA::is_nil(obj)) + { + MESSAGE("SALOME_Container::create_component_instance failed"); + return Engines::Component::_nil(); + } + else + { + MESSAGE("SALOME_Container::create_component_instance successful"); + iobject=Engines::Component::_narrow(obj); + return iobject._retn(); + } + } } //============================================================================= diff --git a/src/Container/SALOME_Component_i.hxx b/src/Container/SALOME_Component_i.hxx index 03234c307..3d49b89c5 100644 --- a/src/Container/SALOME_Component_i.hxx +++ b/src/Container/SALOME_Component_i.hxx @@ -61,6 +61,13 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + //Constructor for standalone component + Engines_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); // Consructeur pour composant parallele: ne pas faire appel au registry Engines_Component_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, @@ -147,6 +154,7 @@ protected: PortableServer::POA_var _poa; PortableServer::ObjectId * _id; PortableServer::ObjectId * _contId; + Engines::Container_var _container; Engines_Component_i * _thisObj ; RegistryConnexion *_myConnexionToRegistry; NOTIFICATION_Supplier* _notifSupplier; diff --git a/src/Container/SALOME_ContainerManager.cxx b/src/Container/SALOME_ContainerManager.cxx index 36965e71f..20f46f6d7 100644 --- a/src/Container/SALOME_ContainerManager.cxx +++ b/src/Container/SALOME_ContainerManager.cxx @@ -19,6 +19,7 @@ // #include "SALOME_ContainerManager.hxx" #include "SALOME_NamingService.hxx" +#include "SALOME_ModuleCatalog.hh" #include "OpUtil.hxx" #include #include @@ -199,7 +200,7 @@ Engines::Container_ptr SALOME_ContainerManager:: StartContainer(const Engines::MachineParameters& params, const Engines::MachineList& possibleComputers, - Engines::ResPolicy policy) + Engines::ResPolicy policy,const std::string& container_exe) { #ifdef WITH_PACO_PARALLEL std::string parallelLib(params.parallelLib); @@ -259,9 +260,9 @@ StartContainer(const Engines::MachineParameters& params, return Engines::Container::_nil(); } else if(theMachine==GetHostname()) - command = BuildCommandToLaunchLocalContainer(params,id); + command = BuildCommandToLaunchLocalContainer(params,id,container_exe); else - command = BuildCommandToLaunchRemoteContainer(theMachine,params,id); + command = BuildCommandToLaunchRemoteContainer(theMachine,params,id,container_exe); RmTmpFile(); @@ -349,7 +350,55 @@ StartContainer(const Engines::MachineParameters& params, const Engines::CompoList& componentList) { Engines::MachineList_var possibleComputers = _ResManager->GetFittingResources(params,componentList); - return StartContainer(params,possibleComputers,policy); + + // Look into ModulCatalog if a specific container must be launched + CORBA::String_var container_exe; + int found=0; + try + { + CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog"); + SALOME_ModuleCatalog::ModuleCatalog_var Catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ; + if (CORBA::is_nil (Catalog)) + return Engines::Container::_nil(); + // Loop through component list + for(int i=0;iGetComponent(compoi); + if (CORBA::is_nil (compoInfo)) + { + INFOS("ContainerManager Error: Component not found in the catalog" ); + INFOS( compoi ); + return Engines::Container::_nil(); + } + SALOME_ModuleCatalog::ImplType impl=compoInfo->implementation_type(); + container_exe=compoInfo->implementation_name(); + if(impl==SALOME_ModuleCatalog::CEXE) + { + if(found) + { + INFOS("ContainerManager Error: you can't have 2 CEXE component in the same container" ); + return Engines::Container::_nil(); + } + found=1; + } + } + } + catch (ServiceUnreachable&) + { + INFOS("Caught exception: Naming Service Unreachable"); + return Engines::Container::_nil(); + } + catch (...) + { + INFOS("Caught unknown exception."); + return Engines::Container::_nil(); + } + + if(found) + return StartContainer(params,possibleComputers,policy,container_exe.in()); + else + return StartContainer(params,possibleComputers,policy); } #ifdef WITH_PACO_PARALLEL @@ -515,9 +564,15 @@ GiveContainer(const Engines::MachineParameters& params, if(valenv) if (strcmp(valenv,"1")==0) { - if(_batchLaunchedContainers.empty()) - fillBatchLaunchedContainers(); - return *(_batchLaunchedContainersIter++); + if(_batchLaunchedContainers.empty()) + fillBatchLaunchedContainers(); + + if (_batchLaunchedContainersIter == _batchLaunchedContainers.end()) + _batchLaunchedContainersIter = _batchLaunchedContainers.begin(); + + Engines::Container_ptr rtn = Engines::Container::_duplicate(*_batchLaunchedContainersIter); + _batchLaunchedContainersIter++; + return rtn; } return StartContainer(params,policy,componentList); } @@ -732,7 +787,7 @@ bool isPythonContainer(const char* ContainerName) string SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer (const string& machine, - const Engines::MachineParameters& params, const long id) + const Engines::MachineParameters& params, const long id,const std::string& container_exe) { string command; int nbproc; @@ -816,7 +871,7 @@ SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer command += " SALOME_MPIContainer "; } else - command += " SALOME_Container "; + command += " " +container_exe+ " "; command += _NS->ContainerName(params); command += " -id "; @@ -839,7 +894,7 @@ SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer -(const Engines::MachineParameters& params, const long id) +(const Engines::MachineParameters& params, const long id,const std::string& container_exe) { _TmpFileName = ""; string command; @@ -900,7 +955,7 @@ SALOME_ContainerManager::BuildCommandToLaunchLocalContainer if (isPythonContainer(params.container_name)) command += "SALOME_ContainerPy.py "; else - command += "SALOME_Container "; + command += container_exe + " "; } command += _NS->ContainerName(params); diff --git a/src/Container/SALOME_ContainerManager.hxx b/src/Container/SALOME_ContainerManager.hxx index d8be68833..869b9c235 100644 --- a/src/Container/SALOME_ContainerManager.hxx +++ b/src/Container/SALOME_ContainerManager.hxx @@ -47,7 +47,8 @@ public: Engines::Container_ptr StartContainer(const Engines::MachineParameters& params, const Engines::MachineList& possibleComputer, - Engines::ResPolicy policy); + Engines::ResPolicy policy, + const std::string& container_exe="SALOME_Container"); Engines::Container_ptr StartContainer(const Engines::MachineParameters& params, @@ -88,9 +89,11 @@ protected: long GetIdForContainer(void); std::string BuildCommandToLaunchRemoteContainer(const std::string& machine, - const Engines::MachineParameters& params, const long id); + const Engines::MachineParameters& params, const long id, + const std::string& container_exe="SALOME_Container"); - std::string BuildCommandToLaunchLocalContainer(const Engines::MachineParameters& params, const long id); + std::string BuildCommandToLaunchLocalContainer(const Engines::MachineParameters& params, const long id, + const std::string& container_exe="SALOME_Container"); std::string BuildTempFileToLaunchRemoteContainer(const std::string& machine, const Engines::MachineParameters& params) throw(SALOME_Exception); diff --git a/src/Container/SALOME_ContainerPy.py b/src/Container/SALOME_ContainerPy.py index 1694bc79d..db23b6c79 100755 --- a/src/Container/SALOME_ContainerPy.py +++ b/src/Container/SALOME_ContainerPy.py @@ -307,6 +307,13 @@ class SALOME_ContainerPy_i (Engines__POA.Container): self._orb.shutdown(0) pass + def _get_logfilename(self): + return self._logfilename + def _set_logfilename(self,logfilename): + self._logfilename=logfilename + def _get_workingdir(self): + return os.getcwd() + #============================================================================= #initialise the ORB and find the root POA @@ -323,6 +330,8 @@ cpy_i = SALOME_ContainerPy_i(orb, poa, containerName) print "SALOME_ContainerPy_i instance created ",cpy_i cpy_o = cpy_i._this() print "SALOME_ContainerPy_i instance activated ",cpy_o +sys.stdout.flush() +sys.stderr.flush() #activate the POA poaManager = poa._get_the_POAManager() diff --git a/src/DSC/DSC_Basic/DSC_i.cxx b/src/DSC/DSC_Basic/DSC_i.cxx index bf67a554c..2daa87423 100644 --- a/src/DSC/DSC_Basic/DSC_i.cxx +++ b/src/DSC/DSC_Basic/DSC_i.cxx @@ -42,5 +42,18 @@ Engines_DSC_i(CORBA::ORB_ptr orb, #endif } +Engines_DSC_i:: +Engines_DSC_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : Engines_Component_i(orb, poa, container, instanceName, interfaceName) +{ +#ifdef _DEBUG_ + std::cerr << "--Engines_DSC_i: MARK 1 --" << instanceName << "----" << std::endl; +#endif +} + Engines_DSC_i::~Engines_DSC_i() {} diff --git a/src/DSC/DSC_Basic/DSC_i.hxx b/src/DSC/DSC_Basic/DSC_i.hxx index 6a495f9ce..a66be1d56 100644 --- a/src/DSC/DSC_Basic/DSC_i.hxx +++ b/src/DSC/DSC_Basic/DSC_i.hxx @@ -56,6 +56,12 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + Engines_DSC_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); virtual ~Engines_DSC_i(); diff --git a/src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx b/src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx index 39a8cac49..fde8203a8 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx +++ b/src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx @@ -13,7 +13,7 @@ PySupervCompo::PySupervCompo( CORBA::ORB_ptr orb, const char *instanceName, const char *interfaceName, bool notif) : - Superv_Component_i(orb, poa,poa->reference_to_id(contain), instanceName, interfaceName) + Superv_Component_i(orb, poa,contain, instanceName, interfaceName) { } diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.cxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.cxx index 2a18b69e3..6835898f9 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.cxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.cxx @@ -38,12 +38,18 @@ void CalciumCouplingPolicy::setDependencyType (CalciumTypes::DependencyType depe CalciumTypes::DependencyType CalciumCouplingPolicy::getDependencyType () const { return _dependencyType;} void CalciumCouplingPolicy::setStorageLevel (size_t storageLevel) { +#ifdef _DEBUG_ + std::cerr << "CalciumCouplingPolicy::setStorageLevel: " << storageLevel << std::endl; +#endif if ( storageLevel < 1 && (storageLevel != CalciumTypes::UNLIMITED_STORAGE_LEVEL) ) throw CalciumException(CalciumTypes::CPRENA,LOC("Un niveau < 1 n'est pas autorisé")); _storageLevel = storageLevel; } size_t CalciumCouplingPolicy::getStorageLevel () const {return _storageLevel;} void CalciumCouplingPolicy::setDateCalSchem (CalciumTypes::DateCalSchem dateCalSchem) { +#ifdef _DEBUG_ + std::cerr << "CalciumCouplingPolicy::setDateCalSchem: " << dateCalSchem << std::endl; +#endif if ( _dependencyType != CalciumTypes::TIME_DEPENDENCY ) throw CalciumException(CalciumTypes::CPITVR,LOC("Il est impossible de positionner un schéma temporel sur un port qui n'est pas en dépendance temporelle")); _dateCalSchem = dateCalSchem; @@ -52,6 +58,9 @@ void CalciumCouplingPolicy::setDateCalSchem (CalciumTypes::DateCalSchem da CalciumTypes::DateCalSchem CalciumCouplingPolicy::getDateCalSchem () const { return _dateCalSchem; } void CalciumCouplingPolicy::setAlpha(double alpha) { +#ifdef _DEBUG_ + std::cerr << "CalciumCouplingPolicy::setAlpha: " << alpha << std::endl; +#endif if ( _dependencyType != CalciumTypes::TIME_DEPENDENCY ) throw CalciumException(CalciumTypes::CPITVR,LOC("Il est impossible de positionner alpha sur un port qui n'est pas en dépendance temporelle")); @@ -72,6 +81,9 @@ void CalciumCouplingPolicy::setDeltaT(double deltaT ) { double CalciumCouplingPolicy::getDeltaT() const {return _deltaT;} void CalciumCouplingPolicy::setInterpolationSchem (CalciumTypes::InterpolationSchem interpolationSchem) { +#ifdef _DEBUG_ + std::cerr << "CalciumCouplingPolicy::setInterpolationSchem: " << interpolationSchem << std::endl; +#endif if ( _dependencyType != CalciumTypes::TIME_DEPENDENCY ) throw CalciumException(CalciumTypes::CPITVR,LOC("Le paramètre InterpolationSchem sur un port qui n'est pas en dépendance temporelle n'a pas de sens")); _interpolationSchem=interpolationSchem; diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx index 1fe1c0e5b..4ae601ad7 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx @@ -244,6 +244,12 @@ struct CalciumCouplingPolicy::BoundedDataIdProcessor< Type dataOut = DataManipulator::create(dataSize); InnerType * const OutIt = DataManipulator::getPointer(dataOut); +#ifdef _DEBUG_ + std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : interpolationSchem : " << _couplingPolicy._interpolationSchem << std::endl; + std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : alpha : " << _couplingPolicy._alpha << std::endl; + std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : datecalschem : " << _couplingPolicy._dateCalSchem << std::endl; + std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : storageLevel : " << _couplingPolicy._storageLevel << std::endl; +#endif if ( timeDiff == 0.0 || _couplingPolicy._interpolationSchem == CalciumTypes::L0_SCHEM ) { std::copy(InIt1,InIt1+dataSize,OutIt); } else { diff --git a/src/DSC/DSC_User/Superv_Component_i.cxx b/src/DSC/DSC_User/Superv_Component_i.cxx index 3f2a3e972..4a6449990 100644 --- a/src/DSC/DSC_User/Superv_Component_i.cxx +++ b/src/DSC/DSC_User/Superv_Component_i.cxx @@ -50,6 +50,20 @@ Superv_Component_i::Superv_Component_i(CORBA::ORB_ptr orb, register_factory("PALM", new palm_port_factory()); register_factory("CALCIUM", new calcium_port_factory()); } +Superv_Component_i::Superv_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : Engines_DSC_i(orb, poa, container, instanceName, interfaceName) +{ +#ifdef _DEBUG_ + std::cerr << "--Superv_Component_i : MARK 1 ---- " << instanceName << "----" << std::endl; +#endif + register_factory("BASIC", new basic_port_factory()); + register_factory("PALM", new palm_port_factory()); + register_factory("CALCIUM", new calcium_port_factory()); +} Superv_Component_i::~Superv_Component_i() diff --git a/src/DSC/DSC_User/Superv_Component_i.hxx b/src/DSC/DSC_User/Superv_Component_i.hxx index 174380f05..2c8467e05 100644 --- a/src/DSC/DSC_User/Superv_Component_i.hxx +++ b/src/DSC/DSC_User/Superv_Component_i.hxx @@ -65,6 +65,12 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + Superv_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); virtual ~Superv_Component_i(); // Exceptions declarations. diff --git a/src/Launcher/BatchTest.cxx b/src/Launcher/BatchTest.cxx new file mode 100644 index 000000000..bb44166f4 --- /dev/null +++ b/src/Launcher/BatchTest.cxx @@ -0,0 +1,689 @@ +#include "BatchTest.hxx" + +BatchTest::BatchTest(const Engines::MachineParameters& batch_descr) +{ + _batch_descr = batch_descr; + + // Getting date + Batch::Date date = Batch::Date(time(0)); + _date = date.str(); + int lend = _date.size() ; + int i = 0 ; + while (i < lend) + { + if (_date[i] == '/' || _date[i] == '-' || _date[i] == ':' ) + { + _date[i] = '_' ; + } + i++ ; + } + + // Creating test temporary file + _test_filename = "/tmp/"; + _test_filename += _date + "_test_cluster_file_"; + _test_filename += _batch_descr.alias.in(); + _base_filename = _date + "_test_cluster_file_" + _batch_descr.alias.in(); +} + +BatchTest::~BatchTest() {} + +bool +BatchTest::test() +{ + bool rtn = false; + INFOS(std::endl + << "--- Testing batch Machine :" << std::endl + << "--- Name : " << _batch_descr.hostname << std::endl + << "--- Alias : " << _batch_descr.alias << std::endl + << "--- Protocol : " << _batch_descr.protocol << std::endl + << "--- User Name : " << _batch_descr.username << std::endl + << "--- Batch Type : " << _batch_descr.batch << std::endl + << "--- MPI Impl : " << _batch_descr.mpiImpl << std::endl + << "--- Appli Path : " << _batch_descr.applipath << std::endl + ); + + std::string result_connection("Not Tested"); + std::string result_filecopy("Not Tested"); + std::string result_getresult("Not Tested"); + std::string result_jobsubmit_simple("Not Tested"); + std::string result_jobsubmit_mpi("Not Tested"); + std::string result_appli("Not Tested"); + + result_connection = test_connection(); + result_filecopy = test_filecopy(); + result_getresult = test_getresult(); + result_jobsubmit_simple = test_jobsubmit_simple(); + result_jobsubmit_mpi = test_jobsubmit_mpi(); + result_appli = test_appli(); + + INFOS(std::endl + << "--- Test results" << std::endl + << "--- Connection : " << result_connection << std::endl + << "--- File copy : " << result_filecopy << std::endl + << "--- Get results : " << result_getresult << std::endl + << "--- Submit simple job : " << result_jobsubmit_simple << std::endl + << "--- Submit mpi job : " << result_jobsubmit_mpi << std::endl + << "--- Application : " << result_appli << std::endl + ); + + if (result_connection == "OK" and + result_filecopy == "OK" and + result_getresult == "OK" and + result_jobsubmit_simple == "OK" and + result_jobsubmit_mpi == "OK" and + result_appli == "OK") + rtn = true; + + return rtn; +} + +// For this test we use : alias, protocol, username +std::string +BatchTest::test_connection() +{ + int status; + std::string command; + std::string result("Failed : "); + std::string alias = _batch_descr.alias.in(); + std::string username = _batch_descr.username.in(); + std::string protocol = _batch_descr.protocol.in(); + + // Basic tests + if(alias == "") + { + result += "alias is empty !"; + return result; + } + if(username == "") + { + result += "username is empty !"; + return result; + } + if( protocol != "rsh" and protocol != "ssh") + { + result += "protocol unknown ! (" + protocol + ")"; + return result; + } + + // Build command + command += protocol + + " " + + username + "@" + alias; + + // Test + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error of connection on remote host ! status = "; + result += oss.str(); + return result; + } + + result = "OK"; + return result; +} + +// For this test we use : alias, protocol, username +std::string +BatchTest::test_filecopy() +{ + int status; + std::string home; + std::string command; + std::string result("Failed : "); + std::string alias = _batch_descr.alias.in(); + std::string username = _batch_descr.username.in(); + std::string protocol = _batch_descr.protocol.in(); + + // Getting home directory + std::string rst = get_home(&home); + if(rst != "") { + result += rst; + return result; + } + + // Writing into the tempory file + command = "echo Hello > " + _test_filename; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in creating tempory file ! status = "; + result += oss.str(); + return result; + } + + // Build command + command = "scp"; + if(protocol == "rsh") + command = "rcp"; + command += " " + _test_filename + " " + + username + "@" + alias + ":" + home; + + // Test + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in copy file on remote host ! status = "; + result += oss.str(); + return result; + } + + result = "OK"; + return result; +} + +// For this test we use : alias, protocol, username +std::string +BatchTest::test_getresult() +{ + int status; + std::string home; + std::string command; + std::string result("Failed : "); + std::string alias = _batch_descr.alias.in(); + std::string username = _batch_descr.username.in(); + std::string protocol = _batch_descr.protocol.in(); + + // Getting home directory + std::string rst = get_home(&home); + if(rst != "") { + result += rst; + return result; + } + + // Build command + command = "scp"; + if(protocol == "rsh") + command = "rcp"; + command += " " + username + "@" + alias + ":" + home + + "/" + _base_filename + " " + _test_filename + "_copy"; + + // Test + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in copy file from remote host ! status = "; + result += oss.str(); + return result; + } + + // Compare files + std::ifstream src_file(_test_filename.c_str()); + if (!src_file) + { + result += "Error in reading temporary file ! filename = " + _test_filename; + return result; + } + std::string cp_filename = _test_filename + "_copy"; + std::ifstream cp_file(cp_filename.c_str()); + if (!cp_file) + { + result += "Error in reading temporary copy file ! filename = " + cp_filename; + return result; + } + std::string src_firstline; + std::string cp_firstline; + std::getline(src_file, src_firstline); + std::getline(cp_file, cp_firstline); + src_file.close(); + cp_file.close(); + if (src_firstline != cp_firstline) + { + result += "Error source file and copy file are not equa ! source = " + src_firstline + " copy = " + cp_firstline; + return result; + } + + result = "OK"; + return result; +} + +std::string +BatchTest::test_jobsubmit_simple() +{ + int status; + std::string home; + std::string command; + std::string result("Failed : "); + std::string alias = _batch_descr.alias.in(); + std::string username = _batch_descr.username.in(); + std::string protocol = _batch_descr.protocol.in(); + std::string batch_type = _batch_descr.batch.in(); + + // Basic test + if (batch_type == "slurm") + { + INFOS("test_jobsubmit_simple not yet implemented for slurm... return OK"); + result = "OK"; + return result; + } + if (batch_type != "pbs") + { + result += "Batch type unknown ! : " + batch_type; + return result; + } + + // Getting home directory + std::string rst = get_home(&home); + if(rst != "") { + result += rst; + return result; + } + + // PBS test + std::string _test_file_simple = _test_filename + "_simple"; + std::ofstream file; + file.open(_test_file_simple.c_str(), std::ofstream::out); + file << "#!/bin/bash\n" + << "#PBS -l nodes=1\n" + << "#PBS -l walltime=00:01:00\n" + << "#PBS -o " + home + "/" + _date + "_simple_output.log\n" + << "#PBS -e " + home + "/" + _date + "_simple_error.log\n" + << "echo Bonjour\n" + << "echo Error >&2\n"; + file.flush(); + file.close(); + + + // Build command for copy + command = "scp"; + if(protocol == "rsh") + command = "rcp"; + command += " " + _test_file_simple + " " + + username + "@" + alias + ":" + home; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in copy job file to remote host ! status = "; + result += oss.str(); + return result; + } + + // Build command for submit job + std::string file_job_name = _test_filename + "_jobid"; + command = protocol + " " + username + "@" + alias + " qsub " + _base_filename + "_simple > " + file_job_name; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in sending qsub to remote host ! status = "; + result += oss.str(); + return result; + } + std::string jobid; + std::ifstream file_job(file_job_name.c_str()); + if (!file_job) + { + result += "Error in reading temporary file ! filename = " + file_job_name; + return result; + } + std::getline(file_job, jobid); + file_job.close(); + + // Wait the end of the job + command = protocol + " " + username + "@" + alias + " qstat -f " + jobid + " > " + file_job_name; + bool stop = false; + while (!stop) + { + status = system(command.c_str()); + if(status && status != 153 && status != 256*153) + { + std::ostringstream oss; + oss << status; + result += "Error in sending qstat to remote host ! status = "; + result += oss.str(); + return result; + } + + if(status == 153 || status == 256*153 ) + stop = true; + sleep(1); + } + + // Build command for getting results + command = "scp"; + if(protocol == "rsh") + command = "rcp"; + command += " " + + username + "@" + alias + ":" + home + "/" + _date + "_simple* /tmp"; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "error in getting file result of qsub simple to remote host ! status = "; + result += oss.str(); + return result; + } + + // Test results + std::string normal_input; + std::string file_normal_name = "/tmp/" + _date + "_simple_output.log"; + std::ifstream file_normal(file_normal_name.c_str()); + if (!file_normal) + { + result += "Error in reading temporary file ! filename = " + file_normal_name; + return result; + } + std::getline(file_normal, normal_input); + file_normal.close(); + if (normal_input != "Bonjour") + { + result += "error from simple ouput file ! waiting for Bonjour and get : " + normal_input; + return result; + } + std::string error_input; + std::string file_error_name = "/tmp/" + _date + "_simple_error.log"; + std::ifstream file_error(file_error_name.c_str()); + if (!file_error) + { + result += "Error in reading temporary file ! filename = " + file_error_name; + return result; + } + std::getline(file_error, error_input); + file_error.close(); + if (error_input != "Error") + { + result += "error from simple error file ! waiting for Error and get : " + error_input; + return result; + } + result = "OK"; + return result; +} + +std::string +BatchTest::test_jobsubmit_mpi() +{ + int status; + std::string home; + std::string command; + MpiImpl * mpiImpl; + std::string result("Failed : "); + std::string alias = _batch_descr.alias.in(); + std::string username = _batch_descr.username.in(); + std::string protocol = _batch_descr.protocol.in(); + std::string batch_type = _batch_descr.batch.in(); + std::string mpi_type = _batch_descr.mpiImpl.in(); + + // Basic test + if(mpi_type == "lam") + mpiImpl = new MpiImpl_LAM(); + else if(mpi_type == "mpich1") + mpiImpl = new MpiImpl_MPICH1(); + else if(mpi_type == "mpich2") + mpiImpl = new MpiImpl_MPICH2(); + else if(mpi_type == "openmpi") + mpiImpl = new MpiImpl_OPENMPI(); + else + { + result += "Error MPI impl not supported : " + mpi_type; + return result; + } + + // SLURM not yet implemented... + if (batch_type == "slurm") + { + INFOS("test_jobsubmit_simple not yet implemented for slurm... return OK"); + result = "OK"; + return result; + } + + // Getting home directory + std::string rst = get_home(&home); + if(rst != "") { + result += rst; + return result; + } + + // MPI test + std::string _test_file_script = _test_filename + "_script"; + std::ofstream file_script; + file_script.open(_test_file_script.c_str(), std::ofstream::out); + file_script << "#!/bin/bash\n" + << "echo HELLO MPI\n"; + file_script.flush(); + file_script.close(); + chmod(_test_file_script.c_str(), 0x1ED); + + std::string _test_file_mpi = _test_filename + "_mpi"; + std::ofstream file_mpi; + file_mpi.open(_test_file_mpi.c_str(), std::ofstream::out); + file_mpi << "#!/bin/bash\n" + << "#PBS -l nodes=1\n" + << "#PBS -l walltime=00:01:00\n" + << "#PBS -o " << home << "/" << _date << "_mpi_output.log\n" + << "#PBS -e " << home << "/" << _date << "_mpi_error.log\n" + << mpiImpl->boot("${PBS_NODEFILE}", 1) + << mpiImpl->run("${PBS_NODEFILE}", 1, _base_filename + "_script") + << mpiImpl->halt(); + file_mpi.flush(); + file_mpi.close(); + + + // Build command for copy + command = "scp"; + if(protocol == "rsh") + command = "rcp"; + command += " " + _test_file_script + " " + + username + "@" + alias + ":" + home; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in copy job file to remote host ! status = "; + result += oss.str(); + return result; + } + command = "scp"; + if(protocol == "rsh") + command = "rcp"; + command += " " + _test_file_mpi + " " + + username + "@" + alias + ":" + home; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in copy job file to remote host ! status = "; + result += oss.str(); + return result; + } + + // Build command for submit job + std::string file_job_name = _test_filename + "_jobid"; + command = protocol + " " + username + "@" + alias + " qsub " + _base_filename + "_mpi > " + file_job_name; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in sending qsub to remote host ! status = "; + result += oss.str(); + return result; + } + std::string jobid; + std::ifstream file_job(file_job_name.c_str()); + if (!file_job) + { + result += "Error in reading temporary file ! filename = " + file_job_name; + return result; + } + std::getline(file_job, jobid); + file_job.close(); + + // Wait the end of the job + command = protocol + " " + username + "@" + alias + " qstat -f " + jobid + " > " + file_job_name; + bool stop = false; + while (!stop) + { + status = system(command.c_str()); + if(status && status != 153 && status != 256*153) + { + std::ostringstream oss; + oss << status; + result += "Error in sending qstat to remote host ! status = "; + result += oss.str(); + return result; + } + + if(status == 153 || status == 256*153 ) + stop = true; + sleep(1); + } + + // Build command for getting results + command = "scp"; + if(protocol == "rsh") + command = "rcp"; + command += " " + + username + "@" + alias + ":" + home + "/" + _date + "_mpi* /tmp"; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "error in getting file result of qsub mpi from remote host ! status = "; + result += oss.str(); + return result; + } + + // Test results + std::string normal_input; + std::string file_normal_name = "/tmp/" + _date + "_mpi_output.log"; + std::ifstream file_normal(file_normal_name.c_str()); + if (!file_normal) + { + result += "Error in reading temporary file ! filename = " + file_normal_name; + return result; + } + bool test_ok = false; + while (std::getline(file_normal, normal_input)) + { + if (normal_input == "HELLO MPI") + test_ok = true; + } + file_normal.close(); + if (!test_ok) + { + result += "error from mpi ouput file ! waiting for HELLO MPI please watch /tmp/" + _date + "_mpi_output.log file"; + return result; + } + result = "OK"; + return result; +} + +std::string +BatchTest::test_appli() +{ + int status; + std::string home; + std::string command; + std::string result("Failed : "); + std::string alias = _batch_descr.alias.in(); + std::string username = _batch_descr.username.in(); + std::string protocol = _batch_descr.protocol.in(); + std::string applipath = _batch_descr.applipath.in(); + + // Getting home directory + std::string rst = get_home(&home); + if(rst != "") { + result += rst; + return result; + } + + std::string _test_file_appli = _test_filename + "_appli_test"; + std::ofstream file_appli; + file_appli.open(_test_file_appli.c_str(), std::ofstream::out); + file_appli << "#!/bin/bash\n" + << "if [ -f " << applipath << "/runAppli ]\n" + << "then\n" + << " echo OK\n" + << "else\n" + << " echo NOK\n" + << "fi\n"; + file_appli.flush(); + file_appli.close(); + + // Build command for copy + command = "scp"; + if(protocol == "rsh") + command = "rcp"; + command += " " + _test_file_appli + " " + + username + "@" + alias + ":" + home; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in copy appli test file to remote host ! status = "; + result += oss.str(); + return result; + } + + // Launch test + command = protocol + " " + username + "@" + alias + + " sh " + home + "/" + _base_filename + "_appli_test > " + + _test_filename + "_appli_test_result"; + + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in launching appli test on remote host ! status = "; + result += oss.str(); + return result; + } + + // Read test result + std::string rst_appli; + std::string file_appli_result_name = _test_filename + "_appli_test_result"; + std::ifstream file_appli_result(file_appli_result_name.c_str()); + if (!file_appli_result) + { + result += "Error in reading temporary file ! filename = " + file_appli_result_name; + return result; + } + std::getline(file_appli_result, rst_appli); + file_appli_result.close(); + + if (rst_appli != "OK") + { + result += "Error checking application on remote host ! result = " + rst; + return result; + } + + result = "OK"; + return result; +} + +// Useful methods +std::string +BatchTest::get_home(std::string * home) +{ + int status; + std::string result = ""; + std::string command; + std::string alias = _batch_descr.alias.in(); + std::string username = _batch_descr.username.in(); + std::string protocol = _batch_descr.protocol.in(); + std::string file_home_name = _test_filename + "_home"; + + command = protocol + " " + username + "@" + alias + " 'echo $HOME' > " + file_home_name; + status = system(command.c_str()); + if(status) { + std::ostringstream oss; + oss << status; + result += "Error in getting home directory ! status = "; + result += oss.str(); + return result; + } + + std::ifstream file_home(file_home_name.c_str()); + if (!file_home) + { + result += "Error in reading temporary file ! filename = " + file_home_name; + return result; + } + std::getline(file_home, *home); + file_home.close(); + return result; +} diff --git a/src/Launcher/BatchTest.hxx b/src/Launcher/BatchTest.hxx new file mode 100644 index 000000000..600b71bee --- /dev/null +++ b/src/Launcher/BatchTest.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __BatchTest_HXX__ +#define __BatchTest_HXX__ + +#include +#include +#include + +#include +#include "utilities.h" +#include CORBA_CLIENT_HEADER(SALOME_ContainerManager) + +#include "Batch_Date.hxx" +#include "MpiImpl.hxx" + +class BatchTest +{ + public: + BatchTest(const Engines::MachineParameters& batch_descr); + virtual ~BatchTest(); + + bool test(); + + std::string test_connection(); + std::string test_filecopy(); + std::string test_getresult(); + std::string test_jobsubmit_simple(); + std::string test_jobsubmit_mpi(); + std::string test_appli(); + + protected: + std::string get_home(std::string * home); + + private: + Engines::MachineParameters _batch_descr; + std::string _test_filename; + std::string _base_filename; + std::string _date; +}; + +#endif diff --git a/src/Launcher/Launcher.cxx b/src/Launcher/Launcher.cxx index 9fd6ed016..a206bf5f1 100644 --- a/src/Launcher/Launcher.cxx +++ b/src/Launcher/Launcher.cxx @@ -138,6 +138,7 @@ long Launcher_cpp::submitJob( const std::string xmlExecuteFile, param[TMPDIR] = remotedir; param[MAXWALLTIME] = getWallTime(""); param[MAXRAMSIZE] = getRamSize(""); + param[HOMEDIR] = ""; Batch::Environnement env; env["COMMAND"] = _launch.Command; @@ -222,16 +223,26 @@ long Launcher_cpp::submitSalomeJob( const string fileToExecute , param[INFILE] = Batch::Couple( fileToExecute, getRemoteFile(tmpdir,fileToExecute) ); for(int i=0;i 0 ){ - param[OUTFILE] = Batch::Couple( "", filesToImport[0] ); - for(int i=1;i _batchmap; std::map < std::pair , Batch::Job* > _jobmap; diff --git a/src/Launcher/Makefile.am b/src/Launcher/Makefile.am index 2bc48a529..79ee054da 100644 --- a/src/Launcher/Makefile.am +++ b/src/Launcher/Makefile.am @@ -38,6 +38,7 @@ include $(top_srcdir)/salome_adm/unix/make_common_starter.am salomeinclude_HEADERS = \ SALOME_Launcher_Parser.hxx \ SALOME_Launcher_Handler.hxx \ + BatchTest.hxx \ SALOME_Launcher.hxx \ Launcher.hxx @@ -99,6 +100,7 @@ else lib_LTLIBRARIES = libLauncher.la libSalomeLauncher.la endif libSalomeLauncher_la_SOURCES=\ + BatchTest.cxx \ SALOME_Launcher.cxx libSalomeLauncher_la_CPPFLAGS =\ diff --git a/src/Launcher/SALOME_Launcher.cxx b/src/Launcher/SALOME_Launcher.cxx index 67f770e95..530a13cf8 100644 --- a/src/Launcher/SALOME_Launcher.cxx +++ b/src/Launcher/SALOME_Launcher.cxx @@ -172,6 +172,41 @@ CORBA::Long SALOME_Launcher::submitSalomeJob( const char * fileToExecute , return jobId; } +//============================================================================= +/*! CORBA Method: + * the test batch configuration + * \param params : The batch cluster + */ +//============================================================================= +CORBA::Boolean +SALOME_Launcher::testBatch(const Engines::MachineParameters& params) +{ + MESSAGE("BEGIN OF SALOME_Launcher::testBatch"); + CORBA::Boolean rtn = false; + try + { + // find a cluster matching the structure params + Engines::CompoList aCompoList ; + Engines::MachineList *aMachineList = _ResManager->GetFittingResources(params, aCompoList); + if (aMachineList->length() == 0) + throw SALOME_Exception("No resources have been found with your parameters"); + + const Engines::MachineParameters* p = _ResManager->GetMachineParameters((*aMachineList)[0]); + string clustername(p->alias); + INFOS("Choose cluster" << clustername); + BatchTest t(*p); + if (t.test()) + { + rtn = true; + } + } + catch(const LauncherException &ex){ + INFOS(ex.msg.c_str()); + THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR); + } + return rtn; +} + //============================================================================= /*! CORBA Method: * Query a batch job on a cluster and returns the status of job diff --git a/src/Launcher/SALOME_Launcher.hxx b/src/Launcher/SALOME_Launcher.hxx index 33755495a..9097643de 100644 --- a/src/Launcher/SALOME_Launcher.hxx +++ b/src/Launcher/SALOME_Launcher.hxx @@ -23,6 +23,7 @@ #include #include CORBA_CLIENT_HEADER(SALOME_ContainerManager) #include "SALOME_ContainerManager.hxx" +#include "BatchTest.hxx" #include "Launcher.hxx" #include @@ -65,6 +66,8 @@ public: void deleteJob( const CORBA::Long jobId, const Engines::MachineParameters& params); void getResultsJob( const char * directory, const CORBA::Long jobId, const Engines::MachineParameters& params ); + CORBA::Boolean testBatch(const Engines::MachineParameters& params); + void Shutdown(); CORBA::Long getPID(); diff --git a/src/ModuleCatalog/SALOME_ModuleCatalog_Acomponent_impl.hxx b/src/ModuleCatalog/SALOME_ModuleCatalog_Acomponent_impl.hxx index e693d70f4..0c8661430 100644 --- a/src/ModuleCatalog/SALOME_ModuleCatalog_Acomponent_impl.hxx +++ b/src/ModuleCatalog/SALOME_ModuleCatalog_Acomponent_impl.hxx @@ -137,7 +137,7 @@ public: //! method to define if a component is implemented in a dyn lib a python module or an executable /*! - \return an enum SO or PY or EXE + \return an enum SO or PY or EXE or CEXE */ virtual SALOME_ModuleCatalog::ImplType implementation_type(); diff --git a/src/ModuleCatalog/SALOME_ModuleCatalog_Handler.cxx b/src/ModuleCatalog/SALOME_ModuleCatalog_Handler.cxx index 5fd1ff4e4..88fd5e7bc 100644 --- a/src/ModuleCatalog/SALOME_ModuleCatalog_Handler.cxx +++ b/src/ModuleCatalog/SALOME_ModuleCatalog_Handler.cxx @@ -413,6 +413,8 @@ void SALOME_ModuleCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc) _aModule.constraint = ""; _aModule.icon=""; _aModule.interfaces.resize(0); + _aModule.implementationType =""; + _aModule.implementationName =""; xmlNodePtr aComponentSubNode = aComponentNode->xmlChildrenNode; while(aComponentSubNode != NULL) diff --git a/src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx b/src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx index c63e0cdea..87c1f80a9 100644 --- a/src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx +++ b/src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx @@ -747,6 +747,8 @@ void SALOME_ModuleCatalogImpl::duplicate C_corba.type = ComponentTypeConvert[C_parser.type]; if(C_parser.implementationType == "EXE") C_corba.implementationType=SALOME_ModuleCatalog::EXE; + else if(C_parser.implementationType == "CEXE") + C_corba.implementationType=SALOME_ModuleCatalog::CEXE; else if(C_parser.implementationType == "PY") C_corba.implementationType=SALOME_ModuleCatalog::PY; else diff --git a/src/NOTIFICATION_SWIG/Makefile.am b/src/NOTIFICATION_SWIG/Makefile.am index e043680f4..d171e39a5 100644 --- a/src/NOTIFICATION_SWIG/Makefile.am +++ b/src/NOTIFICATION_SWIG/Makefile.am @@ -56,8 +56,6 @@ _libNOTIFICATION_la_CPPFLAGS =\ _libNOTIFICATION_la_LDFLAGS = -module _libNOTIFICATION_la_LIBADD = ../Notification/libSalomeNotification.la -# @PYTHON_LIBS@ - swig_wrap.cpp : $(SWIG_SOURCES) $(SWIG) $(SWIG_FLAGS) -o $@ $< diff --git a/src/ResourcesManager/ResourcesManager.cxx b/src/ResourcesManager/ResourcesManager.cxx index ef28d7597..24338dc78 100644 --- a/src/ResourcesManager/ResourcesManager.cxx +++ b/src/ResourcesManager/ResourcesManager.cxx @@ -137,6 +137,12 @@ ResourcesManager_cpp::GetFittingResources(const machineParams& params, vec.push_back(hostname); } + else if (_resourcesBatchList.find(hostname) != _resourcesBatchList.end()) + { + // --- params.hostname is in the list of resources so return it. + vec.push_back(hostname); + } + else { // Cas d'un cluster: nombre de noeuds > 1 @@ -277,7 +283,7 @@ void ResourcesManager_cpp::WriteInXmlFile() xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog"); SALOME_ResourcesCatalog_Handler* handler = - new SALOME_ResourcesCatalog_Handler(_resourcesList); + new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList); handler->PrepareDocToXmlFile(aDoc); delete handler; @@ -303,7 +309,7 @@ void ResourcesManager_cpp::WriteInXmlFile() const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile() { SALOME_ResourcesCatalog_Handler* handler = - new SALOME_ResourcesCatalog_Handler(_resourcesList); + new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList); const char* aFilePath = _path_resources.c_str(); FILE* aFile = fopen(aFilePath, "r"); @@ -437,7 +443,10 @@ throw(ResourcesException) ParserResourcesType ResourcesManager_cpp::GetResourcesList(const std::string& machine) { - return _resourcesList[machine]; + if (_resourcesList.find(machine) != _resourcesList.end()) + return _resourcesList[machine]; + else + return _resourcesBatchList[machine]; } std::string ResourcesManager_cpp::GetHostname() diff --git a/src/ResourcesManager/ResourcesManager.hxx b/src/ResourcesManager/ResourcesManager.hxx index d1f47e3b3..6fdd211ff 100644 --- a/src/ResourcesManager/ResourcesManager.hxx +++ b/src/ResourcesManager/ResourcesManager.hxx @@ -102,6 +102,9 @@ class ResourcesManager_cpp //! will contain the informations on the data type catalog(after parsing) MapOfParserResourcesType _resourcesList; + //! will contain the informations on the data type catalog(after parsing) + MapOfParserResourcesType _resourcesBatchList; + SALOME_LoadRateManager _dynamicResourcesSelecter; //! different behaviour if $APPLI exists (SALOME Application) diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx index c7a2cd171..75fa7672b 100755 --- a/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx @@ -46,8 +46,10 @@ static int MYDEBUG = 0; //============================================================================= SALOME_ResourcesCatalog_Handler:: -SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& listOfResources): - _resources_list(listOfResources) +SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& resources_list, + MapOfParserResourcesType& resources_batch_list): + _resources_list(resources_list), + _resources_batch_list(resources_batch_list) { //XML tags initialisation test_machine = "machine"; @@ -121,6 +123,7 @@ void SALOME_ResourcesCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc) { xmlChar* hostname = xmlGetProp(aCurNode, (const xmlChar*)test_hostname); _resource.DataForSort._hostName = (const char*)hostname; + _resource.HostName = (const char*)hostname; xmlFree(hostname); } else @@ -274,23 +277,32 @@ void SALOME_ResourcesCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc) } aCurSubNode = aCurSubNode->next; } - - int aNbNodes = _resource.DataForSort._nbOfNodes; - if( aNbNodes > 1 ){ - string clusterNode = _resource.DataForSort._hostName ; - for( int i=0; i < aNbNodes; i++ ){ - char inode[64]; - inode[0] = '\0' ; - sprintf(inode,"%s%d",clusterNode.c_str(),i+1); - std::string nodeName(inode); - _resource.DataForSort._hostName = nodeName ; - _resources_list[nodeName] = _resource; + + // There is two lists + // _resources_list for interactive resources + // _resources_batch_list for batch resources + // This choice is done with Mode parameter + if (_resource.Mode == interactive) + { + int aNbNodes = _resource.DataForSort._nbOfNodes; + if( aNbNodes > 1 ){ + string clusterNode = _resource.DataForSort._hostName ; + for( int i=0; i < aNbNodes; i++ ){ + char inode[64]; + inode[0] = '\0' ; + sprintf(inode,"%s%d",clusterNode.c_str(),i+1); + std::string nodeName(inode); + _resource.DataForSort._hostName = nodeName ; + _resource.HostName = nodeName ; + _resources_list[nodeName] = _resource; + } } + else + _resources_list[_resource.HostName] = _resource; } else - _resources_list[_resource.DataForSort._hostName] = _resource; + _resources_batch_list[_resource.HostName] = _resource; } - aCurNode = aCurNode->next; } @@ -337,7 +349,90 @@ void SALOME_ResourcesCatalog_Handler::PrepareDocToXmlFile(xmlDocPtr theDoc) iter++) { node = xmlNewChild(root_node, NULL, BAD_CAST test_machine, NULL); - xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).first.c_str()); + xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).second.HostName.c_str()); + xmlNewProp(node, BAD_CAST test_alias, BAD_CAST (*iter).second.Alias.c_str()); + + switch ((*iter).second.Protocol) + { + case rsh: + xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh"); + break; + case ssh: + xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "ssh"); + break; + default: + xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh"); + } + + switch ((*iter).second.Mode) + { + case interactive: + xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive"); + break; + case batch: + xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "batch"); + break; + default: + xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive"); + } + + switch ((*iter).second.Batch) + { + case pbs: + xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "pbs"); + break; + case lsf: + xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "lsf"); + break; + case slurm: + xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "slurm"); + break; + default: + xmlNewProp(node, BAD_CAST test_batch, BAD_CAST ""); + } + + switch ((*iter).second.mpi) + { + case lam: + xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "lam"); + break; + case mpich1: + xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich1"); + break; + case mpich2: + xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich2"); + break; + case openmpi: + xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "openmpi"); + break; + default: + xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST ""); + } + + xmlNewProp(node, BAD_CAST test_user_name, BAD_CAST (*iter).second.UserName.c_str()); + + for (vector::const_iterator iter2 = + (*iter).second.ModulesList.begin(); + iter2 != (*iter).second.ModulesList.end(); + iter2++) + { + node1 = xmlNewChild(node, NULL, BAD_CAST test_modules, NULL); + xmlNewProp(node1, BAD_CAST test_module_name, BAD_CAST (*iter2).c_str()); + } + + xmlNewProp(node, BAD_CAST test_os, BAD_CAST (*iter).second.OS.c_str()); + xmlNewProp(node, BAD_CAST test_mem_in_mb, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._memInMB)); + xmlNewProp(node, BAD_CAST test_cpu_freq_mhz, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._CPUFreqMHz)); + xmlNewProp(node, BAD_CAST test_nb_of_nodes, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfNodes)); + xmlNewProp(node, BAD_CAST test_nb_of_proc_per_node, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfProcPerNode)); + } + for (map::iterator iter = + _resources_batch_list.begin(); + iter != _resources_batch_list.end(); + iter++) + { + node = xmlNewChild(root_node, NULL, BAD_CAST test_machine, NULL); + xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).second.HostName.c_str()); xmlNewProp(node, BAD_CAST test_alias, BAD_CAST (*iter).second.Alias.c_str()); switch ((*iter).second.Protocol) diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.hxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.hxx index d636ff22f..9422c7bd1 100755 --- a/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.hxx +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.hxx @@ -40,7 +40,8 @@ class SALOME_ResourcesCatalog_Handler { public : - SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& listOfResources); + SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& resources_list, + MapOfParserResourcesType& resources_batch_list); const MapOfParserResourcesType& GetResourcesAfterParsing() const; @@ -55,6 +56,7 @@ class SALOME_ResourcesCatalog_Handler ParserResourcesType _resource; MapOfParserResourcesType& _resources_list; + MapOfParserResourcesType& _resources_batch_list; const char *test_machine; const char *test_resources; diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.cxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.cxx index 18765ff29..1ebc6cb41 100644 --- a/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.cxx +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.cxx @@ -116,7 +116,7 @@ void ParserResourcesType::Print() const { ostringstream oss; oss << endl << - "HostName : " << DataForSort._hostName << endl << + "HostName : " << HostName << endl << "Alias : " << Alias << endl << "NbOfNodes : " << DataForSort._nbOfNodes << endl << "NbOfProcPerNode : " << DataForSort._nbOfProcPerNode << endl << @@ -145,6 +145,7 @@ void ParserResourcesType::Clear() DataForSort._nbOfProcPerNode = 1; DataForSort._CPUFreqMHz = 0; DataForSort._memInMB = 0; + HostName = ""; Alias = ""; Protocol = rsh; Mode = interactive; diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx index f452b1a6c..901def13c 100755 --- a/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx @@ -73,6 +73,7 @@ class ResourceDataToSort struct ParserResourcesType { ResourceDataToSort DataForSort; + std::string HostName; std::string Alias; AccessProtocolType Protocol; AccessModeType Mode; diff --git a/src/ResourcesManager/SALOME_ResourcesManager.cxx b/src/ResourcesManager/SALOME_ResourcesManager.cxx index 49bf36a8f..90f273d69 100644 --- a/src/ResourcesManager/SALOME_ResourcesManager.cxx +++ b/src/ResourcesManager/SALOME_ResourcesManager.cxx @@ -157,7 +157,6 @@ SALOME_ResourcesManager::GetFittingResources(const Engines::MachineParameters& p cl.push_back(string(componentList[i])); Engines::MachineList *ret=new Engines::MachineList; - try{ vector vec = _rm.GetFittingResources(p,cl); ret->length(vec.size()); @@ -193,7 +192,7 @@ Engines::MachineParameters* SALOME_ResourcesManager::GetMachineParameters(const ParserResourcesType resource = _rm.GetResourcesList(string(hostname)); Engines::MachineParameters *p_ptr = new Engines::MachineParameters; p_ptr->container_name = CORBA::string_dup(""); - p_ptr->hostname = CORBA::string_dup("hostname"); + p_ptr->hostname = CORBA::string_dup(resource.HostName.c_str()); p_ptr->alias = CORBA::string_dup(resource.Alias.c_str()); if( resource.Protocol == rsh ) p_ptr->protocol = "rsh"; @@ -219,12 +218,13 @@ Engines::MachineParameters* SALOME_ResourcesManager::GetMachineParameters(const p_ptr->mpiImpl = "mpich2"; else if( resource.mpi == openmpi ) p_ptr->mpiImpl = "openmpi"; + else if( resource.mpi == slurm ) + p_ptr->mpiImpl = "slurm"; if( resource.Batch == pbs ) p_ptr->batch = "pbs"; else if( resource.Batch == lsf ) p_ptr->batch = "lsf"; - else if( resource.Batch == slurm ) - p_ptr->batch = "slurm"; + return p_ptr; } diff --git a/src/ResourcesManager/SALOME_ResourcesManager.hxx b/src/ResourcesManager/SALOME_ResourcesManager.hxx index 4a00444cf..f2fdc259b 100644 --- a/src/ResourcesManager/SALOME_ResourcesManager.hxx +++ b/src/ResourcesManager/SALOME_ResourcesManager.hxx @@ -84,6 +84,10 @@ class RESOURCESMANAGER_EXPORT SALOME_ResourcesManager: CORBA::ORB_var _orb; PortableServer::POA_var _poa; + // + //! will contain the informations on the data type catalog(after parsing) + MapOfParserResourcesType _resourcesBatchList; + ResourcesManager_cpp _rm; }; -- 2.39.2