From: prascle Date: Fri, 21 Jan 2005 14:05:47 +0000 (+0000) Subject: PR: merge from tag mergeto_trunk_20Jan05 X-Git-Tag: V2_2_0a2~7 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ab41913b136c189f3aab5e4ce3f3da7f62395f23;p=modules%2Fkernel.git PR: merge from tag mergeto_trunk_20Jan05 --- diff --git a/Makefile.in b/Makefile.in index 426130bbd..ab8870626 100644 --- a/Makefile.in +++ b/Makefile.in @@ -21,6 +21,7 @@ back.xpm \ cascade.png \ CatalogDataType.xml \ KERNELCatalog.xml \ +CatalogResources.xml \ CatalogRessources.xml \ close.png \ config \ diff --git a/bin/runSalome.py b/bin/runSalome.py index d7ba78d8d..5fb5c006d 100755 --- a/bin/runSalome.py +++ b/bin/runSalome.py @@ -252,7 +252,6 @@ class Server: pid = os.spawnvp(os.P_NOWAIT, command[0], command) process_id[pid]=self.CMD -# --- class CatalogServer(Server): def __init__(self,args): @@ -449,6 +448,8 @@ def startSalome(args, modules_list, modules_root_dir): # Notify Server launch # + print "Notify Server to launch" + myServer=NotifyServer(args,modules_root_dir) myServer.run() @@ -466,6 +467,7 @@ def startSalome(args, modules_list, modules_root_dir): # Lancement Catalog Server, # attente de la disponibilité du Catalog Server dans le Naming Service # + if 'moduleCatalog' not in args['embedded']: cataServer=CatalogServer(args) @@ -527,7 +529,7 @@ def startSalome(args, modules_list, modules_root_dir): os.environ["HOSTNAME"]=os.getenv("HOST") theComputer = getShortHostName() - + # # Lancement Container C++ local, # attente de la disponibilité du Container C++ local dans le Naming Service diff --git a/doc/salome/tui/Makefile.in b/doc/salome/tui/Makefile.in index 3f4811e43..eeaff820d 100644 --- a/doc/salome/tui/Makefile.in +++ b/doc/salome/tui/Makefile.in @@ -23,6 +23,7 @@ docs: mv -f doxyfile1 doxyfile; \ $(doxygen) ./doxyfile; \ cd ..; \ + mkdir KERNEL; \ cp -fr $(srcdir)/KERNEL/sources/static/*.* ./KERNEL/ cp -fr $(srcdir)/KERNEL/sources/ KERNEL/ cp -fr $(srcdir)/KERNEL/HTML/ KERNEL/ diff --git a/idl/Makefile.in b/idl/Makefile.in index 6e46e61bd..40542236a 100644 --- a/idl/Makefile.in +++ b/idl/Makefile.in @@ -20,6 +20,7 @@ IDL_FILES = \ SALOMEDS_Attributes.idl \ SALOME_Session.idl \ SALOME_Component.idl \ + SALOME_ContainerManager.idl \ SALOME_TestComponent.idl \ SALOME_Registry.idl \ SALOME_MPIObject.idl \ diff --git a/idl/SALOME_Component.idl b/idl/SALOME_Component.idl index ecad1fa41..8760ae9df 100644 --- a/idl/SALOME_Component.idl +++ b/idl/SALOME_Component.idl @@ -52,12 +52,6 @@ module Engines */ interface Container { -/*! - Initializes the %container with a definite name. - \param ContainerName Name of the container - \return an initialized container -*/ - Container start_impl( in string ContainerName ) ; /*! Loads into the container a new component, registers it and starts it's CORBA servant. @@ -94,6 +88,10 @@ module Engines Returns True if the %container has been killed */ boolean Kill_impl() ; +/*! + Shutdown the Container process. +*/ + oneway void Shutdown(); /*! Returns the hostname of the container */ diff --git a/idl/SALOME_ContainerManager.idl b/idl/SALOME_ContainerManager.idl new file mode 100644 index 000000000..d8a57247e --- /dev/null +++ b/idl/SALOME_ContainerManager.idl @@ -0,0 +1,40 @@ +#ifndef _SALOME_CONTAINERMANAGER_IDL_ +#define _SALOME_CONTAINERMANAGER_IDL_ + +#include "SALOME_Component.idl" + +module Engines +{ + +/*! + Type to describe properties of wanted resource. +*/ +struct MachineParameters { + string container_name; + string hostname; + string OS; + long mem_mb; + long cpu_clock; + long nb_proc_per_node; + long nb_node; +}; + +/*! + Type to transmit list of machines. +*/ + typedef sequence MachineList; + +/*! \brief Interface of the %containerManager + This interface is used for interaction with the unique instance of ContainerManager +*/ + interface ContainerManager + { + Container FindOrStartContainer( in string containerName, in MachineList possibleComputers); + string FindBest(in MachineList possibleComputers); + MachineList GetFittingResources( in MachineParameters params, in string componentName ); + void Shutdown(); + void ShutdownContainers(); + } ; +}; + +#endif diff --git a/resources/CatalogResources.xml b/resources/CatalogResources.xml new file mode 100644 index 000000000..99939a378 --- /dev/null +++ b/resources/CatalogResources.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/Container/Component_i.cxx b/src/Container/Component_i.cxx index 880bb0438..ff343a2cc 100644 --- a/src/Container/Component_i.cxx +++ b/src/Container/Component_i.cxx @@ -27,6 +27,7 @@ // $Header$ #include "SALOME_Component_i.hxx" +#include "SALOME_Container_i.hxx" #include "RegistryConnexion.hxx" #include "OpUtil.hxx" #include @@ -397,3 +398,20 @@ CORBA::Long Engines_Component_i::CpuUsed_impl() { void Engines_Component_i::sendMessage(const char *event_type, const char *message) { _notifSupplier->Send(graphName(), nodeName(), event_type, message); } + +string Engines_Component_i::GetDynLibraryName(const char *componentName) +{ + string ret="lib"; + ret+=componentName; + ret+="Engine.so"; + return ret; +} + +string Engines_Component_i::BuildComponentNameForNS(const char *ComponentName, const char *ContainerName, const char *hostname) +{ + string ret=Engines_Container_i::BuildContainerNameForNS(ContainerName,hostname); + ret+="/"; + ret+=ComponentName; + return ret; +} + diff --git a/src/Container/Container_i.cxx b/src/Container/Container_i.cxx index e36089f5e..301b56719 100644 --- a/src/Container/Container_i.cxx +++ b/src/Container/Container_i.cxx @@ -30,8 +30,9 @@ #include CORBA_SERVER_HEADER(SALOME_Component) #include "SALOME_Container_i.hxx" #include "SALOME_NamingService.hxx" -#include "Utils_SINGLETON.hxx" +//#include "Utils_SINGLETON.hxx" #include "OpUtil.hxx" +#include #include #include #include @@ -52,6 +53,8 @@ char ** _ArgV ; extern "C" {void ActSigIntHandler() ; } extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; } +const char *Engines_Container_i::_defaultContainerName="FactoryServer"; + Engines_Container_i::Engines_Container_i () : _numInstance(0) { @@ -61,13 +64,12 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, char *containerName , int argc , char* argv[], - bool regist, - bool activ ) : + bool activAndRegist ) : _numInstance(0) { _pid = (long)getpid(); - if(regist) + if(activAndRegist) ActSigIntHandler() ; _ArgC = argc ; @@ -98,35 +100,20 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb, SCRUTE(hostname); - _containerName = "/Containers/"; - if (strlen(containerName)== 0) - { - _containerName += hostname; - } - else - { - _containerName += hostname; - _containerName += "/" ; - _containerName += containerName; - } + _containerName = BuildContainerNameForNS(containerName,hostname.c_str()); _orb = CORBA::ORB::_duplicate(orb) ; _poa = PortableServer::POA::_duplicate(poa) ; - // Pour les containers paralleles: il ne faut pas activer le container generique, mais le container specialise - if(activ){ - MESSAGE("activate object"); - _id = _poa->activate_object(this); - } - - // Pour les containers paralleles: il ne faut pas enregistrer le container generique, mais le container specialise - if(regist){ - // _NS = new SALOME_NamingService(_orb); - _NS = SINGLETON_::Instance() ; - ASSERT(SINGLETON_::IsAlreadyExisting()) ; - _NS->init_orb( orb ) ; - Engines::Container_ptr pCont - = Engines::Container::_narrow(_this()); + // Pour les containers paralleles: il ne faut pas enregistrer et activer le container generique, mais le container specialise + if(activAndRegist){ + _id = _poa->activate_object(this); + _NS = new SALOME_NamingService();//SINGLETON_::Instance() ; + //ASSERT(SINGLETON_::IsAlreadyExisting()) ; + _NS->init_orb( CORBA::ORB::_duplicate(_orb) ) ; + CORBA::Object_var obj=_poa->id_to_reference(*_id); + Engines::Container_var pCont + = Engines::Container::_narrow(obj); SCRUTE(_containerName); _NS->Register(pCont, _containerName.c_str()); } @@ -135,6 +122,7 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb, Engines_Container_i::~Engines_Container_i() { MESSAGE("Container_i::~Container_i()"); + delete _id; } char* Engines_Container_i::name() @@ -154,6 +142,16 @@ void Engines_Container_i::ping() MESSAGE("Engines_Container_i::ping() pid "<< getpid()); } +// shutdown corba server +void Engines_Container_i::Shutdown() +{ + MESSAGE("Engines_Container_i::Shutdown()"); + _NS->Destroy_Name(_containerName.c_str()); + //_remove_ref(); + //_poa->deactivate_object(*_id); + _orb->shutdown(0); +} + //! Kill current container bool Engines_Container_i::Kill_impl() { MESSAGE("Engines_Container_i::Kill() pid "<< getpid() << " containerName " @@ -162,147 +160,6 @@ bool Engines_Container_i::Kill_impl() { exit( 0 ) ; } -//! Launch a new container from the current container -Engines::Container_ptr Engines_Container_i::start_impl( - const char* ContainerName ) { - MESSAGE("start_impl argc " << _argc << " ContainerName " << ContainerName - << hex << this << dec) ; - _numInstanceMutex.lock() ; // lock on the instance number - - CORBA::Object_var obj = Engines::Container::_nil() ; - bool nilvar = true ; - try { - string cont("/Containers/"); - cont += machineName() ; - cont += "/" ; - cont += ContainerName; - INFOS(machineName() << " start_impl unknown container " << cont.c_str() - << " try to Resolve" ); - obj = _NS->Resolve( cont.c_str() ); - nilvar = CORBA::is_nil( obj ) ; - if ( nilvar ) { - INFOS(machineName() << " start_impl unknown container " - << ContainerName); - } - } - catch (ServiceUnreachable&) { - INFOS(machineName() << "Caught exception: Naming Service Unreachable"); - } - catch (...) { - INFOS(machineName() << "Caught unknown exception."); - } - if ( !nilvar ) { - _numInstanceMutex.unlock() ; - MESSAGE("start_impl container found without new launch") ; - return Engines::Container::_narrow(obj); - } - int i = 0 ; - while ( _argv[ i ] ) { - MESSAGE(" argv" << i << " " << _argv[ i ]) ; - i++ ; - } - string shstr = string(getenv("KERNEL_ROOT_DIR")) + "/bin/salome/SALOME_Container "; -// string shstr( "./runSession SALOME_Container " ) ; - shstr += ContainerName ; - if ( _argc == 4 ) { - shstr += " " ; - shstr += _argv[ 2 ] ; - shstr += " " ; - shstr += _argv[ 3 ] ; - } - - // asv : 16.11.04 : creation of log file in /tmp/logs/$USER dir. - // "/tmp/logs/$USER" was created by runSalome.py -> orbmodule.py. - string tempfilename = "/tmp/logs/"; - tempfilename += getenv( "USER" ) ; - tempfilename += "/" ; - tempfilename += ContainerName ; - tempfilename += ".log" ; - FILE* f = fopen ( tempfilename.c_str(), "a" ); - if ( f ) { // check if file can be opened for writing - fclose( f ); - shstr += " > " ; - shstr += tempfilename; - shstr += " 2>&1 &" ; - } - else { // if file can't be opened - use a guaranteed temp file name - char* tmpFileName = tempnam( NULL, ContainerName ); - shstr += " > "; - shstr += tmpFileName; - shstr += " 2>&1 &"; - free( tmpFileName ); - } - - MESSAGE("system(" << shstr << ")") ; - int status = system( shstr.c_str() ) ; - if (status == -1) { - INFOS("Engines_Container_i::start_impl SALOME_Container failed (system command status -1)") ; - } - else if (status == 217) { - INFOS("Engines_Container_i::start_impl SALOME_Container failed (system command status 217)") ; - } - INFOS(machineName() << " Engines_Container_i::start_impl SALOME_Container launch done"); - -// pid_t pid = fork() ; -// if ( pid == 0 ) { -// string anExe( _argv[ 0 ] ) ; -// anExe += "runSession" ; -// char * args[ 6 ] ; -// args[ 0 ] = "runSession" ; -// args[ 1 ] = "SALOME_Container" ; -// args[ 2 ] = strdup( ContainerName ) ; -// args[ 3 ] = strdup( _argv[ 2 ] ) ; -// args[ 4 ] = strdup( _argv[ 3 ] ) ; -// args[ 5 ] = NULL ; -// MESSAGE("execl(" << anExe.c_str() << " , " << args[ 0 ] << " , " -// << args[ 1 ] << " , " << args[ 2 ] << " , " << args[ 3 ] -// << " , " << args[ 4 ] << ")") ; -// int status = execv( anExe.c_str() , args ) ; -// if (status == -1) { -// INFOS("Engines_Container_i::start_impl execl failed (system command status -1)") ; -// perror( "Engines_Container_i::start_impl execl error ") ; -// } -// else { -// INFOS(machineName() << " Engines_Container_i::start_impl execl done"); -// } -// exit(0) ; -// } - - obj = Engines::Container::_nil() ; - try { - string cont("/Containers/"); - cont += machineName() ; - cont += "/" ; - cont += ContainerName; - nilvar = true ; - int count = 20 ; - while ( nilvar && count >= 0) { - sleep( 1 ) ; - obj = _NS->Resolve(cont.c_str()); - nilvar = CORBA::is_nil( obj ) ; - if ( nilvar ) { - INFOS(count << ". " << machineName() - << " start_impl unknown container " << cont.c_str()); - count -= 1 ; - } - } - _numInstanceMutex.unlock() ; - if ( !nilvar ) { - MESSAGE("start_impl container found after new launch of SALOME_Container") ; - } - return Engines::Container::_narrow(obj); - } - catch (ServiceUnreachable&) { - INFOS(machineName() << "Caught exception: Naming Service Unreachable"); - } - catch (...) { - INFOS(machineName() << "Caught unknown exception."); - } - _numInstanceMutex.unlock() ; - MESSAGE("start_impl container not found after new launch of SALOME_Container") ; - return Engines::Container::_nil() ; -} - Engines::Component_ptr Engines_Container_i::load_impl( const char* nameToRegister, const char* componentName ) { @@ -477,3 +334,27 @@ long Engines_Container_i::getPID() { char* Engines_Container_i::getHostName() { return((char*)(GetHostname().c_str())); } + +// Retrieves only with container naming convention if it is a python container +bool Engines_Container_i::isPythonContainer(const char* ContainerName) +{ + bool ret=false; + int len=strlen(ContainerName); + if(len>=2) + if(strcmp(ContainerName+len-2,"Py")==0) + ret=true; + return ret; +} + +string Engines_Container_i::BuildContainerNameForNS(const char *ContainerName, const char *hostname) +{ + string ret="/Containers/"; + ret += hostname; + ret+="/"; + if (strlen(ContainerName)== 0) + ret+=_defaultContainerName; + else + ret += ContainerName; + return ret; +} + diff --git a/src/Container/Makefile.in b/src/Container/Makefile.in index 5cd3980a5..cc74c34b5 100644 --- a/src/Container/Makefile.in +++ b/src/Container/Makefile.in @@ -38,24 +38,26 @@ EXPORT_PYSCRIPTS = SALOME_ComponentPy.py SALOME_ContainerPy.py EXPORT_HEADERS = \ SALOME_Component_i.hxx \ - SALOME_Container_i.hxx + SALOME_Container_i.hxx \ + SALOME_ContainerManager.hxx # Libraries targets LIB = libSalomeContainer.la -LIB_SRC = Component_i.cxx Container_i.cxx -LIB_SERVER_IDL = SALOME_Registry.idl SALOME_Component.idl +LIB_SRC = Component_i.cxx Container_i.cxx SALOME_ContainerManager.cxx +LIB_SERVER_IDL = SALOME_Registry.idl SALOME_Component.idl SALOME_ContainerManager.idl +LIB_CLIENT_IDL = # Executables targets BIN = SALOME_Container BIN_SRC = SALOME_Container_SignalsHandler.cxx -BIN_SERVER_IDL = SALOME_Component.idl +BIN_SERVER_IDL = SALOME_Component.idl SALOME_ContainerManager.idl -CPPFLAGS+= $(PYTHON_INCLUDES) $(MPI_INCLUDE) $(OCC_INCLUDES) +CPPFLAGS+= $(PYTHON_INCLUDES) $(MPI_INCLUDE) $(OCC_INCLUDES) $(QT_MT_INCLUDES) CXXFLAGS+=$(OCC_CXXFLAGS) -LDFLAGS+= -lSalomeNS -lRegistry -lOpUtil -lSalomeNotification -lSALOMELocalTrace -lSALOMETraceCollector +LDFLAGS+= $(QT_MT_LIBS) -lSalomeNS -lRegistry -lOpUtil -lSalomeNotification -lSALOMELocalTrace -lSALOMETraceCollector -lSalomeResourcesManager -LIBS += @LDEXPDYNFLAGS@ $(PYTHON_LIBS) $(MPI_LIBS) -lCASCatch +LIBS += @LDEXPDYNFLAGS@ $(PYTHON_LIBS) $(MPI_LIBS) @CONCLUDE@ diff --git a/src/Container/SALOME_Component_i.hxx b/src/Container/SALOME_Component_i.hxx index 2911434da..620ca1499 100644 --- a/src/Container/SALOME_Component_i.hxx +++ b/src/Container/SALOME_Component_i.hxx @@ -92,6 +92,8 @@ public: long CpuUsed() ; CORBA::Long CpuUsed_impl() ; + static std::string GetDynLibraryName(const char *componentName); + static std::string BuildComponentNameForNS(const char *ComponentName, const char *ContainerName, const char *hostname); protected: std::string _instanceName ; std::string _interfaceName ; diff --git a/src/Container/SALOME_Container.cxx b/src/Container/SALOME_Container.cxx index 646480535..77904cbe0 100644 --- a/src/Container/SALOME_Container.cxx +++ b/src/Container/SALOME_Container.cxx @@ -30,8 +30,9 @@ #include #include -#include "Utils_ORB_INIT.hxx" -#include "Utils_SINGLETON.hxx" +//#include "Utils_ORB_INIT.hxx" +//#include "Utils_SINGLETON.hxx" +#include #include "SALOME_NamingService.hxx" #include "SALOME_Container_i.hxx" #include "utilities.h" @@ -59,8 +60,8 @@ int main(int argc, char* argv[]) MPI_Init(&argc,&argv); #endif // Initialise the ORB. - ORB_INIT &init = *SINGLETON_::Instance() ; - CORBA::ORB_var &orb = init( argc , argv ) ; + //ORB_INIT &init = *SINGLETON_::Instance() ; + CORBA::ORB_var orb = CORBA::ORB_init( argc , argv ) ; SALOMETraceCollector *myThreadTrace = SALOMETraceCollector::instance(orb); INFOS_COMPILATION; BEGIN_OF(argv[0]); @@ -87,7 +88,7 @@ int main(int argc, char* argv[]) CORBA::Object_var theObj; CORBA::Object_var obj; CORBA::Object_var object; - SALOME_NamingService &naming = *SINGLETON_::Instance() ; + //SALOME_NamingService &naming = *SINGLETON_::Instance() ; int CONTAINER=0; const char * Env = getenv("USE_LOGGER"); int EnvL =0; @@ -139,47 +140,14 @@ int main(int argc, char* argv[]) break; } - // define policy objects - PortableServer::ImplicitActivationPolicy_var implicitActivation = - root_poa->create_implicit_activation_policy(PortableServer::NO_IMPLICIT_ACTIVATION) ; - - // default = NO_IMPLICIT_ACTIVATION - PortableServer::ThreadPolicy_var threadPolicy = - root_poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL); - // default = ORB_CTRL_MODEL, other choice SINGLE_THREAD_MODEL - - // create policy list - CORBA::PolicyList policyList; - policyList.length(2); - policyList[0] = PortableServer::ImplicitActivationPolicy::_duplicate(implicitActivation) ; - policyList[1] = PortableServer::ThreadPolicy::_duplicate(threadPolicy) ; - - // create the child POA - PortableServer::POAManager_var nil_mgr = PortableServer::POAManager::_nil() ; - PortableServer::POA_var factory_poa = - root_poa->create_POA("factory_poa", pman, policyList) ; - //with nil_mgr instead of pman, a new POA manager is created with the new POA - - // destroy policy objects - implicitActivation->destroy() ; - threadPolicy->destroy() ; - char *containerName = ""; if(argc > 1){ containerName = argv[1] ; } Engines_Container_i * myContainer - = new Engines_Container_i(orb, factory_poa, containerName , argc , argv ); - - // Engines_Container_i * myContainer - // = new Engines_Container_i(string(argv[1]),string(argv[2]), orb, factory_poa); - - // use naming service - // myContainer->_NS.init_orb(orb); - // Engines::Container_ptr pCont = Engines::Container::_narrow(myContainer->_this()); - // myContainer->_NS.Register(pCont, argv[2]); - + = new Engines_Container_i(orb, root_poa, containerName , argc , argv ); + pman->activate(); #ifdef CHECKTIME @@ -191,8 +159,6 @@ int main(int argc, char* argv[]) #endif HandleServerSideSignals(orb); - - orb->destroy(); }catch(CORBA::SystemException&){ INFOS("Caught CORBA::SystemException."); }catch(PortableServer::POA::WrongPolicy&){ diff --git a/src/Container/SALOME_ContainerManager.cxx b/src/Container/SALOME_ContainerManager.cxx new file mode 100644 index 000000000..14e377405 --- /dev/null +++ b/src/Container/SALOME_ContainerManager.cxx @@ -0,0 +1,138 @@ +#include "SALOME_ContainerManager.hxx" +#include "SALOME_NamingService.hxx" +#include "OpUtil.hxx" +#include +#include +#include + +#define TIME_OUT_TO_LAUNCH_CONT 21 + +using namespace std; + +const char *SALOME_ContainerManager::_ContainerManagerNameInNS="ContainerManager"; + +SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb) +{ + _NS=new SALOME_NamingService(orb); + PortableServer::POA_var root_poa=PortableServer::POA::_the_root_poa(); + PortableServer::ObjectId_var id=root_poa->activate_object(this); + CORBA::Object_var obj=root_poa->id_to_reference(id); + Engines::ContainerManager_var refContMan = Engines::ContainerManager::_narrow(obj); + _NS->Register(refContMan,_ContainerManagerNameInNS); +} + +SALOME_ContainerManager::~SALOME_ContainerManager() +{ + delete _NS; +} + +void SALOME_ContainerManager::Shutdown() +{ + ShutdownContainers(); + PortableServer::ObjectId_var oid = _default_POA()->servant_to_id(this); + _default_POA()->deactivate_object(oid); + _remove_ref(); + +} + +void SALOME_ContainerManager::ShutdownContainers() +{ + _NS->Change_Directory("/Containers"); + vector vec=_NS->list_directory_recurs(); + for(vector::iterator iter=vec.begin();iter!=vec.end();iter++) + { + CORBA::Object_var obj=_NS->Resolve((*iter).c_str()); + Engines::Container_var cont=Engines::Container::_narrow(obj); + if(!CORBA::is_nil(cont)) + cont->Shutdown(); + } +} + +Engines::Container_ptr SALOME_ContainerManager::FindOrStartContainer(const char *containerName, const Engines::MachineList& possibleComputers) +{ + Engines::Container_ptr ret=FindContainer(containerName,possibleComputers); + if(!CORBA::is_nil(ret)) + return ret; + // Container doesn't exist try to launch it ... + vector vector; + string theMachine=_LoadManager.FindBest(possibleComputers); + string command; + if(theMachine==GetHostname()) + command=_ResManager.BuildCommandToLaunchLocalContainer(containerName); + else + command=_ResManager.BuildTempFileToLaunchRemoteContainer(theMachine,containerName); + _ResManager.RmTmpFile(); + int status=system(command.c_str()); + if (status == -1) { + MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status -1)"); + return Engines::Container::_nil(); + } + else if (status == 217) { + MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status 217)"); + return Engines::Container::_nil(); + } + else { + int count=TIME_OUT_TO_LAUNCH_CONT; + while ( CORBA::is_nil(ret) && count ) { + sleep( 1 ) ; + count-- ; + if ( count != 10 ) + MESSAGE( count << ". Waiting for FactoryServer on " << theMachine); + string containerNameInNS=BuildContainerNameInNS(containerName,theMachine.c_str()); + CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str()); + ret=Engines::Container::_narrow(obj); + } + if ( CORBA::is_nil(ret) ) { + MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed"); + } + return ret; + } +} + +Engines::MachineList *SALOME_ContainerManager::GetFittingResources(const Engines::MachineParameters& params, const char *componentName) +{ + vector vec=_ResManager.GetFittingResources(params,componentName); + Engines::MachineList *ret=new Engines::MachineList; + ret->length(vec.size()); + for(unsigned int i=0;iResolve(containerNameInNS.c_str()); + if( !CORBA::is_nil(obj) ) + return Engines::Container::_narrow(obj); + else + return Engines::Container::_nil(); +} + +Engines::Container_ptr SALOME_ContainerManager::FindContainer(const char *containerName,const Engines::MachineList& possibleComputers) +{ + for(unsigned int i=0;i +#include CORBA_CLIENT_HEADER(SALOME_Component) +#include CORBA_CLIENT_HEADER(SALOME_ContainerManager) +#include "SALOME_ResourcesManager.hxx" +#include "SALOME_LoadRateManager.hxx" + +#include + +class SALOME_NamingService; + +class SALOME_ContainerManager: public POA_Engines::ContainerManager, + public PortableServer::RefCountServantBase { +private: + SALOME_ResourcesManager _ResManager; + SALOME_LoadRateManager _LoadManager; + SALOME_NamingService *_NS; +public: + SALOME_ContainerManager(CORBA::ORB_ptr orb); + ~SALOME_ContainerManager(); + Engines::Container_ptr FindOrStartContainer(const char *containerName, const Engines::MachineList& possibleComputer); + Engines::MachineList *GetFittingResources(const Engines::MachineParameters& params, const char *componentName); + char* FindBest(const Engines::MachineList& possibleComputers); + void Shutdown(); + void ShutdownContainers(); + + static const char *_ContainerManagerNameInNS; +private: + Engines::Container_ptr FindContainer(const char *containerName,const Engines::MachineList& possibleComputers); + Engines::Container_ptr FindContainer(const char *containerName,const char *theMachine); + std::string BuildContainerNameInNS(const char *containerName,const char *machineName); +}; + +#endif diff --git a/src/Container/SALOME_Container_i.hxx b/src/Container/SALOME_Container_i.hxx index 6f309c50c..249f80657 100644 --- a/src/Container/SALOME_Container_i.hxx +++ b/src/Container/SALOME_Container_i.hxx @@ -52,14 +52,10 @@ public: PortableServer::POA_ptr poa, char * containerName , int argc, char* argv[], - bool regist = true, - bool activ = true); + bool activAndRegist = true); virtual ~Engines_Container_i(); - //! Launch a new container from the current container - Engines::Container_ptr start_impl(const char* ContainerName); - //! Load component in current container Engines::Component_ptr load_impl(const char* nameToRegister, const char* componentName); @@ -71,13 +67,16 @@ public: char* name(); char* machineName(); void ping(); - + void Shutdown(); //! Kill current container bool Kill_impl() ; char* getHostName(); CORBA::Long getPID(); + static bool isPythonContainer(const char* ContainerName); + static std::string BuildContainerNameForNS(const char *ContainerName, const char *hostname); + static const char *_defaultContainerName; protected: SALOME_NamingService *_NS ; diff --git a/src/LifeCycleCORBA/LifeCycleCORBA.py b/src/LifeCycleCORBA/LifeCycleCORBA.py index 273916dd4..82c364936 100644 --- a/src/LifeCycleCORBA/LifeCycleCORBA.py +++ b/src/LifeCycleCORBA/LifeCycleCORBA.py @@ -78,6 +78,15 @@ class LifeCycleCORBA: if self._catalog is None: MESSAGE( "/Kernel.dir/ModulCatalog.object exists but is not a ModulCatalog" ) + name = [CosNaming.NameComponent("ContainerManager","object")] + try: + obj = self._rootContext.resolve(name) + except CosNaming.NamingContext.NotFound, ex: + MESSAGE( "ContainerManager.object not found in Naming Service" ) + self._contManager = obj._narrow(Engines.ContainerManager) + if self._contManager is None: + MESSAGE( "ContainerManager.object exists but is not a ContainerManager") + #------------------------------------------------------------------------- def ContainerName(self, containerName): @@ -130,120 +139,81 @@ class LifeCycleCORBA: #------------------------------------------------------------------------- - def FindOrStartContainer(self, theComputer , theContainer ): - MESSAGE( "FindOrStartContainer" + theComputer + theContainer ) - aContainer = self.FindContainer( theComputer + "/" + theContainer ) - if aContainer is None : - if (theContainer == "FactoryServer") | (theContainer == "FactoryServerPy") : - myMachine=getShortHostName() - if theComputer == myMachine : - rshstr = "" - else : - rshstr = "rsh -n " + theComputer + " " - path = self.ComputerPath( theComputer ) -## if path != "" : -## rshstr = rshstr + path + "/../bin/" -## else : -## rshstr = rshstr + os.getenv( "KERNEL_ROOT_DIR" ) + "/bin/" - if theContainer == "FactoryServer" : - rshstr = rshstr + path + "SALOME_Container " - else : - rshstr = rshstr + path + "SALOME_ContainerPy.py '" - rshstr = rshstr + theContainer + " -" - omniORBcfg = os.getenv( "OMNIORB_CONFIG" ) - file = os.open( omniORBcfg , os.O_RDONLY ) - ORBInitRef = os.read(file,132) - if ORBInitRef[len(ORBInitRef)-1] == '\n' : - ORBInitRef,bsn = ORBInitRef.split('\n') - os.close( file ) - rshstr = rshstr + ORBInitRef - if theContainer == "FactoryServerPy" : - rshstr = rshstr + "'" - rshstr = rshstr + " > /tmp/" + theContainer + "_" - rshstr = rshstr + theComputer - rshstr = rshstr + ".log 2>&1 &" - os.system( rshstr ) - MESSAGE( "FindOrStartContainer" + rshstr + " done" ) - else : - if theContainer.find('Py') == -1 : - aContainer = self.FindContainer( theComputer + "/" + "FactoryServer" ) - else : - aContainer = self.FindContainer( theComputer + "/" + "FactoryServerPy" ) - aContainer = aContainer.start_impl( theContainer ) - - count = 21 - while aContainer is None : - time.sleep(1) - count = count - 1 - MESSAGE( str(count) + ". Waiting for " + theComputer + "/" + theContainer ) - aContainer = self.FindContainer( theComputer + "/" + theContainer ) - if count == 0 : - return aContainer - - return aContainer - #os.system("rsh -n dm2s0017 /export/home/KERNEL_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515") + def FindComponent(self,containerName,componentName,listOfMachines): + if containerName!="": + machinesOK=[] + for i in range(len(listOfMachines)): + currentMachine=listOfMachines[i] + componentNameForNS= [CosNaming.NameComponent(currentMachine,"dir"), + CosNaming.NameComponent(containerName,"dir"), + CosNaming.NameComponent(componentName,"object")] + obj=None + try: + obj = self._containerRootContext.resolve(componentNameForNS) + except CosNaming.NamingContext.NotFound, ex: + MESSAGE( "component " + componentName + " not found on machine " + currentMachine + " , trying to load" ) + pass + if obj is not None: + machinesOK.append(currentMachine) + pass + pass + if len(machinesOK)!=0: + bestMachine=self._contManager.FindBest(machinesOK) + componentNameForNS= [CosNaming.NameComponent(bestMachine,"dir"), + CosNaming.NameComponent(containerName,"dir"), + CosNaming.NameComponent(componentName,"object")] + obj=None + try: + obj = self._containerRootContext.resolve(componentNameForNS) + except: + pass + if obj is not None: + return obj._narrow(Engines.Component) + else: + MESSAGE( "Big problem !!!") + return None + else: + return None + else: + bestMachine=self._contManager.FindBest(listOfMachines) + MESSAGE("Not implemented yet ...") + return None + pass #------------------------------------------------------------------------- - def FindOrLoadComponent(self, containerName, componentName): - - theComputer,theContainer = self.ContainerName( containerName ) - name = [CosNaming.NameComponent(theComputer,"dir"), - CosNaming.NameComponent(theContainer,"dir"), - CosNaming.NameComponent(componentName,"object")] + def LoadComponent(self,containerName,componentName,listOfMachine): + container=self._contManager.FindOrStartContainer(containerName,listOfMachine) + implementation="lib"+componentName+"Engine.so" try: - obj = self._containerRootContext.resolve(name) - except CosNaming.NamingContext.NotFound, ex: - MESSAGE( "component " + componentName + " not found, trying to load" ) - container = self.FindContainer(theComputer + "/" + theContainer) - if container is None: - MESSAGE( "container " + theComputer + "/" + theContainer + " not found in Naming Service, trying to start" ) - if (theContainer != "FactoryServer") & (theContainer != "FactoryServerPy") : - if theContainer.find('Py') == -1 : - theFactorycontainer = "FactoryServer" - else : - theFactorycontainer = "FactoryServerPy" - Factorycontainer = self.FindContainer(theComputer + "/" + theFactorycontainer) - if Factorycontainer is None: - MESSAGE( "container " + theComputer + "/" + theFactorycontainer + " not found in Naming Service, trying to start" ) - Factorycontainer = self.FindOrStartContainer(theComputer,theFactorycontainer) - else: - Factorycontainer = self.FindOrStartContainer(theComputer,theContainer) - if Factorycontainer != None : - container = self.FindOrStartContainer(theComputer,theContainer) - - if container != None: - compoinfo = self._catalog.GetComponent(componentName) - if compoinfo is None: - MESSAGE( "component " + componentName + " not found in Module Catalog" ) - else: - try: - machineName = theComputer - path = compoinfo.GetPathPrefix(machineName) + "/" - except SALOME_ModuleCatalog.NotFound, ex: - MESSAGE( "machine " + machineName + " not found in Module Catalog" ) - MESSAGE( "trying localhost" ) - try: - path = compoinfo.GetPathPrefix("localhost") + "/" - except SALOME_ModuleCatalog.NotFound, ex: - path = "" - implementation = path + "lib" + componentName + "Engine.so" - MESSAGE( "Trying to load " + implementation ) - try: - component = container.load_impl(componentName, implementation) - MESSAGE( "component " + component._get_instanceName() + " launched !" ) - return component - except: - MESSAGE( "component " + componentName + " NOT launched !" ) + component = container.load_impl(componentName, implementation) + MESSAGE( "component " + component._get_instanceName() + " launched !" ) + return component + except: + MESSAGE( "component " + componentName + " NOT launched !" ) + return None + #------------------------------------------------------------------------- + + + def FindOrLoadComponent(self, containerName, componentName): + sp=containerName.split("/") + if len(sp)==1: + listOfMachine=[] + listOfMachine.append(getShortHostName()) + comp=self.FindComponent(containerName,componentName,listOfMachine) + if comp is None: + return self.LoadComponent(containerName,componentName,listOfMachine) + else: + return comp + pass else: - try: - component = obj._narrow(Engines.Component) - if component is None: - MESSAGE( componentName + " is not a component !" ) - else: - MESSAGE( "component " + component._get_instanceName() + " found !" ) - return component - except: - MESSAGE( componentName + " failure" ) - return None + params= Engines.MachineParameters(sp[1],sp[0],"LINUX",0,0,0,0) + listOfMachine=self._contManager.GetFittingResources(params,componentName) + ret=self.FindComponent(sp[1],componentName,listOfMachine); + if ret is None: + return self.LoadComponent(sp[1],componentName,listOfMachine) + else: + return ret + pass + diff --git a/src/LifeCycleCORBA/Makefile.in b/src/LifeCycleCORBA/Makefile.in index 33ee1ac81..49e86e969 100644 --- a/src/LifeCycleCORBA/Makefile.in +++ b/src/LifeCycleCORBA/Makefile.in @@ -43,15 +43,17 @@ EXPORT_PYSCRIPTS = LifeCycleCORBA.py LIB = libSalomeLifeCycleCORBA.la LIB_SRC = SALOME_LifeCycleCORBA.cxx LIB_CLIENT_IDL = SALOME_Component.idl SALOME_TestComponent.idl \ - SALOME_ModuleCatalog.idl + SALOME_ModuleCatalog.idl SALOME_ContainerManager.idl # Executables targets BIN = TestLifeCycleCORBA BIN_SRC = BIN_CLIENT_IDL = SALOME_Component.idl SALOME_TestComponent.idl \ - SALOME_ModuleCatalog.idl + SALOME_ModuleCatalog.idl SALOME_ContainerManager.idl -LDFLAGS += -lSalomeNS -lOpUtil -lSALOMELocalTrace +CPPFLAGS += $(QT_MT_INCLUDES) + +LDFLAGS += -lSalomeNS -lOpUtil -lSALOMELocalTrace -lSalomeContainer -lSalomeResourcesManager -lRegistry -lSalomeNotification -lSALOMETraceCollector @CONCLUDE@ diff --git a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx index 7908d60ae..cbc8b24ec 100644 --- a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx +++ b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx @@ -38,19 +38,17 @@ #include "SALOME_LifeCycleCORBA.hxx" #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include "SALOME_ContainerManager.hxx" +#include "SALOME_Component_i.hxx" #include "SALOME_NamingService.hxx" using namespace std; -SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA() -{ - _NS = NULL; - _FactoryServer = NULL ; -} - SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA(SALOME_NamingService *ns) { _NS = ns; - _FactoryServer = NULL ; + //add try catch + CORBA::Object_var obj=_NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS); + _ContManager=Engines::ContainerManager::_narrow(obj); } SALOME_LifeCycleCORBA::~SALOME_LifeCycleCORBA() @@ -86,6 +84,7 @@ string SALOME_LifeCycleCORBA::ContainerName( theComputerContainer += "/" ; theComputerContainer += *theContainer ; } + delete [] ContainerName; return theComputerContainer ; } @@ -106,316 +105,92 @@ string SALOME_LifeCycleCORBA::ComputerPath( return CORBA::string_dup( path ) ; } -Engines::Container_var SALOME_LifeCycleCORBA::FindContainer(const char *containerName ) { - ASSERT(_NS != NULL); - string cont ; - if ( strncmp( containerName , "/Containers/" , 12 ) ) { // Compatibility ... - string theComputer ; - string theContainer ; - cont = ContainerName( containerName , &theComputer , &theContainer ) ; +Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component + (const char *containerName, + const char *componentName) +{ + char *stContainer=strdup(containerName); + string st2Container(stContainer); + int rg=st2Container.find("/"); + if(rg<0) { + //containerName doesn't contain "/" => Local container + free(stContainer); + Engines::MachineList_var listOfMachine=new Engines::MachineList; + listOfMachine->length(1); + listOfMachine[0]=CORBA::string_dup(GetHostname().c_str()); + Engines::Component_ptr ret=FindComponent(containerName,componentName,listOfMachine.in()); + if(CORBA::is_nil(ret)) + return LoadComponent(containerName,componentName,listOfMachine); + else + return ret; } else { - cont = containerName ; + //containerName contains "/" => Remote container + stContainer[rg]='\0'; + Engines::MachineParameters_var params=new Engines::MachineParameters; + params->container_name=CORBA::string_dup(stContainer+rg+1); + params->hostname=CORBA::string_dup(stContainer); + params->OS=CORBA::string_dup("LINUX"); + free(stContainer); + return FindOrLoad_Component(params,componentName); } - try { - - SCRUTE( cont ); - - CORBA::Object_var obj = _NS->Resolve( cont.c_str() ); - if( !CORBA::is_nil( obj ) ) { - return Engines::Container::_narrow( obj ) ; - } - } - catch (ServiceUnreachable&) { - INFOS("Caught exception: Naming Service Unreachable"); - } - catch (...) { - INFOS("Caught unknown exception."); - } - return Engines::Container::_nil(); } -Engines::Container_var SALOME_LifeCycleCORBA::FindOrStartContainer( - const string aComputerContainer , - const string theComputer , - const string theContainer ) { - Engines::Container_var aContainer = FindContainer( aComputerContainer.c_str() ) ; - Engines::Container_var aFactoryServer ; - SCRUTE( aComputerContainer ) ; - SCRUTE( theComputer ) ; - SCRUTE( theContainer ) ; - bool pyCont = false ; - int len = theContainer.length() ; - if ( !strcmp( &theContainer.c_str()[len-2] , "Py" ) ) { - pyCont = true ; - } - if ( !CORBA::is_nil( aContainer ) ) { - return aContainer ; - } - else { - string FactoryServer = theComputer ; - if ( pyCont ) { - FactoryServer += "/FactoryServerPy" ; - } - else { - FactoryServer += "/FactoryServer" ; - } - aFactoryServer = FindContainer( FactoryServer.c_str() ) ; - if ( CORBA::is_nil( aFactoryServer ) ) { -// rsh -n ikkyo /export/home/rahuel/SALOME_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515 & - string rsh( "" ) ; - if ( theComputer!= GetHostname() ) { - rsh += "rsh -n " ; - rsh += theComputer ; - rsh += " " ; - } - string path = ComputerPath( theComputer.c_str() ) ; - SCRUTE( path ) ; - if ( path[0] != '\0' ) { - rsh += path ; - rsh += "/../bin/" ; - } - rsh += "runSession " ; - if ( pyCont ) { - rsh += "SALOME_ContainerPy.py " ; - rsh += "FactoryServerPy -" ; - } - else { - rsh += "SALOME_Container " ; - rsh += "FactoryServer -" ; - } - string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ; - ifstream omniORBfile( omniORBcfg.c_str() ) ; - char ORBInitRef[12] ; - char nameservice[132] ; - omniORBfile >> ORBInitRef ; - rsh += ORBInitRef ; - rsh += " " ; - omniORBfile >> nameservice ; - omniORBfile.close() ; - char * bsn = strchr( nameservice , '\n' ) ; - if ( bsn ) { - bsn[ 0 ] = '\0' ; - } - rsh += nameservice ; - if ( pyCont ) { - rsh += " > /tmp/FactoryServerPy_" ; - } - else { - rsh += " > /tmp/FactoryServer_" ; - } - rsh += theComputer ; - rsh += ".log 2>&1 &" ; - SCRUTE( rsh ); - int status = system( rsh.c_str() ) ; - if (status == -1) { - MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status -1)") ; - } - else if (status == 217) { - MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status 217)") ; - } - else { - int count = 21 ; - while ( CORBA::is_nil( aFactoryServer ) && count ) { - sleep( 1 ) ; - count-- ; - if ( count != 10 ) - MESSAGE( count << ". Waiting for FactoryServer on " << theComputer) - aFactoryServer = FindContainer( FactoryServer.c_str() ) ; - } - if ( CORBA::is_nil( aFactoryServer ) ) { - MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed") ; - } - else if ( strcmp( theComputer.c_str() , GetHostname().c_str() ) ) { - _FactoryServer = aFactoryServer ; - } - } - } - if ( !CORBA::is_nil( aFactoryServer ) ) { - if ( strcmp( theContainer.c_str() , "FactoryServer" ) || - strcmp( theContainer.c_str() , "FactoryServerPy" ) ) { - MESSAGE("Container not found ! trying to start " << aComputerContainer); - Engines::Container_var myContainer = aFactoryServer->start_impl( theContainer.c_str() ) ; - if ( !CORBA::is_nil( myContainer ) ) { - MESSAGE("Container " << aComputerContainer << " started"); - return myContainer ; - } - else { - MESSAGE("Container " << aComputerContainer << " NOT started"); - } - } - else { - MESSAGE("Container " << aComputerContainer << " started"); - return aFactoryServer ; - } - } - } - return Engines::Container::_nil(); +Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component(const Engines::MachineParameters& params, + const char *componentName) +{ + Engines::MachineList_var listOfMachine=_ContManager->GetFittingResources(params,componentName); + Engines::Component_ptr ret=FindComponent(params.container_name,componentName,listOfMachine); + if(CORBA::is_nil(ret)) + return LoadComponent(params.container_name,componentName,listOfMachine); + else + return ret; } -Engines::Component_var SALOME_LifeCycleCORBA::FindOrLoad_Component - (const char *containerName, - const char *componentName, - const char *implementation) +Engines::Component_ptr SALOME_LifeCycleCORBA::FindComponent(const char *containerName, + const char *componentName, + const Engines::MachineList& listOfMachines) { - BEGIN_OF("FindOrLoad_Component(1)"); - ASSERT(_NS != NULL); - string theComputer ; - string theContainer ; - string theComputerContainer = ContainerName( containerName , - &theComputer , - &theContainer ) ; - Engines::Container_var cont = FindOrStartContainer( theComputerContainer , - theComputer , - theContainer ) ; -// ASSERT(!CORBA::is_nil(cont)); - - string path( theComputerContainer ); - path = path + "/"; - path = path + componentName; - SCRUTE(path); - try + if(containerName[0]!='\0') { - CORBA::Object_var obj = _NS->Resolve(path.c_str()); - if (CORBA::is_nil(obj)) - { - MESSAGE("Component not found ! trying to load " << path); - Engines::Component_var compo - = cont->load_impl(componentName, implementation); -// ASSERT(!CORBA::is_nil(compo)); - MESSAGE("Component launched !" << path); - return compo; - } - else + Engines::MachineList_var machinesOK=new Engines::MachineList; + unsigned int lghtOfmachinesOK=0; + machinesOK->length(listOfMachines.length()); + for(unsigned int i=0;iping(); - } - catch (CORBA::COMM_FAILURE&) + const char *currentMachine=listOfMachines[i]; + string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,currentMachine); + CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str()); + if(!CORBA::is_nil(obj)) { - INFOS("Caught CORBA::SystemException CommFailure. Engine " - << path << "does not respond" ); + machinesOK[lghtOfmachinesOK++]=CORBA::string_dup(currentMachine); } - return compo; } + if(lghtOfmachinesOK!=0) + { + machinesOK->length(lghtOfmachinesOK); + CORBA::String_var bestMachine=_ContManager->FindBest(machinesOK); + string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine); + CORBA::Object_var obj=_NS->Resolve(componentNameForNS.c_str()); + return Engines::Component::_narrow(obj); + } + else + return Engines::Component::_nil(); } - catch (ServiceUnreachable&) - { - INFOS("Caught exception: Naming Service Unreachable"); - } - catch (...) + else { - INFOS("Caught unknown exception."); + //user specified no container name so trying to find a component in the best machine among listOfMachines + CORBA::String_var bestMachine=_ContManager->FindBest(listOfMachines); + //Normally look at all containers launched on bestMachine to see if componentName is already launched on one of them. To do.. + string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine); + CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str()); + return Engines::Component::_narrow(obj); } - return Engines::Component::_nil(); } -Engines::Component_var SALOME_LifeCycleCORBA::FindOrLoad_Component - (const char *containerName, - const char *componentName) +Engines::Component_ptr SALOME_LifeCycleCORBA::LoadComponent(const char *containerName, const char *componentName, const Engines::MachineList& listOfMachines) { -// BEGIN_OF("FindOrLoad_Component(2)"); - ASSERT(_NS != NULL); - string theComputer ; - string theContainer ; - string theComputerContainer = ContainerName( containerName , - &theComputer , - &theContainer ) ; - Engines::Container_var cont = FindOrStartContainer( theComputerContainer , - theComputer , - theContainer ) ; - - if ( CORBA::is_nil( cont ) ) { - MESSAGE("Container not found ! " << theComputerContainer ); - return Engines::Component::_nil(); - } - -// char * machine = cont->machineName() ; - const char * machine = theComputer.c_str() ; - - string path( theComputerContainer ); - path += "/"; - path += componentName; - SCRUTE(path); - - try { - CORBA::Object_var obj = _NS->Resolve(path.c_str()); - if ( CORBA::is_nil( obj ) ) { - MESSAGE("Component not found ! trying to load " << path); - CORBA::Object_var obj2 = _NS->Resolve("/Kernel/ModulCatalog"); - SALOME_ModuleCatalog::ModuleCatalog_var Catalog = - SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj2); - - SALOME_ModuleCatalog::Acomponent_ptr compoInfo = - Catalog->GetComponent(componentName); - if (CORBA::is_nil (compoInfo)) - { - INFOS("Catalog Error : Component not found in the catalog") - return Engines::Component::_nil(); -// exit (-1); - } - - string path; - try - { - path = compoInfo->GetPathPrefix( machine ) ; - path += "/" ; - } - catch (SALOME_ModuleCatalog::NotFound&) - { - INFOS("GetPathPrefix(" << machine << ") not found!" - << "trying localhost"); - try { - path = compoInfo->GetPathPrefix("localhost") ; - path += "/" ; - } - catch (SALOME_ModuleCatalog::NotFound&) { - INFOS("GetPathPrefix(localhost) not found!") ; - path = "" ; - } - } - - SCRUTE(path); - string implementation(path); - implementation += "lib"; - implementation += componentName; - implementation += "Engine.so"; - - Engines::Component_var compo - = cont->load_impl(componentName, implementation.c_str()); - -// ASSERT(!CORBA::is_nil(compo)); -// MESSAGE("Component launched !" << path); - return compo; - } - else - { - MESSAGE("Component found !" << path); - Engines::Component_var compo = Engines::Component::_narrow(obj); -// ASSERT(!CORBA::is_nil(compo)); - try - { - string instanceName = compo->instanceName(); - } - catch (CORBA::COMM_FAILURE&) - { - INFOS("Caught CORBA::SystemException CommFailure. Engine " - << path << "does not respond" ); - } - return compo; - } - } - catch (ServiceUnreachable&) - { - INFOS("Caught exception: Naming Service Unreachable"); - } - catch (...) - { - INFOS("Caught unknown exception."); - } - return Engines::Component::_nil(); + Engines::Container_var cont=_ContManager->FindOrStartContainer(containerName,listOfMachines); + string implementation=Engines_Component_i::GetDynLibraryName(componentName); + return cont->load_impl(componentName, implementation.c_str()); } diff --git a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx index 23b4e8797..ed5c78c25 100644 --- a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx +++ b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx @@ -34,6 +34,7 @@ #include #include +#include CORBA_CLIENT_HEADER(SALOME_ContainerManager) #include CORBA_CLIENT_HEADER(SALOME_Component) class SALOME_NamingService; @@ -41,29 +42,29 @@ class SALOME_NamingService; class SALOME_LifeCycleCORBA { public: - SALOME_LifeCycleCORBA(); SALOME_LifeCycleCORBA(SALOME_NamingService *ns); virtual ~SALOME_LifeCycleCORBA(); - - Engines::Container_var FindContainer(const char *containerName); - Engines::Component_var FindOrLoad_Component(const char *containerName, - const char *componentName, - const char *implementationPath); - Engines::Component_var FindOrLoad_Component(const char *containerName, + Engines::Component_ptr FindOrLoad_Component(const Engines::MachineParameters& params, + const char *componentName); + Engines::Component_ptr FindOrLoad_Component(const char *containerName, const char *componentName); protected: - SALOME_NamingService *_NS; - Engines::Container_var _FactoryServer ; + //! Establish if a component called "componentName" in a container called "containerName" exists among the list of resources + //! in "listOfMachines". This method uses Naming Service to find the component. + Engines::Component_ptr FindComponent(const char *containerName, + const char *componentName, + const Engines::MachineList& listOfMachines); + Engines::Component_ptr LoadComponent(const char *containerName, const char *componentName, const Engines::MachineList& listOfMachines); + + SALOME_NamingService *_NS; + Engines::ContainerManager_var _ContManager; + //private: std::string ContainerName( const char * aComputerContainer , - std::string * theComputer , - std::string * theContainer ) ; + std::string * theComputer , + std::string * theContainer ) ; std::string ComputerPath( const char * theComputer ) ; - Engines::Container_var FindOrStartContainer(const std::string aComputerContainer , - const std::string theComputer , - const std::string theContainer ) ; - } ; #endif diff --git a/src/MPIContainer/MPIContainer_i.cxx b/src/MPIContainer/MPIContainer_i.cxx index ad729c45a..73e9ffaa0 100644 --- a/src/MPIContainer/MPIContainer_i.cxx +++ b/src/MPIContainer/MPIContainer_i.cxx @@ -40,7 +40,7 @@ Engines_MPIContainer_i::Engines_MPIContainer_i(int nbproc, int numproc, PortableServer::POA_ptr poa, char * containerName, int argc, char *argv[]) - : Engines_Container_i(orb,poa,containerName,argc,argv,false,false), MPIObject_i(nbproc,numproc) + : Engines_Container_i(orb,poa,containerName,argc,argv,false), MPIObject_i(nbproc,numproc) { MESSAGE("[" << numproc << "] activate object"); _id = _poa->activate_object(this); diff --git a/src/Makefile.in b/src/Makefile.in index 2cca687df..91f81257e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -36,7 +36,7 @@ ifeq (@WITHIHM@,yes) SUBDIRS = MSG2QM SALOMELocalTrace SALOMETraceCollector Logger Utils CASCatch PatchQt \ GenericObj MEDWrapper NamingService Registry \ ModuleCatalog DataTypeCatalog RessourcesCatalog \ - Notification NOTIFICATION_SWIG \ + ResourcesManager Notification NOTIFICATION_SWIG \ Container TestContainer LifeCycleCORBA HDFPersist Prs \ VTKFilter OBJECT \ TOOLSDS SALOMEDS Event \ @@ -50,7 +50,7 @@ ifeq (@WITHIHM@,no) SUBDIRS = MSG2QM SALOMELocalTrace SALOMETraceCollector Logger Utils CASCatch \ GenericObj NamingService Registry \ ModuleCatalog DataTypeCatalog RessourcesCatalog \ - Notification NOTIFICATION_SWIG \ + ResourcesManager Notification NOTIFICATION_SWIG \ Container TestContainer LifeCycleCORBA HDFPersist Prs \ TOOLSDS SALOMEDS Event \ SALOME_SWIG_WITHOUTIHM ModuleGenerator Loader Communication diff --git a/src/NamingService/SALOME_NamingService.cxx b/src/NamingService/SALOME_NamingService.cxx index 07b0e9342..2db7a59b5 100644 --- a/src/NamingService/SALOME_NamingService.cxx +++ b/src/NamingService/SALOME_NamingService.cxx @@ -645,7 +645,7 @@ char* SALOME_NamingService::Current_Directory() // the directories length_path = length_path + strlen(result_path[k]) + 1; } - char* return_Path = new char[length_path +1]; + char* return_Path = new char[length_path +2]; return_Path[0] = '/' ; return_Path[1] = '\0' ; for (int k = 0 ; k SALOME_NamingService::list_directory() return _list; } +//---------------------------------------------------------------------- +/*! Function : list_directory_recurs + * Purpose : method to get all the contexts contained in the current + * directory + * Get only objects and is recursive + * If the NamingService is out, the exception ServiceUnreachable is thrown + */ +//---------------------------------------------------------------------- +vector SALOME_NamingService::list_directory_recurs() + throw(ServiceUnreachable) +{ + vector _list ; + char *currentDir=Current_Directory(); + _list_directory_recurs(_list,0,currentDir); + delete [] currentDir; + return _list; +} //---------------------------------------------------------------------- /*! Function : Destroy_Name @@ -1310,4 +1327,58 @@ SALOME_NamingService::_current_directory(char** result_path, // We go to the last directory where an occurence was found _current_context = _ref_context ; } + + +//---------------------------------------------------------------------- +/*! Function :_list_directory_recurs. + * Purpose : method to list recursively all the objects contained in the tree of absCurDirectory/relativeSubDir. + * \param myList The list that will be filled. + * \param relativeSubDir The directory from absCurDirectory in which the objects are found. + * \param absCurDirectory The directory in ABSOLUTE form. + * _current_context must refer to absCurDirectory. + */ +//---------------------------------------------------------------------- +void SALOME_NamingService::_list_directory_recurs(vector& myList, const char *relativeSubDir,const char *absCurDirectory) +{ + CosNaming::BindingList_var _binding_list; + CosNaming::BindingIterator_var _binding_iterator; + unsigned long nb=0 ; // for using only the BindingIterator to access the bindings + CosNaming::Binding_var _binding ; + char *absDir; + + CosNaming::NamingContext_var _ref_context = _current_context; + if(relativeSubDir) + { + Change_Directory(relativeSubDir); + absDir=new char[strlen(absCurDirectory)+2+strlen(relativeSubDir)]; + strcpy(absDir,absCurDirectory); + strcat(absDir,relativeSubDir); + strcat(absDir,"/"); + } + else + absDir=(char *)absCurDirectory; + _current_context->list(nb, _binding_list, _binding_iterator) ; + + while (_binding_iterator->next_one(_binding)) { + CosNaming::Name _bindingName = _binding->binding_name; + if (_binding->binding_type == CosNaming::ncontext) { + _list_directory_recurs(myList,_bindingName[0].id,absDir); + } + else if (_binding->binding_type == CosNaming::nobject) { + char *elt=new char[strlen(absDir)+2+strlen(_bindingName[0].id)]; + strcpy(elt,absDir); + strcat(elt,_bindingName[0].id); + myList.push_back(elt); + delete [] elt; + } + } + if(relativeSubDir) + { + _current_context = _ref_context ; + delete [] absDir; + } + + _binding_iterator->destroy(); +} + //---------------------------------------------------------------------- diff --git a/src/NamingService/SALOME_NamingService.hxx b/src/NamingService/SALOME_NamingService.hxx index 4504e6ec7..e6ee89213 100644 --- a/src/NamingService/SALOME_NamingService.hxx +++ b/src/NamingService/SALOME_NamingService.hxx @@ -84,6 +84,10 @@ public: // Get only objects, isn't iterative std::vector list_directory() throw(ServiceUnreachable); + + //!methods that lists all objects RECUSIVELY in the current directory + std::vector list_directory_recurs() + throw(ServiceUnreachable); //! method to destroy an association Path-Object Reference void Destroy_Name(const char* Path) @@ -120,6 +124,10 @@ protected: int& length_result, CosNaming::NamingContext_var context_to_found, CORBA::Boolean& _continue); + + //! internal method to list all (recursively) the objects contains in absCurDirectory/relativeSubDir. + void _list_directory_recurs(std::vector& myList, const char *relativeSubDir,const char *absCurDirectory); + }; #endif // SALOME_NAMINGSERVICE_H diff --git a/src/OCCViewer/Makefile.in b/src/OCCViewer/Makefile.in index 55719f6e8..669b4f8ca 100644 --- a/src/OCCViewer/Makefile.in +++ b/src/OCCViewer/Makefile.in @@ -39,6 +39,7 @@ LIB_MOC = \ LIB_CLIENT_IDL = SALOMEDS.idl \ SALOME_ModuleCatalog.idl \ SALOME_Component.idl \ + SALOME_ContainerManager.idl \ SALOME_Exception.idl diff --git a/src/Plot2d/Makefile.in b/src/Plot2d/Makefile.in index 375a786b0..ca9f91bf1 100644 --- a/src/Plot2d/Makefile.in +++ b/src/Plot2d/Makefile.in @@ -43,6 +43,7 @@ LIB_MOC = \ LIB_CLIENT_IDL = SALOMEDS.idl \ SALOME_ModuleCatalog.idl \ SALOME_Component.idl \ + SALOME_ContainerManager.idl \ SALOME_Exception.idl CPPFLAGS+=$(QT_INCLUDES) $(OCC_INCLUDES) $(OGL_INCLUDES) $(PYTHON_INCLUDES) $(QWT_INCLUDES) diff --git a/src/ResourcesManager/Makefile.in b/src/ResourcesManager/Makefile.in new file mode 100755 index 000000000..ac30999d7 --- /dev/null +++ b/src/ResourcesManager/Makefile.in @@ -0,0 +1,66 @@ +# SALOME RessourcesCatalog : implementation of catalog resources parsing (SALOME_ModuleCatalog.idl) +# +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Paul RASCLE, EDF +# Module : SALOME +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +EXPORT_HEADERS = \ + SALOME_ResourcesCatalog_Parser.hxx \ + SALOME_ResourcesManager.hxx \ + SALOME_ResourcesCatalog_Handler.hxx \ + SALOME_LoadRateManager.hxx \ + +# Libraries targets +LIB = libSalomeResourcesManager.la +LIB_SRC = \ + SALOME_ResourcesCatalog_Parser.cxx \ + SALOME_ResourcesCatalog_Handler.cxx \ + SALOME_LoadRateManager.cxx \ + SALOME_ResourcesManager.cxx \ + +# Executables targets +# trouble we have client and serveur and build don't known about this with rule +# in fact client is a test ! So it may go away BIN ! +#BIN = test_rc2 +#SALOME_RessourcesCatalog_Server SALOME_RessourcesCatalog_Client test +LIB_CLIENT_IDL = SALOME_ContainerManager.idl SALOME_Component.idl +BIN_SRC = +BIN_SERVER_IDL = SALOME_ContainerManager.idl + +CPPFLAGS+= $(QT_MT_INCLUDES) -I$(srcdir)/../Container +CXXFLAGS+= +LDFLAGS+= $(QT_MT_LIBS) $(OGL_LIBS) -lSalomeNS -lOpUtil -lSALOMELocalTrace -lSALOMETraceCollector + +@CONCLUDE@ + + diff --git a/src/ResourcesManager/SALOME_LoadRateManager.cxx b/src/ResourcesManager/SALOME_LoadRateManager.cxx new file mode 100644 index 000000000..ab5aa4d88 --- /dev/null +++ b/src/ResourcesManager/SALOME_LoadRateManager.cxx @@ -0,0 +1,9 @@ +#include "SALOME_LoadRateManager.hxx" + +using namespace std; + +string SALOME_LoadRateManager::FindBest(const Engines::MachineList& hosts) +{ + // for the moment then "maui" will be used for dynamic selection ... + return string(hosts[0]); +} diff --git a/src/ResourcesManager/SALOME_LoadRateManager.hxx b/src/ResourcesManager/SALOME_LoadRateManager.hxx new file mode 100644 index 000000000..9a5d98441 --- /dev/null +++ b/src/ResourcesManager/SALOME_LoadRateManager.hxx @@ -0,0 +1,14 @@ +#ifndef __SALOME_LOADRATEMANAGER_HXX__ +#define __SALOME_LOADRATEMANAGER_HXX__ + +#include +#include CORBA_CLIENT_HEADER(SALOME_ContainerManager) +#include + +class SALOME_LoadRateManager +{ +public: + std::string FindBest(const Engines::MachineList& hosts); +}; + +#endif diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx new file mode 100755 index 000000000..2dc349b2d --- /dev/null +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx @@ -0,0 +1,289 @@ +// SALOME ResourcesCatalog : implementation of catalog resources parsing (SALOME_ModuleCatalog.idl) +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SALOME_ResourcesCatalog_Handler.cxx +// Author : Estelle Deville +// Module : SALOME +//$Header$ + +#include "SALOME_ResourcesCatalog_Handler.hxx" +#include +#include +#include +#include "utilities.h" + +using namespace std; + +//---------------------------------------------------------------------- +//Function : SALOME_ResourcesCatalog_Handler +//Purpose: Constructor +//---------------------------------------------------------------------- +SALOME_ResourcesCatalog_Handler::SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& listOfResources):_resources_list(listOfResources) +{ + MESSAGE("SALOME_ResourcesCatalog_Handler creation"); + //XML tags initialisation + test_machine="machine"; + test_resources="resources"; + + test_hostname="hostname"; + test_alias="alias"; + test_protocol="protocol"; + test_mode="mode"; + test_user_name="userName"; + test_modules="modules"; + test_module_name="moduleName"; + test_module_path="modulePath"; + test_pre_req_file_path="preReqFilePath"; + test_os="OS"; + test_mem_in_mb="memInMB"; + test_cpu_freq_mhz="CPUFreqMHz"; + test_nb_of_nodes="nbOfNodes"; + test_nb_of_proc_per_node="nbOfProcPerNode"; +} + +//---------------------------------------------------------------------- +//Function : ~SALOME_ResourcesCatalog_Handler +//Purpose: Destructor +//---------------------------------------------------------------------- +SALOME_ResourcesCatalog_Handler::~SALOME_ResourcesCatalog_Handler() +{ + MESSAGE("SALOME_ResourcesCatalog_Handler destruction"); +} + +//---------------------------------------------------------------------- +//Function : GetResourcesAfterParsing +//Purpose: Retrieves DS after the file parse. +//---------------------------------------------------------------------- +const MapOfParserResourcesType& SALOME_ResourcesCatalog_Handler::GetResourcesAfterParsing() const +{ + return _resources_list; +} + +//---------------------------------------------------------------------- +//Function : startDocument +//Purpose: overload handler function +//---------------------------------------------------------------------- +bool SALOME_ResourcesCatalog_Handler::startDocument() +{ + MESSAGE("Begin parse document"); + // Empty private elements + _resources_list.clear(); + return true; +} + +//---------------------------------------------------------------------- +//Function : startElement +//Purpose: overload handler function +//---------------------------------------------------------------------- +bool SALOME_ResourcesCatalog_Handler::startElement(const QString&, + const QString&, + const QString& name, + const QXmlAttributes& attrs) +{ + for(int i=0;i::iterator iter=_resources_list.begin();iter!=_resources_list.end();iter++) + { + QDomElement eltRoot = doc.createElement(test_machine); + root.appendChild( eltRoot ); + eltRoot.setAttribute((char *)test_hostname,(*iter).first.c_str()); + eltRoot.setAttribute((char *)test_alias,(*iter).second.Alias.c_str()); + switch((*iter).second.Protocol) + { + case rsh: + eltRoot.setAttribute((char *)test_protocol,"rsh"); + break; + case ssh: + eltRoot.setAttribute((char *)test_protocol,"ssh"); + break; + default: + eltRoot.setAttribute((char *)test_protocol,"rsh"); + } + switch((*iter).second.Mode) + { + case interactive: + eltRoot.setAttribute((char *)test_mode,"interactive"); + break; + case batch: + eltRoot.setAttribute((char *)test_mode,"batch"); + break; + default: + eltRoot.setAttribute((char *)test_mode,"interactive"); + } + eltRoot.setAttribute((char *)test_user_name,(*iter).second.UserName.c_str()); + for(map::const_iterator iter2=(*iter).second.ModulesPath.begin();iter2!=(*iter).second.ModulesPath.end();iter2++) + { + QDomElement rootForModulesPaths=doc.createElement(test_modules); + rootForModulesPaths.setAttribute(test_module_name,(*iter2).first.c_str()); + rootForModulesPaths.setAttribute(test_module_path,(*iter2).second.c_str()); + eltRoot.appendChild(rootForModulesPaths); + } + eltRoot.setAttribute(test_pre_req_file_path,(*iter).second.PreReqFilePath.c_str()); + eltRoot.setAttribute(test_os,(*iter).second.OS.c_str()); + eltRoot.setAttribute(test_mem_in_mb,(*iter).second.DataForSort._memInMB); + eltRoot.setAttribute(test_cpu_freq_mhz,(*iter).second.DataForSort._CPUFreqMHz); + eltRoot.setAttribute(test_nb_of_nodes,(*iter).second.DataForSort._nbOfNodes); + eltRoot.setAttribute(test_nb_of_proc_per_node,(*iter).second.DataForSort._nbOfProcPerNode); + } +} diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.hxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.hxx new file mode 100755 index 000000000..6e9916aab --- /dev/null +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Handler.hxx @@ -0,0 +1,137 @@ +// SALOME ResourcesCatalog : implementation of catalog resources parsing (SALOME_ModuleCatalog.idl) +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SALOME_ResourcesCatalog_Handler.hxx +// Author : Estelle Deville +// Module : SALOME +//$Header$ + +#ifndef SALOME_RESOURCES_CATALOG_HANDLER +#define SALOME_RESOURCES_CATALOG_HANDLER + +#include "SALOME_ResourcesCatalog_Parser.hxx" + +#include +#include +#include + +class QDomElement; +class QDomDocument; + +class SALOME_ResourcesCatalog_Handler : public QXmlDefaultHandler +{ +public : + //! standard constructor + SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& listOfResources); + + const MapOfParserResourcesType& GetResourcesAfterParsing() const; + + //! standard destructor + virtual ~SALOME_ResourcesCatalog_Handler(); + + //! method to overload handler function startDocument + /*! is called before a xml file is parsed + \return true if no error was detected + */ + virtual bool startDocument(); + + //! method to overload handler function startElement + /*! + \param QString argument by value + \param QString argument by value + \param QString qName argument by value + \param QXmlAttributes atts argument by value + \return true if no error was detected + */ + virtual bool startElement(const QString& , const QString& , + const QString& name, const QXmlAttributes& attrs); + + //! method to overload handler function endElement + /*! + \param QString argument by value + \param QString argument by value + \param QString qName argument by value + \return true if no error was detected + */ + virtual bool endElement(const QString&, const QString&, + const QString& qName); + + //! method to overload handler function characters + /*! + \param QString chars argument by value + \return true if no error was detected + */ + virtual bool characters(const QString& chars); + + //! method to overload handler function endDocument + /*! is called at the end of the parsing + \return true if no error was detected + */ + virtual bool endDocument(); + + //! method to overload handler function errorProtocol + /*! + \return the error message + */ + virtual QString errorProtocol(); + +//! method to overload handler function fatalError + /*! + \param QXmlParseException exception argument by value + \return true if no error was detected + */ + virtual bool fatalError(const QXmlParseException& exception); + +//! method to fill the document to be writen in a file + void PrepareDocToXmlFile(QDomDocument& doc); + +private : + QString errorProt; + std::string content; + std::string previous_module_name; + std::string previous_module_path; + + ParserResourcesType _resource; + MapOfParserResourcesType& _resources_list; + + const char *test_machine; + const char *test_resources; + + const char *test_hostname; + const char *test_alias; + const char *test_protocol; + const char *test_mode; + const char *test_user_name; + const char *test_modules; + const char *test_module_name; + const char *test_module_path; + const char *test_pre_req_file_path; + const char *test_os; + const char *test_mem_in_mb; + const char *test_cpu_freq_mhz; + const char *test_nb_of_nodes; + const char *test_nb_of_proc_per_node; + +}; + +#endif // SALOME_RESOURCES_CATALOG_HANDLER diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.cxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.cxx new file mode 100644 index 000000000..d6562befc --- /dev/null +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.cxx @@ -0,0 +1,82 @@ +#include "SALOME_ResourcesCatalog_Parser.hxx" +#include + +#define NULL_VALUE 0 + +using namespace std; + +unsigned int ResourceDataToSort::_nbOfNodesWanted=NULL_VALUE; +unsigned int ResourceDataToSort::_nbOfProcPerNodeWanted=NULL_VALUE; +unsigned int ResourceDataToSort::_CPUFreqMHzWanted=NULL_VALUE; +unsigned int ResourceDataToSort::_memInMBWanted=NULL_VALUE; + +ResourceDataToSort::ResourceDataToSort() +{ +} + +ResourceDataToSort::ResourceDataToSort(const string& hostname,unsigned int nbOfNodes,unsigned int nbOfProcPerNode,unsigned int CPUFreqMHz,unsigned int memInMB):_hostName(hostname),_nbOfNodes(nbOfNodes),_nbOfProcPerNode(nbOfProcPerNode),_CPUFreqMHz(CPUFreqMHz),_memInMB(memInMB) +{ +} + +//! Method used by list::sort to sort the resources used in SALOME_ResourcesManager::GetResourcesFitting +bool ResourceDataToSort::operator< (const ResourceDataToSort& other) const +{ + unsigned int nbPts=GetNumberOfPoints(); + return nbPts_nbOfNodesWanted) + ret+=2000; + else + ret+=1000; + } + //priority 2 : Nb of proc by node + if(_nbOfProcPerNodeWanted!=NULL_VALUE) + { + if(_nbOfProcPerNode==_nbOfProcPerNodeWanted) + ret+=300; + else if(_nbOfProcPerNode > _nbOfProcPerNodeWanted) + ret+=200; + else + ret+=100; + } + //priority 3 : Cpu freq + if(_CPUFreqMHzWanted!=NULL_VALUE) + { + if(_CPUFreqMHz==_CPUFreqMHzWanted) + ret+=30; + else if(_CPUFreqMHz > _CPUFreqMHzWanted) + ret+=20; + else + ret+=10; + } + //priority 4 : memory + if(_memInMBWanted!=NULL_VALUE) + { + if(_memInMB==_memInMBWanted) + ret+=3; + else if(_memInMB > _memInMBWanted) + ret+=2; + else + ret+=1; + } + return ret; +} + +//! Method used for debug +void ResourceDataToSort::Print() const +{ + cout << "Nb of nodes : " << _nbOfNodes << endl; + cout << "Nb of proc per node : " << _nbOfProcPerNode << endl; + cout << "CPU : " << _CPUFreqMHz << endl; + cout << "Mem : " << _memInMB << endl; +} + diff --git a/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx new file mode 100755 index 000000000..989db2f44 --- /dev/null +++ b/src/ResourcesManager/SALOME_ResourcesCatalog_Parser.hxx @@ -0,0 +1,97 @@ +// SALOME ResourcesCatalog : implementation of catalog resources parsing (SALOME_ModuleCatalog.idl) +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SALOME_ResourcesCatalog_Parser.hxx +// Author : Estelle Deville +// Module : SALOME +//$Header$ + +#ifndef SALOME_RESOURCES_CATALOG_PARSER +#define SALOME_RESOURCES_CATALOG_PARSER + +#include +#include +#include +#include + +typedef std::map MapOfModulesPath; + +enum AccessProtocolType {rsh, ssh}; + +enum AccessModeType {interactive, batch}; + +class ResourceDataToSort { +public: + std::string _hostName; + unsigned int _nbOfNodes; + unsigned int _nbOfProcPerNode; + unsigned int _CPUFreqMHz; + unsigned int _memInMB; + static unsigned int _nbOfNodesWanted; + static unsigned int _nbOfProcPerNodeWanted; + static unsigned int _CPUFreqMHzWanted; + static unsigned int _memInMBWanted; +public: + ResourceDataToSort(); + ResourceDataToSort(const std::string& hostname,unsigned int nbOfNodes,unsigned int nbOfProcPerNode,unsigned int CPUFreqMHz,unsigned int memInMB); + bool operator< (const ResourceDataToSort& other) const; + void Print() const; +private: + unsigned int GetNumberOfPoints() const; +// friend class SALOME_ResourcesCatalog_Handler; +// friend class SALOME_ResourcesManager; +// friend struct ParserResourcesType; +}; + +struct ParserResourcesType { + ResourceDataToSort DataForSort; + std::string Alias; + AccessProtocolType Protocol; + AccessModeType Mode; + std::string UserName; + MapOfModulesPath ModulesPath; + std::string PreReqFilePath; + std::string OS; + + void Print(){ + std::cout << "##############*****" << std::endl; + std::cout << "HostName : " << DataForSort._hostName << std::endl; + std::cout << "Alias : " << Alias << std::endl; + std::cout << "Protocol : " << Protocol << std::endl; + std::cout << "Mode : " << Mode << std::endl; + std::cout << "UserName : " << UserName << std::endl; + std::cout << "Modules : " << std::endl; + int i=1; + for(std::map::iterator iter=ModulesPath.begin();iter!=ModulesPath.end();iter++) + { + std::cout << " Module " << i++ << " called : " << (*iter).first << " with path : " << (*iter).second << std::endl; + } + std::cout << "PreReqFilePath : " << PreReqFilePath << std::endl; + std::cout << "OS : " << OS << std::endl; + DataForSort.Print(); + } +}; + +typedef std::map MapOfParserResourcesType; + +#endif //SALOME_RESOURCES_CATALOG_PARSER diff --git a/src/ResourcesManager/SALOME_ResourcesManager.cxx b/src/ResourcesManager/SALOME_ResourcesManager.cxx new file mode 100644 index 000000000..3742f2f83 --- /dev/null +++ b/src/ResourcesManager/SALOME_ResourcesManager.cxx @@ -0,0 +1,365 @@ +#include "SALOME_ResourcesManager.hxx" +#include "SALOME_Container_i.hxx" +#include "Utils_ExceptHandlers.hxx" +#include "OpUtil.hxx" + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#define MAX_SIZE_FOR_HOSTNAME 256; + +using namespace std; + +//just for test +SALOME_ResourcesManager::SALOME_ResourcesManager(const char *xmlFilePath):_path_resources(xmlFilePath) +{ +} + +SALOME_ResourcesManager::SALOME_ResourcesManager() +{ + _path_resources=getenv("KERNEL_ROOT_DIR"); + _path_resources+="/share/salome/resources/CatalogResources.xml"; + ParseXmlFile(); +} + +SALOME_ResourcesManager::~SALOME_ResourcesManager() +{ +} + +vector SALOME_ResourcesManager::GetFittingResources(const Engines::MachineParameters& params,const char *moduleName) throw(SALOME_Exception) +{ + vector ret; + //To be sure that we search in a correct list. + ParseXmlFile(); + const char *hostname=(const char *)params.hostname; + if(hostname[0]!='\0') + { + if(_resourcesList.find(hostname)!=_resourcesList.end()) + // params.hostame is in the list of resources so return it. + ret.push_back(hostname); + else + //user specified an unknown hostame so notify to him. + throw SALOME_Exception("unknown host"); + } + else + // Search for available resources sorted by priority + { + SelectOnlyResourcesWithOS(ret,params.OS); + KeepOnlyResourcesWithModule(ret,moduleName); + //set wanted parameters + ResourceDataToSort::_nbOfNodesWanted=params.nb_node; + ResourceDataToSort::_nbOfProcPerNodeWanted=params.nb_proc_per_node; + ResourceDataToSort::_CPUFreqMHzWanted=params.cpu_clock; + ResourceDataToSort::_memInMBWanted=params.mem_mb; + //end of set + list li; + for(vector::iterator iter=ret.begin();iter!=ret.end();iter++) + li.push_back(_resourcesList[(*iter)].DataForSort); + li.sort(); + unsigned int i=0; + for(list::iterator iter2=li.begin();iter2!=li.end();iter2++) + ret[i++]=(*iter2)._hostName; + } + return ret; +} + +int SALOME_ResourcesManager::AddResourceInCatalog(const Engines::MachineParameters& paramsOfNewResources, const map& modulesOnNewResources, + const char *environPathOfPrerequired, + const char *alias, const char *userName, AccessModeType mode, AccessProtocolType prot) throw(SALOME_Exception) +{ + map::const_iterator iter=modulesOnNewResources.find("KERNEL"); + if(iter!=modulesOnNewResources.end()) + { + ParserResourcesType newElt; + newElt.DataForSort._hostName=paramsOfNewResources.hostname; + newElt.Alias=alias; + newElt.Protocol=prot; + newElt.Mode=mode; + newElt.UserName=userName; + newElt.ModulesPath=modulesOnNewResources; + newElt.PreReqFilePath=environPathOfPrerequired; + newElt.OS=paramsOfNewResources.OS; + newElt.DataForSort._memInMB=paramsOfNewResources.mem_mb; + newElt.DataForSort._CPUFreqMHz=paramsOfNewResources.cpu_clock; + newElt.DataForSort._nbOfNodes=paramsOfNewResources.nb_node; + newElt.DataForSort._nbOfProcPerNode=paramsOfNewResources.nb_proc_per_node; + _resourcesList[newElt.DataForSort._hostName]=newElt; + return 0; + } + else + throw SALOME_Exception("KERNEL is not present in this resource"); +} + +void SALOME_ResourcesManager::DeleteResourceInCatalog(const char *hostname) +{ + _resourcesList.erase(hostname); +} + +void SALOME_ResourcesManager::WriteInXmlFile() +{ + QDomDocument doc("ResourcesCatalog"); + SALOME_ResourcesCatalog_Handler* handler = new SALOME_ResourcesCatalog_Handler(_resourcesList); + handler->PrepareDocToXmlFile(doc); + delete handler; + QFile file( _path_resources ); + if( !file.open( IO_WriteOnly ) ) + cout << "WRITING ERROR !!!" << endl; + + QTextStream ts( &file ); + ts << doc.toString(); + + file.close(); + cout << "WRITING DONE!!!" << endl; +} + +const MapOfParserResourcesType& SALOME_ResourcesManager::ParseXmlFile() +{ + SALOME_ResourcesCatalog_Handler* handler = new SALOME_ResourcesCatalog_Handler(_resourcesList); + QFile xmlFile(_path_resources); + + QXmlInputSource source(xmlFile); + + QXmlSimpleReader reader; + reader.setContentHandler( handler ); + reader.setErrorHandler( handler ); + reader.parse( source ); + xmlFile.close(); + delete handler; + return _resourcesList; +} + +bool SALOME_ResourcesManager::_verify_resources(MapOfParserResourcesType resourceslist) +{ +// bool _return_value = true; +// bool _bool = false ; +// vector _machine_list; +// _machine_list.resize(0); + +// // Fill a list of all computers indicated in the resources list +// for (unsigned int ind = 0; ind < resourceslist.size(); ind++) +// _machine_list.push_back(resourceslist[ind].HostName); + +// // Parse if a computer name is twice in the list of computers +// for (unsigned int ind = 0; ind < _machine_list.size(); ind++) +// { +// for (unsigned int ind1 = ind+1 ; ind1 < _machine_list.size(); ind1++) +// { +// if(_machine_list[ind].compare(_machine_list[ind1]) == 0) +// { +// MESSAGE("The computer " << _machine_list[ind] << " is indicated more than once in the resources list") +// _return_value = false; +// } +// } +// } + +// return _return_value; + return true; +} + +const MapOfParserResourcesType& SALOME_ResourcesManager::GetList() const +{ + return _resourcesList; +} + +string SALOME_ResourcesManager::FindBest(const Engines::MachineList& listOfMachines) +{ + return _dynamicResourcesSelecter.FindBest(listOfMachines); +} + +string SALOME_ResourcesManager::BuildTempFileToLaunchRemoteContainer(const string& machine,const char *containerName) +{ + _TmpFileName=BuildTemporaryFileName(); + ofstream tempOutputFile; + tempOutputFile.open(_TmpFileName.c_str(),ofstream::out ); + const ParserResourcesType& resInfo=_resourcesList[machine]; + tempOutputFile << "#! /bin/sh" << endl; + //set env vars + for(map::const_iterator iter=resInfo.ModulesPath.begin();iter!=resInfo.ModulesPath.end();iter++) + { + string curModulePath((*iter).second); + tempOutputFile << (*iter).first << "_ROOT_DIR="<< curModulePath << endl; + tempOutputFile << "export " << (*iter).first << "_ROOT_DIR" << endl; + tempOutputFile << "LD_LIBRARY_PATH=" << curModulePath << "/lib/salome" << ":${LD_LIBRARY_PATH}" << endl; + tempOutputFile << "PYTHONPATH=" << curModulePath << "/bin/salome:" << curModulePath << "/lib/python2.2/site-packages/salome:"; + tempOutputFile << curModulePath << "/lib/python2.2/site-packages/salome/shared_modules:${PYTHONPATH}" << endl; + } + tempOutputFile << "export LD_LIBRARY_PATH" << endl; + tempOutputFile << "export PYTHONPATH" << endl; + tempOutputFile << "source " << resInfo.PreReqFilePath << endl; + // ! env vars + tempOutputFile << (*(resInfo.ModulesPath.find("KERNEL"))).second << "/bin/salome/"; + if(Engines_Container_i::isPythonContainer(containerName)) + tempOutputFile << "SALOME_ContainerPy.py "; + else + tempOutputFile << "SALOME_Container "; + tempOutputFile << containerName << " -"; + AddOmninamesParams(tempOutputFile); + tempOutputFile << " > /tmp/" << containerName << "_" << machine << ".log 2>&1 &" << endl;//" &" << endl; + //tempOutputFile << "EOF" << endl; + //tempOutputFile << "&" << endl; + tempOutputFile.flush(); + tempOutputFile.close(); + chmod(_TmpFileName.c_str(),0x1ED); + //Build command + string command; + if(resInfo.Protocol==rsh) + { + command = "rsh "; + string commandRcp="rcp "; + commandRcp+=_TmpFileName; + commandRcp+=" "; + commandRcp+=machine; + commandRcp+=":"; + commandRcp+=_TmpFileName; + system(commandRcp.c_str()); + } + else if(resInfo.Protocol==ssh) + command = "ssh "; + else + throw SALOME_Exception("Unknown protocol"); + command+=machine; + _CommandForRemAccess=command; + command+=" "; + command+=_TmpFileName; + command+=" & "; + cout << "Command is ... " << command << endl; + return command; +} + +string SALOME_ResourcesManager::BuildCommandToLaunchLocalContainer(const char *containerName) +{ + _TmpFileName=""; + string command; + if(Engines_Container_i::isPythonContainer(containerName)) + command="SALOME_ContainerPy.py "; + else + command="SALOME_Container "; + command+=containerName; + command+=" -"; + AddOmninamesParams(command); + command+=" > /tmp/"; + command+=containerName; + command += "_"; + command += GetHostname(); + command += ".log 2>&1 &" ; + cout << "Command is ... " << command << endl << flush; + return command; +} + +void SALOME_ResourcesManager::RmTmpFile() +{ + if(_TmpFileName!="") + { + string command="rm "; + command+=_TmpFileName; + system(command.c_str()); + } +} + +string SALOME_ResourcesManager::BuildCommand(const string& machine,const char *containerName) +{ +// rsh -n ikkyo /export/home/rahuel/SALOME_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515 & + const ParserResourcesType& resInfo=_resourcesList[machine]; + bool pyCont=Engines_Container_i::isPythonContainer(containerName); + string command; + if(resInfo.Protocol==rsh) + command = "rsh -n " ; + else if(resInfo.Protocol==ssh) + command = "ssh -f -n "; + else + throw SALOME_Exception("Not implemented yet..."); + command += machine; + command += " "; + string path = (*(resInfo.ModulesPath.find("KERNEL"))).second; + command +=path; + command += "/bin/salome/"; + if ( pyCont ) + command += "SALOME_ContainerPy.py "; + else + command += "SALOME_Container "; + command += containerName; + command += " -"; + AddOmninamesParams(command); + command += " > /tmp/"; + command += containerName; + command += "_"; + command += machine; + command += ".log 2>&1 &" ; + SCRUTE( command ); + return command; +} + +// Warning need an updated parsed list : _resourcesList +void SALOME_ResourcesManager::SelectOnlyResourcesWithOS(vector& hosts,const char *OS) const throw(SALOME_Exception) +{ + string base(OS); + for(map::const_iterator iter=_resourcesList.begin();iter!=_resourcesList.end();iter++) + if((*iter).second.OS==base) + hosts.push_back((*iter).first); +} + +//Warning need an updated parsed list : _resourcesList +void SALOME_ResourcesManager::KeepOnlyResourcesWithModule(vector& hosts,const char *moduleName) const throw(SALOME_Exception) +{ + for(vector::iterator iter=hosts.begin();iter!=hosts.end();iter++) + { + MapOfParserResourcesType::const_iterator it=_resourcesList.find(*iter); + const map& mapOfModulesOfCurrentHost=(((*it).second).ModulesPath); + if(mapOfModulesOfCurrentHost.find(moduleName)==mapOfModulesOfCurrentHost.end()) + { + hosts.erase(iter); + } + } +} + +void SALOME_ResourcesManager::AddOmninamesParams(string& command) const +{ + string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ; + ifstream omniORBfile( omniORBcfg.c_str() ) ; + char ORBInitRef[12] ; + char nameservice[132] ; + omniORBfile >> ORBInitRef ; + command += ORBInitRef ; + command += " " ; + omniORBfile >> nameservice ; + omniORBfile.close() ; + char * bsn = strchr( nameservice , '\n' ) ; + if ( bsn ) { + bsn[ 0 ] = '\0' ; + } + command += nameservice ; +} + +void SALOME_ResourcesManager::AddOmninamesParams(ofstream& fileStream) const +{ + string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ; + ifstream omniORBfile( omniORBcfg.c_str() ) ; + char ORBInitRef[12] ; + char nameservice[132] ; + omniORBfile >> ORBInitRef ; + fileStream << ORBInitRef; + fileStream << " "; + omniORBfile >> nameservice ; + omniORBfile.close() ; + char * bsn = strchr( nameservice , '\n' ) ; + if ( bsn ) { + bsn[ 0 ] = '\0' ; + } + fileStream << nameservice; +} + +string SALOME_ResourcesManager::BuildTemporaryFileName() const +{ + //build more complex file name to support multiple salome session + return "/tmp/command.sh"; +} + + diff --git a/src/ResourcesManager/SALOME_ResourcesManager.hxx b/src/ResourcesManager/SALOME_ResourcesManager.hxx new file mode 100644 index 000000000..c0b6ef385 --- /dev/null +++ b/src/ResourcesManager/SALOME_ResourcesManager.hxx @@ -0,0 +1,99 @@ +#ifndef __SALOME_RESOURCESMANAGER_HXX__ +#define __SALOME_RESOURCESMANAGER_HXX__ + +#include "Utils_SALOME_Exception.hxx" +#include "utilities.h" +#include +#include "SALOME_ResourcesCatalog_Handler.hxx" +#include "SALOME_LoadRateManager.hxx" +#include CORBA_CLIENT_HEADER(SALOME_ContainerManager) +#include +#include +#include + +//WARNING the call of BuildTempFileToLaunchRemoteContainer and RmTmpFile must be done in a critical section to be sure to be clean. +//Only one thread should use the SALOME_ResourcesManager class in a SALOME session. + +class SALOME_ResourcesManager +{ +public: + //! standard constructor + SALOME_ResourcesManager(); + + //!just for test + SALOME_ResourcesManager(const char *xmlFilePath); + + //! standard destructor + ~SALOME_ResourcesManager(); + + //! method to get the list of name of ressources fitting for the specified module. + std::vector GetFittingResources(const Engines::MachineParameters& params,const char *moduleName) throw(SALOME_Exception); + + //! method to dynamically obtain the best machines + std::string FindBest(const Engines::MachineList& listOfMachines); + + //! method that builds in a temporary file the script to be launched + std::string BuildTempFileToLaunchRemoteContainer(const std::string& machine,const char *containerName); + + //! method that builds the command to be launched. + std::string BuildCommandToLaunchLocalContainer(const char *containerName); + + //! method that remove the generated temporary file in case of a remote launch. + void RmTmpFile(); + + //! method that builds the script to be launched + std::string BuildCommand(const std::string& machine,const char *containerName); + + //! add an entry in the ressources catalog xml file. Return 1 if OK. Return 0 if the ressource with the same hostname already exists. + int AddResourceInCatalog(const Engines::MachineParameters& paramsOfNewResources, const std::map& modulesOnNewResources, + const char *environPathOfPrerequired, + const char *alias, const char *userName, AccessModeType mode, AccessProtocolType prot) throw(SALOME_Exception); + + //! delete a ressource from the Catalog. + void DeleteResourceInCatalog(const char *hostname); + + //! write the current data in memory in file. + void WriteInXmlFile(); + + //! method to parse the data type catalog + const MapOfParserResourcesType& ParseXmlFile(); + + //! to consult the content of the list + const MapOfParserResourcesType& GetList() const; + +private: + + //! method to verify ressources catalog content - return true if verfication is OK + bool _verify_resources(MapOfParserResourcesType resourceslist); + + //! method that fill hosts with only resources in xml files that are on the specified OS + void SelectOnlyResourcesWithOS(std::vector& hosts,const char *OS) const throw(SALOME_Exception); + + //! method that keep from hosts only those having component of name moduleName. + void KeepOnlyResourcesWithModule(std::vector& hosts,const char *moduleName) const throw(SALOME_Exception); + + //! methode that add to command all options relative to naming service. + void AddOmninamesParams(std::string& command) const; + + //! method that add to command all options relative to naming service. + void AddOmninamesParams(std::ofstream& fileStream) const; + + //! method that generate a file name in /tmp directory + std::string BuildTemporaryFileName() const; + + // will contain the path to the ressources catalog + QString _path_resources; + + //! attribute that contains current tmp files generated + std::string _TmpFileName; + + //! attribute that contains the rsh or ssh command to access directly to machine. Only used by this->RmTmpFile in case of a remote launch. + std::string _CommandForRemAccess; + + //will contain the informations on the data type catalog(after parsing) + MapOfParserResourcesType _resourcesList; + + SALOME_LoadRateManager _dynamicResourcesSelecter; +}; + +#endif // RESSOURCESCATALOG_IMPL_H diff --git a/src/SALOMEDS/Makefile.in b/src/SALOMEDS/Makefile.in index 41c222733..da674c956 100644 --- a/src/SALOMEDS/Makefile.in +++ b/src/SALOMEDS/Makefile.in @@ -113,14 +113,14 @@ LIB_SRC = \ # Executables targets BIN = SALOMEDS_Server SALOMEDS_Client BIN_SRC = -LIB_SERVER_IDL = SALOMEDS.idl SALOMEDS_Attributes.idl SALOME_Exception.idl +LIB_SERVER_IDL = SALOMEDS.idl SALOMEDS_Attributes.idl SALOME_Exception.idl SALOME_ContainerManager.idl BIN_SERVER_IDL = SALOMEDS.idl SALOMEDS_Attributes.idl BIN_CLIENT_IDL = LIB_CLIENT_IDL = SALOME_Component.idl SALOME_GenericObj.idl CPPFLAGS+=$(OCC_INCLUDES) $(HDF5_INCLUDES) CXXFLAGS+=$(OCC_CXXFLAGS) -LDFLAGS+= $(HDF5_LIBS) -lTOOLSDS -lSalomeNS -lSalomeHDFPersist -lOpUtil -lSALOMELocalTrace $(CAS_LDPATH) -lTKCAF -lTKBO -lTKStdSchema -lSalomeGenericObj -lSalomeLifeCycleCORBA +LDFLAGS+= $(HDF5_LIBS) -lTOOLSDS -lSalomeNS -lSalomeHDFPersist -lOpUtil -lSALOMELocalTrace $(CAS_LDPATH) -lTKCAF -lTKBO -lTKStdSchema -lSalomeGenericObj -lSalomeLifeCycleCORBA -lSalomeContainer -lSalomeResourcesManager -lRegistry -lSalomeNotification -lSALOMETraceCollector # _CS_gbo_090604 Ajout Spécifique Calibre 3, pour l'utilisation de la version 5.12 de la bibliothèque OCC. # La bibliothèque OCC5.12 a été compilée sur Calibre 3 avec l'extention Xmu (impossible de compiler sans). diff --git a/src/SALOMEGUI/Makefile.in b/src/SALOMEGUI/Makefile.in index f3d426d18..d3acbc362 100644 --- a/src/SALOMEGUI/Makefile.in +++ b/src/SALOMEGUI/Makefile.in @@ -218,6 +218,7 @@ LIB_CLIENT_IDL = SALOMEDS.idl \ SALOMEDS_Attributes.idl \ SALOME_ModuleCatalog.idl \ SALOME_Component.idl \ + SALOME_ContainerManager.idl \ SALOME_Exception.idl CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) diff --git a/src/SALOME_PY/Makefile.in b/src/SALOME_PY/Makefile.in index f99d2e4ed..9b8cf7e33 100644 --- a/src/SALOME_PY/Makefile.in +++ b/src/SALOME_PY/Makefile.in @@ -41,6 +41,7 @@ LIB_SRC = SalomePy.cxx LIB_CLIENT_IDL = SALOMEDS.idl \ SALOMEDS_Attributes.idl \ + SALOME_ContainerManager.idl \ SALOME_Exception.idl CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) -DHAVE_CONFIG_H diff --git a/src/SALOME_PYQT/Makefile.in b/src/SALOME_PYQT/Makefile.in index 7c1de51a1..6797d4dbf 100644 --- a/src/SALOME_PYQT/Makefile.in +++ b/src/SALOME_PYQT/Makefile.in @@ -47,7 +47,7 @@ LIB_MOC = SALOME_PYQT_GUI.h EXPORT_SHAREDPYSCRIPTS = SalomePyQt.py -LIB_CLIENT_IDL = SALOME_Exception.idl +LIB_CLIENT_IDL = SALOME_Exception.idl SALOME_ContainerManager.idl CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(SIP_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) LIBS+= $(PYTHON_LIBS) $(SIP_LIBS) $(PYQT_LIBS) $(VTK_LIBS) $(OGL_LIBS) diff --git a/src/SALOME_SWIG_WITHOUTIHM/salome.py b/src/SALOME_SWIG_WITHOUTIHM/salome.py index 2d5ae11cf..7cd1fb0af 100755 --- a/src/SALOME_SWIG_WITHOUTIHM/salome.py +++ b/src/SALOME_SWIG_WITHOUTIHM/salome.py @@ -28,6 +28,7 @@ from omniORB import CORBA from LifeCycleCORBA import * from libSALOME_Swig import * import SALOMEDS +import Engines from SALOME_NamingServicePy import * from SALOME_utilities import * @@ -154,3 +155,7 @@ myStudyManager = obj._narrow(SALOMEDS.StudyManager) # get active study myStudy = myStudyManager.GetStudyByName(myStudyName) + +# get Container Manager +obj = naming_service.Resolve('/ContainerManager') +cm = obj._narrow(Engines.ContainerManager) diff --git a/src/SUPERVGraph/Makefile.in b/src/SUPERVGraph/Makefile.in index 3edb511e4..b108204d7 100644 --- a/src/SUPERVGraph/Makefile.in +++ b/src/SUPERVGraph/Makefile.in @@ -22,6 +22,7 @@ LIB_MOC = SUPERVGraph_moc.cxx \ LIB_CLIENT_IDL = SALOMEDS.idl \ SALOME_ModuleCatalog.idl \ SALOME_Component.idl \ + SALOME_ContainerManager.idl \ SALOME_Exception.idl diff --git a/src/Session/Makefile.in b/src/Session/Makefile.in index 45ce4c82b..3fb121981 100644 --- a/src/Session/Makefile.in +++ b/src/Session/Makefile.in @@ -49,11 +49,11 @@ LIB_SRC=\ BIN = SALOME_Session_Server BIN_SRC = BIN_SERVER_IDL = SALOME_Session.idl -BIN_CLIENT_IDL = SALOMEDS.idl SALOMEDS_Attributes.idl SALOME_Component.idl SALOME_Registry.idl SALOME_ModuleCatalog.idl SALOME_Exception.idl +BIN_CLIENT_IDL = SALOMEDS.idl SALOMEDS_Attributes.idl SALOME_Component.idl SALOME_ContainerManager.idl SALOME_Registry.idl SALOME_ModuleCatalog.idl SALOME_Exception.idl CPPFLAGS+=$(QT_MT_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) $(HDF5_INCLUDES) CXXFLAGS+=$(OCC_CXXFLAGS) -LDFLAGS+=$(QT_MT_LIBS) $(HDF5_LIBS) -lSalomeHDFPersist -lSalomeNS -lSalomeGUI -lSalomeObject -lSalomeLifeCycleCORBA -lqsplitterP -lOpUtil -lPlot2d -lSalomeVTKFilter -lSALOMELocalTrace -lSALOMETraceCollector -lSalomeContainer -lRegistry -lSalomeNotification -lSalomeDS -lTOOLSDS -lSalomeGenericObj -lSalomeCatalog -lEvent -lSalomePrs $(CAS_LDPATH) -lTKBO -lCASCatch +LDFLAGS+=$(QT_MT_LIBS) $(HDF5_LIBS) -lSalomeHDFPersist -lSalomeNS -lSalomeGUI -lSalomeObject -lSalomeLifeCycleCORBA -lqsplitterP -lOpUtil -lPlot2d -lSalomeVTKFilter -lSALOMELocalTrace -lSALOMETraceCollector -lSalomeContainer -lRegistry -lSalomeNotification -lSalomeDS -lTOOLSDS -lSalomeGenericObj -lSalomeCatalog -lEvent -lSalomePrs $(CAS_LDPATH) -lTKBO -lCASCatch -lSalomeResourcesManager @CONCLUDE@ diff --git a/src/Session/Session_ServerLauncher.cxx b/src/Session/Session_ServerLauncher.cxx index 82a8c6733..6b9f4b92e 100644 --- a/src/Session/Session_ServerLauncher.cxx +++ b/src/Session/Session_ServerLauncher.cxx @@ -181,6 +181,17 @@ void Session_ServerLauncher::CheckArgs() void Session_ServerLauncher::ActivateAll() { + + // Always launch ContainerManager + + char** argv = new char* [1]; + argv[0] = "ContainerManager"; + Session_SessionThread* aServerThread2 + = new Session_SessionThread(1, argv, _orb,_root_poa,_GUIMutex,_ServerLaunch); + _serverThreads.push_front(aServerThread2); + + aServerThread2->Init(); + list::iterator itServ; for (itServ = _argServToLaunch.begin(); itServ !=_argServToLaunch.end(); itServ++) { @@ -205,7 +216,7 @@ void Session_ServerLauncher::ActivateAll() // Always launch Session Server int argc=1; - char** argv = new char*[argc]; + argv = new char*[argc]; argv[0] = "Session"; Session_SessionThread* aServerThread = new Session_SessionThread(argc, argv, _orb,_root_poa,_GUIMutex,_ServerLaunch); diff --git a/src/Session/Session_ServerThread.cxx b/src/Session/Session_ServerThread.cxx index a4fb054cc..9fa3e76af 100644 --- a/src/Session/Session_ServerThread.cxx +++ b/src/Session/Session_ServerThread.cxx @@ -33,6 +33,7 @@ #include "Session_ServerThread.hxx" #include "SALOME_Container_i.hxx" +#include "SALOME_ContainerManager.hxx" #include "SALOMEDS_StudyManager_i.hxx" #include "SALOME_ModuleCatalog_impl.hxx" #include "RegistryService.hxx" @@ -50,12 +51,13 @@ using namespace std; -const int Session_ServerThread::NB_SRV_TYP = 5; +const int Session_ServerThread::NB_SRV_TYP = 6; const char* Session_ServerThread::_serverTypes[NB_SRV_TYP] = {"Container", "ModuleCatalog", "Registry", "SALOMEDS", - "Session"}; + "Session", + "ContainerManager"}; //============================================================================= /*! @@ -124,6 +126,7 @@ void Session_ServerThread::Init() case 0: // Container { NamingService_WaitForServerReadiness(_NS,"/Registry"); + NamingService_WaitForServerReadiness(_NS,"/ContainerManager"); ActivateContainer(_argc, _argv); break; } @@ -155,6 +158,12 @@ void Session_ServerThread::Init() ActivateSession(_argc, _argv); break; } + case 5: // Container Manager + { + NamingService_WaitForServerReadiness(_NS,""); + ActivateContainerManager(_argc, _argv); + break; + } default: { ASSERT(0); @@ -324,6 +333,44 @@ void Session_ServerThread::ActivateRegistry(int argc, */ //============================================================================= +void Session_ServerThread::ActivateContainerManager(int argc, + char ** argv) +{ + try + { + PortableServer::POA_var root_poa=PortableServer::POA::_the_root_poa(); + cout << "ActivateContainerManager ......!!!! " << endl; + SALOME_ContainerManager * myContainer + = new SALOME_ContainerManager(_orb); + } + catch(CORBA::SystemException&) + { + INFOS("Caught CORBA::SystemException."); + } + catch(PortableServer::POA::WrongPolicy&) + { + INFOS("Caught CORBA::WrongPolicyException."); + } + catch(PortableServer::POA::ServantAlreadyActive&) + { + INFOS("Caught CORBA::ServantAlreadyActiveException"); + } + catch(CORBA::Exception&) + { + INFOS("Caught CORBA::Exception."); + } + catch(...) + { + INFOS("Caught unknown exception."); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + void Session_ServerThread::ActivateContainer(int argc, char ** argv) { diff --git a/src/Session/Session_ServerThread.hxx b/src/Session/Session_ServerThread.hxx index e67ee7fe8..9293cd4d2 100644 --- a/src/Session/Session_ServerThread.hxx +++ b/src/Session/Session_ServerThread.hxx @@ -58,6 +58,8 @@ protected: char ** argv); void ActivateContainer(int argc, char ** argv); + void ActivateContainerManager(int argc, + char ** argv); virtual void ActivateSession(int argc, char ** argv); diff --git a/src/TOOLSGUI/Makefile.in b/src/TOOLSGUI/Makefile.in index 73a914c7f..d41cb3724 100644 --- a/src/TOOLSGUI/Makefile.in +++ b/src/TOOLSGUI/Makefile.in @@ -51,7 +51,7 @@ LIB_SRC = ToolsGUI.cxx \ LIB_MOC = ToolsGUI_CatalogGeneratorDlg_moc.cxx LIB_CLIENT_IDL = SALOMEDS.idl SALOMEDS_Attributes.idl \ - SALOME_Component.idl SALOME_Exception.idl + SALOME_Component.idl SALOME_ContainerManager.idl SALOME_Exception.idl # additionnal information to compil and link file diff --git a/src/TestContainer/Makefile.in b/src/TestContainer/Makefile.in index b16797b1f..dd0848460 100644 --- a/src/TestContainer/Makefile.in +++ b/src/TestContainer/Makefile.in @@ -45,7 +45,7 @@ LIB_CLIENT_IDL = SALOME_Component.idl SALOME_TestComponent.idl BIN = TestContainer TestLogger BIN_SRC = -LDFLAGS+= -lSalomeNotification -lSalomeNS -lSalomeContainer -lRegistry -lOpUtil -lSALOMELocalTrace -lSALOMETraceCollector +LDFLAGS+= -lSalomeNotification -lSalomeNS -lSalomeContainer -lRegistry -lOpUtil -lSALOMELocalTrace -lSALOMETraceCollector -lSalomeResourcesManager @CONCLUDE@ diff --git a/src/VTKViewer/Makefile.in b/src/VTKViewer/Makefile.in index 46cfdd0ad..f5e06c1ed 100644 --- a/src/VTKViewer/Makefile.in +++ b/src/VTKViewer/Makefile.in @@ -69,6 +69,7 @@ LIB_MOC = \ LIB_CLIENT_IDL = SALOMEDS.idl \ SALOME_ModuleCatalog.idl \ SALOME_Component.idl \ + SALOME_ContainerManager.idl \ SALOME_Exception.idl CPPFLAGS+=$(QT_INCLUDES) $(OGL_INCLUDES) $(VTK_INCLUDES) $(OCC_INCLUDES)