1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "SalomeContainerTools.hxx"
21 #include "SALOME_LifeCycleCORBA.hxx"
22 #include "SALOME_NamingService.hxx"
23 #include "SALOME_ResourcesManager.hxx"
24 #include "SALOME_ContainerManager.hxx"
25 #include "Container.hxx"
26 #include "AutoLocker.hxx"
28 #include "YacsTrace.hxx"
30 #include "ServiceNode.hxx"
31 #include "ComponentInstance.hxx"
32 #include "SalomeContainerHelper.hxx"
33 #include "SalomeHPContainerTools.hxx"
34 #include "RuntimeSALOME.hxx"
35 #include "Exception.hxx"
41 #define getpid _getpid
44 using namespace YACS::ENGINE;
47 * \param [in] compoNames
48 * \param [in,out] shutdownLevel
50 void SalomeContainerToolsBase::Start(const std::vector<std::string>& compoNames, SalomeContainerHelper *schelp, SalomeContainerToolsBase& sct, int& shutdownLevel, const Container *cont, const Task *askingNode)
52 CORBA::ORB_ptr orb(getSALOMERuntime()->getOrb());
53 SALOME_NamingService ns;
58 catch(SALOME_Exception& e)
60 throw Exception("SalomeContainer::start : Unable to contact the SALOME Naming Service");
62 CORBA::Object_var obj(ns.Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS));
63 Engines::ContainerManager_var contManager(Engines::ContainerManager::_narrow(obj));
66 std::string str(sct.getNotNullContainerName(cont,askingNode,isEmptyName));
67 DEBTRACE("SalomeContainer::start " << str <<";"<< sct.getHostName() <<";"<< schelp->getType());
69 // Finalize parameters with components found in the container
71 for(std::vector<std::string>::const_iterator iter=compoNames.begin();iter!=compoNames.end();iter++)
72 sct.addToComponentList(*iter);
74 Engines::ContainerParameters myparams(sct.getParameters());
76 std::string dftLauchMode(schelp->getDftLaunchMode());
77 myparams.mode=CORBA::string_dup(dftLauchMode.c_str());
80 //If a container_name is given try to find an already existing container in naming service
81 //If not found start a new container with the given parameters
82 if (dynamic_cast<SalomeContainerMonoHelper *>(schelp) && !isEmptyName)
84 myparams.mode=CORBA::string_dup("getorstart");
91 //sct.setContainerName(str);
92 SetContainerNameOf(myparams,str);
93 Engines::Container_var trueCont(Engines::Container::_nil());
94 if(!isEmptyName && shutdownLevel==999)
96 //Make this only the first time start is called (_shutdownLevel==999)
97 //If the container is named, first try to get an existing container
98 //If there is an existing container use it and set the shutdown level to 3
99 //If there is no existing container, try to launch a new one and set the shutdown level to 2
103 trueCont=contManager->GiveContainer(myparams);
105 catch( const SALOME::SALOME_Exception& ex )
107 std::string msg="SalomeContainer::start : no existing container : ";
109 msg += ex.details.text.in();
116 if(!CORBA::is_nil(trueCont))
119 DEBTRACE( "container found: " << str << " " << _shutdownLevel );
124 myparams.mode="start";
125 DEBTRACE( "container not found: " << str << " " << _shutdownLevel);
129 if(CORBA::is_nil(trueCont))
132 // --- GiveContainer is used in batch mode to retreive launched containers,
133 // and is equivalent to StartContainer when not in batch.
134 trueCont=contManager->GiveContainer(myparams);
136 catch( const SALOME::SALOME_Exception& ex )
138 std::string msg="SalomeContainer::start : Unable to launch container in Salome : ";
140 msg += ex.details.text.in();
141 throw Exception(msg);
143 catch(CORBA::COMM_FAILURE&)
145 throw Exception("SalomeContainer::start : Unable to launch container in Salome : CORBA Comm failure detected");
147 catch(CORBA::Exception&)
149 throw Exception("SalomeContainer::start : Unable to launch container in Salome : Unexpected CORBA failure detected");
152 if(CORBA::is_nil(trueCont))
153 throw Exception("SalomeContainer::start : Unable to launch container in Salome. Check your CatalogResources.xml file");
155 schelp->setContainer(askingNode,trueCont);
157 CORBA::String_var containerName(trueCont->name()),hostName(trueCont->getHostName());
158 std::cerr << "SalomeContainer launched : " << containerName << " " << hostName << " " << trueCont->getPID() << std::endl;
161 CORBA::Object_ptr SalomeContainerToolsBase::LoadComponent(SalomeContainerHelper *launchModeType, Container *cont, Task *askingNode)
163 DEBTRACE("SalomeContainer::loadComponent ");
164 const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
166 YACS::BASES::AutoLocker<Container> alck(cont);//To be sure
167 if(!cont->isAlreadyStarted(askingNode))
168 cont->start(askingNode);
171 throw Exception("SalomeContainerTools::LoadComponent : no instance of component in the task requesting for a load of its component !");
172 CORBA::Object_ptr objComponent=CORBA::Object::_nil();
174 YACS::BASES::AutoLocker<Container> alck(cont);//To be sure
175 std::string compoName(inst->getCompoName());
176 Engines::Container_var container(launchModeType->getContainer(askingNode));
179 bool isLoadable(container->load_component_Library(compoName.c_str(), reason));
181 objComponent=CreateComponentInstance(cont,container,inst);
186 CORBA::Object_ptr SalomeContainerToolsBase::CreateComponentInstance(Container *cont, Engines::Container_ptr contPtr, const ComponentInstance *inst)
189 throw Exception("SalomeContainerTools::CreateComponentInstance : no instance of component in the task requesting for a load of its component !");
191 std::string compoName(inst->getCompoName());
192 CORBA::Object_ptr objComponent=CORBA::Object::_nil();
194 Proc* p(cont->getProc());
197 std::string value(p->getProperty("DefaultStudyID"));
199 studyid= atoi(value.c_str());
201 // prepare component instance properties
202 Engines::FieldsDict_var env(new Engines::FieldsDict);
203 std::map<std::string, std::string> properties(inst->getProperties());
206 std::map<std::string,std::string> procMap=p->getProperties();
207 properties.insert(procMap.begin(),procMap.end());
210 std::map<std::string, std::string>::const_iterator itm;
211 env->length(properties.size());
213 for(itm = properties.begin(); itm != properties.end(); ++itm, item++)
215 DEBTRACE("envname="<<itm->first<<" envvalue="<< itm->second);
216 env[item].key= CORBA::string_dup(itm->first.c_str());
217 env[item].value <<= itm->second.c_str();
220 objComponent=contPtr->create_component_instance_env(compoName.c_str(), env, reason);
221 if(CORBA::is_nil(objComponent))
223 std::string text="Error while trying to create a new component: component '"+ compoName;
224 text=text+"' is not installed or it's a wrong name";
227 CORBA::string_free(reason);
228 throw Exception(text);
233 std::string SalomeContainerToolsBase::GetPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
235 if(cont->isAlreadyStarted(askingNode))
237 Engines::Container_var container(launchModeType->getContainer(askingNode));
238 const char *what="/";
239 CORBA::String_var corbaStr(container->name());
240 std::string ret(corbaStr);
243 std::string::size_type i=ret.find_first_of(what,0);
244 i=ret.find_first_of(what, i==std::string::npos ? i:i+1);
245 if(i!=std::string::npos)
246 return ret.substr(i+1);
250 return "Not placed yet !!!";
253 std::string SalomeContainerToolsBase::GetFullPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
255 if(cont->isAlreadyStarted(askingNode))
257 Engines::Container_var container(launchModeType->getContainer(askingNode));
260 CORBA::String_var corbaStr(container->name());
261 std::string ret(corbaStr);
266 return "Unknown_placement";
270 return "Not_placed_yet";
273 void SalomeContainerToolsBase::SetContainerNameOf(Engines::ContainerParameters& params, const std::string& name)
275 params.container_name=CORBA::string_dup(name.c_str());
279 /////////////////////////////////
281 SalomeContainerToolsInter::SalomeContainerToolsInter(const SalomeContainerToolsInter& other):_propertyMap(other._propertyMap)
285 void SalomeContainerToolsInter::clearProperties()
287 _propertyMap.clear();
290 std::string SalomeContainerToolsInter::getProperty(const std::string& name) const
292 std::map<std::string,std::string>::const_iterator it(_propertyMap.find(name));
293 if(it!=_propertyMap.end())
296 return std::string();
299 std::map<std::string,std::string> SalomeContainerToolsInter::getResourceProperties(const std::string& name) const
301 std::map<std::string,std::string> properties;
303 YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
304 CORBA::ORB_ptr orb = runTime->getOrb();
305 if (!orb) return properties;
306 SALOME_NamingService namingService(orb);
307 SALOME_LifeCycleCORBA lcc(&namingService);
308 CORBA::Object_var obj = namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS);
309 if (CORBA::is_nil(obj))
311 Engines::ResourcesManager_var resManager = Engines::ResourcesManager::_narrow(obj);
312 if (CORBA::is_nil(resManager))
315 std::ostringstream value;
316 Engines::ResourceDefinition_var resource_definition = resManager->GetResourceDefinition(name.c_str());
317 properties["hostname"]=resource_definition->hostname.in();
318 properties["OS"]=resource_definition->OS.in();
319 value.str(""); value << resource_definition->mem_mb;
320 properties["mem_mb"]=value.str();
321 value.str(""); value << resource_definition->cpu_clock;
322 properties["cpu_clock"]=value.str();
323 value.str(""); value << resource_definition->nb_node;
324 properties["nb_node"]=value.str();
325 value.str(""); value << resource_definition->nb_proc_per_node;
326 properties["nb_proc_per_node"]=value.str();
328 properties["component_list"]="";
329 for(CORBA::ULong i=0; i < resource_definition->componentList.length(); i++)
332 properties["component_list"]=properties["component_list"]+",";
333 properties["component_list"]=properties["component_list"]+resource_definition->componentList[i].in();
339 ////////////////////////
341 SalomeContainerTools::SalomeContainerTools()
343 /* Init ContainerParameters */
344 SALOME_LifeCycleCORBA::preSet(_params);
347 SalomeContainerTools::SalomeContainerTools(const SalomeContainerTools& other):SalomeContainerToolsInter(other),_params(other._params)
351 int SalomeContainerTools::getNumberOfCoresPerWorker() const
353 return _params.resource_params.nb_proc_per_node;
356 void SalomeContainerTools::clearProperties()
358 SalomeContainerToolsInter::clearProperties();
359 _params=Engines::ContainerParameters();
362 void SalomeContainerTools::setProperty(const std::string& name, const std::string& value)
364 //DEBTRACE("SalomeContainer::setProperty : " << name << " ; " << value);
366 if (name == "container_name")
367 _params.container_name = CORBA::string_dup(value.c_str());
368 else if (name == "workingdir")
369 _params.workingdir = CORBA::string_dup(value.c_str());
370 else if (name == "nb_parallel_procs")
372 std::istringstream iss(value);
373 if (!(iss >> _params.nb_proc))
374 throw Exception("salomecontainer::setproperty : params.nb_proc value not correct : " + value);
376 else if (name == "isMPI")
379 _params.isMPI = true;
380 else if (value == "false")
381 _params.isMPI = false;
383 throw Exception("SalomeContainer::setProperty : params.isMPI value not correct : " + value);
385 else if (name == "parallelLib")
386 _params.parallelLib = CORBA::string_dup(value.c_str());
389 else if (name == "name")
390 _params.resource_params.name = CORBA::string_dup(value.c_str());
391 else if (name == "hostname")
392 _params.resource_params.hostname = CORBA::string_dup(value.c_str());
393 else if (name == "OS")
394 _params.resource_params.OS = CORBA::string_dup(value.c_str());
395 else if (name == "nb_resource_procs")
397 std::istringstream iss(value);
398 if (!(iss >> _params.resource_params.nb_proc))
399 throw Exception("salomecontainer::setproperty : params.resource_params.nb_proc value not correct : " + value);
401 else if (name == "mem_mb")
403 std::istringstream iss(value);
404 if (!(iss >> _params.resource_params.mem_mb))
405 throw Exception("salomecontainer::setproperty : params.resource_params.mem_mb value not correct : " + value);
407 else if (name == "cpu_clock")
409 std::istringstream iss(value);
410 if (!(iss >> _params.resource_params.cpu_clock))
411 throw Exception("salomecontainer::setproperty : params.resource_params.cpu_clock value not correct : " + value);
413 else if (name == "nb_node")
415 std::istringstream iss(value);
416 if (!(iss >> _params.resource_params.nb_node))
417 throw Exception("salomecontainer::setproperty : params.nb_node value not correct : " + value);
419 else if (name == "nb_proc_per_node")
421 std::istringstream iss(value);
422 if (!(iss >> _params.resource_params.nb_proc_per_node))
423 throw Exception("salomecontainer::setproperty : params.nb_proc_per_node value not correct : " + value);
425 else if (name == "policy")
426 _params.resource_params.policy = CORBA::string_dup(value.c_str());
427 else if (name == "component_list")
429 std::string clean_value(value);
431 // Step 1: remove blanks
432 while(clean_value.find(" ") != std::string::npos)
433 clean_value = clean_value.erase(clean_value.find(" "), 1);
435 // Step 2: get values
436 while(!clean_value.empty())
438 std::string result("");
439 std::string::size_type loc = clean_value.find(",", 0);
440 if (loc != std::string::npos)
442 result = clean_value.substr(0, loc);
443 clean_value = clean_value.erase(0, loc+1);
447 result = clean_value;
450 if (result != "," && result != "")
452 addToComponentList(result);
457 else if (name == "resource_list")
459 std::string clean_value(value);
461 // Step 1: remove blanks
462 while(clean_value.find(" ") != std::string::npos)
463 clean_value = clean_value.erase(clean_value.find(" "), 1);
465 // Step 2: get values
466 while(!clean_value.empty())
468 std::string result("");
469 std::string::size_type loc = clean_value.find(",", 0);
470 if (loc != std::string::npos)
472 result = clean_value.substr(0, loc);
473 clean_value = clean_value.erase(0, loc+1);
477 result = clean_value;
480 if (result != "," && result != "")
482 addToResourceList(result);
487 _propertyMap[name]=value;
490 void SalomeContainerTools::addToComponentList(const std::string& name)
492 // Search if name is already in the list
493 for (CORBA::ULong i = 0; i < _params.resource_params.componentList.length(); i++)
495 std::string component_name = _params.resource_params.componentList[i].in();
496 if (component_name == name)
500 CORBA::ULong lgth = _params.resource_params.componentList.length();
501 _params.resource_params.componentList.length(lgth + 1);
502 _params.resource_params.componentList[lgth] = CORBA::string_dup(name.c_str());
505 void SalomeContainerTools::addToResourceList(const std::string& name)
507 // Search if name is already in the list
508 for (CORBA::ULong i = 0; i < _params.resource_params.resList.length(); i++)
510 std::string component_name = _params.resource_params.resList[i].in();
511 if (component_name == name)
515 CORBA::ULong lgth = _params.resource_params.resList.length();
516 _params.resource_params.resList.length(lgth + 1);
517 _params.resource_params.resList[lgth] = CORBA::string_dup(name.c_str());
520 std::string SalomeContainerTools::getContainerName() const
522 return std::string(_params.container_name);
525 void SalomeContainerTools::setContainerName(const std::string& name)
527 SetContainerNameOf(_params,name);
530 std::string SalomeContainerTools::getHostName() const
532 return std::string(_params.resource_params.hostname);
535 std::string SalomeContainerTools::getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const
538 std::string name(_params.container_name);
546 //give a almost unique name to the container : Pid_Name_Addr
547 std::ostringstream stream;
550 stream << contPtr->getName();
552 stream << contPtr->getDiscreminantStrOfThis(askingNode);
557 //////////////////////////
559 std::string SalomeContainerToolsDecoratorBase::getProperty(const std::string& name) const
561 return _sct->getProperty(name);
564 void SalomeContainerToolsDecoratorBase::setProperty(const std::string& name, const std::string& value)
566 _sct->setProperty(name,value);
569 const std::map<std::string,std::string>& SalomeContainerToolsDecoratorBase::getProperties() const
571 return _sct->getProperties();
574 void SalomeContainerToolsDecoratorBase::clearProperties()
576 _sct->clearProperties();
579 std::map<std::string,std::string> SalomeContainerToolsDecoratorBase::getResourceProperties(const std::string& name) const
581 return _sct->getResourceProperties(name);
584 void SalomeContainerToolsDecoratorBase::addToComponentList(const std::string& name)
586 _sct->addToComponentList(name);
589 void SalomeContainerToolsDecoratorBase::addToResourceList(const std::string& name)
591 _sct->addToResourceList(name);
594 Engines::ContainerParameters SalomeContainerToolsDecoratorBase::getParameters() const
596 return _sct->getParameters();
599 std::string SalomeContainerToolsDecoratorBase::getContainerName() const
601 return _sct->getContainerName();
604 void SalomeContainerToolsDecoratorBase::setContainerName(const std::string& name)
606 _sct->setContainerName(name);
609 std::string SalomeContainerToolsDecoratorBase::getHostName() const
611 return _sct->getHostName();
615 std::string SalomeContainerToolsDecoratorBase::getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const
617 return _sct->getNotNullContainerName(contPtr,askingNode,isEmpty);
620 //////////////////////////////
622 Engines::ContainerParameters SalomeContainerToolsSpreadOverTheResDecorator::getParameters() const
624 Engines::ContainerParameters ret(getWorker()->getParameters());
625 std::string st(ret.resource_params.hostname);
628 int nbProcPerNode(ret.resource_params.nb_proc_per_node);
629 std::size_t iPos(_vh->locateTask(_node)),nPos(_vh->size());
630 if(_vh->size()!=_pg->getNumberOfWorkers(nbProcPerNode))
631 throw YACS::Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Internal error !");
632 std::string zeMachine(_pg->deduceMachineFrom(iPos,nbProcPerNode));
633 ret.resource_params.hostname=CORBA::string_dup(zeMachine.c_str());