]> SALOME platform Git repositories - modules/kernel.git/blob - src/ResourcesManager/SALOME_ResourcesManager.cxx
Salome HOME
Draft
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesManager.cxx
1 #include "SALOME_ResourcesManager.hxx"
2 #include "SALOME_Container_i.hxx"
3 #include "Utils_ExceptHandlers.hxx"
4 #include "OpUtil.hxx"
5
6 #include <qdom.h>
7
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <fstream>
11 #include <iostream>
12 #include <map>
13
14 #define MAX_SIZE_FOR_HOSTNAME 256;
15
16 using namespace std;
17
18 //just for test
19 SALOME_ResourcesManager::SALOME_ResourcesManager(const char *xmlFilePath):_path_resources(xmlFilePath)
20 {
21 }
22
23 SALOME_ResourcesManager::SALOME_ResourcesManager()
24 {
25   _path_resources=getenv("KERNEL_ROOT_DIR");
26   _path_resources+="/share/salome/resources/CatalogResources.xml";
27   ParseXmlFile();
28 }
29
30 SALOME_ResourcesManager::~SALOME_ResourcesManager()
31 {
32 }
33
34 vector<string> SALOME_ResourcesManager::GetResourcesFitting(const MachineParameters& params,const char *moduleName) throw(SALOME_Exception)
35 {
36   vector <std::string> ret;
37   //To be sure that we search in a correct list.
38   ParseXmlFile();
39   const char *hostname=(const char *)params.hostname;
40   if(hostname[0]!='\0')
41     {
42       if(_resourcesList.find(hostname)!=_resourcesList.end())
43         // params.hostame is in the list of resources so return it.
44         ret.push_back(hostname);
45       else
46         //user specified an unknown hostame so notify to him.
47         throw SALOME_Exception("unknown host");
48     }
49   else
50     // Search for available resources sorted by priority
51     {
52       SelectOnlyResourcesWithOS(ret,params.OS);
53       KeepOnlyResourcesWithModule(ret,moduleName);
54       //set wanted parameters
55       ResourceDataToSort::_nbOfNodesWanted=params.nb_node;
56       ResourceDataToSort::_nbOfProcPerNodeWanted=params.nb_proc_per_node;
57       ResourceDataToSort::_CPUFreqMHzWanted=params.cpu_clock;
58       ResourceDataToSort::_memInMBWanted=params.mem_mb;
59       //end of set
60       list<ResourceDataToSort> li;
61       for(vector<string>::iterator iter=ret.begin();iter!=ret.end();iter++)
62         li.push_back(_resourcesList[(*iter)].DataForSort);
63       li.sort();
64       unsigned int i=0;
65       for(list<ResourceDataToSort>::iterator iter2=li.begin();iter2!=li.end();iter2++)
66         ret[i++]=(*iter2)._hostName;
67     }
68 //     }
69 //   else
70 //     // user don't specify parameters so default behaviour, only localhost returned
71 //     {
72 //       char *hostName=new char[MAX_SIZE_FOR_HOSTNAME];
73 //       gethostname(hostName,MAX_SIZE_FOR_HOSTNAME);
74 //       ret.push_back(hostName);
75 //       delete [] hostName;
76 //     }
77   return ret;
78 }
79
80 int SALOME_ResourcesManager::AddResourceInCatalog(const MachineParameters& paramsOfNewResources, const map<string,string>& modulesOnNewResources,
81                                                   const char *environPathOfPrerequired,
82                                                   const char *alias, const char *userName, AccessModeType mode, AccessProtocolType prot) throw(SALOME_Exception)
83 {
84   map<string,string>::const_iterator iter=modulesOnNewResources.find("KERNEL");
85   if(iter!=modulesOnNewResources.end())
86     {
87       ParserResourcesType newElt;
88       newElt.DataForSort._hostName=paramsOfNewResources.hostname;
89       newElt.Alias=alias;
90       newElt.Protocol=prot;
91       newElt.Mode=mode;
92       newElt.UserName=userName;
93       newElt.ModulesPath=modulesOnNewResources;
94 //       for(int i=0;i<modulesOnNewResources.size();i++)
95 //      newElt.ModulesPath[modulesOnNewResources[i]]=pathOfModulesOnNewResources[i];
96       newElt.PreReqFilePath=environPathOfPrerequired;
97       newElt.OS=paramsOfNewResources.OS;
98       newElt.DataForSort._memInMB=paramsOfNewResources.mem_mb;
99       newElt.DataForSort._CPUFreqMHz=paramsOfNewResources.cpu_clock;
100       newElt.DataForSort._nbOfNodes=paramsOfNewResources.nb_node;
101       newElt.DataForSort._nbOfProcPerNode=paramsOfNewResources.nb_proc_per_node;
102       _resourcesList[newElt.DataForSort._hostName]=newElt;
103       cout << "AddResourceInCatalog ... " << _resourcesList.size() << endl;
104       return 0;
105     }
106   else
107     throw SALOME_Exception("KERNEL is not present in this resource");
108 }
109
110 void SALOME_ResourcesManager::DeleteResourceInCatalog(const char *hostname)
111 {
112   _resourcesList.erase(hostname);
113 }
114
115 void SALOME_ResourcesManager::WriteInXmlFile()
116 {
117   QDomDocument doc("ResourcesCatalog");
118   SALOME_ResourcesCatalog_Handler* handler = new SALOME_ResourcesCatalog_Handler(_resourcesList);
119   handler->PrepareDocToXmlFile(doc);
120   delete handler;
121   QFile file( _path_resources );
122   if( !file.open( IO_WriteOnly ) )
123     cout << "WRITING ERROR !!!" << endl;
124     //return -1;
125
126   QTextStream ts( &file );
127   ts << doc.toString();
128
129   file.close();
130   cout << "WRITING DONE!!!" << endl;
131 }
132
133 const MapOfParserResourcesType& SALOME_ResourcesManager::ParseXmlFile() 
134 {
135   SALOME_ResourcesCatalog_Handler* handler = new SALOME_ResourcesCatalog_Handler(_resourcesList);
136   QFile xmlFile(_path_resources);
137
138   QXmlInputSource source(xmlFile);
139
140   QXmlSimpleReader reader;
141   reader.setContentHandler( handler );
142   reader.setErrorHandler( handler );
143   reader.parse( source );
144   xmlFile.close();
145   delete handler;
146   return _resourcesList;
147 }
148
149 bool SALOME_ResourcesManager::_verify_resources(MapOfParserResourcesType resourceslist)
150 {
151 //     bool _return_value = true;
152 //     bool _bool = false ;
153 //     vector<string> _machine_list;
154 //     _machine_list.resize(0);
155
156 //   // Fill a list of all computers indicated in the resources list
157 //   for (unsigned int ind = 0; ind < resourceslist.size(); ind++)
158 //           _machine_list.push_back(resourceslist[ind].HostName);   
159
160 //   // Parse if a computer name is twice in the list of computers
161 //   for (unsigned int ind = 0; ind < _machine_list.size(); ind++)
162 //     {
163 //      for (unsigned int ind1 = ind+1 ; ind1 < _machine_list.size(); ind1++)
164 //        {
165 //          if(_machine_list[ind].compare(_machine_list[ind1]) == 0)
166 //            {
167 //              MESSAGE("The computer " << _machine_list[ind] << " is indicated more than once in the resources list")
168 //              _return_value = false;
169 //           }
170 //        }
171 //     }
172
173 //    return _return_value;
174   return true;
175 }
176
177 const MapOfParserResourcesType& SALOME_ResourcesManager::GetList() const
178 {
179   return _resourcesList;
180 }
181
182 string SALOME_ResourcesManager::FindBest(const MachineList& listOfMachines)
183 {
184   return _dynamicResourcesSelecter.FindBest(listOfMachines);
185 }
186
187 string SALOME_ResourcesManager::BuildTempFileToLaunchRemoteContainer(const string& machine,const char *containerName)
188 {
189   _TmpFileName=BuildTemporaryFileName();
190   ofstream tempOutputFile(_TmpFileName.c_str());
191   const ParserResourcesType& resInfo=_resourcesList[machine];
192   tempOutputFile << "/bin/sh <<EOF" << endl;
193   //set env vars
194   for(map<string,string>::const_iterator iter=resInfo.ModulesPath.begin();iter!=resInfo.ModulesPath.end();iter++)
195     {
196       string curModulePath((*iter).second);
197       tempOutputFile << "export " << (*iter).first << "_ROOT_DIR="<< curModulePath << endl;
198       tempOutputFile << "export LD_LIBRARY_PATH=" << curModulePath << "/lib/salome" << ":${LD_LIBRARY_PATH}" << endl;
199       tempOutputFile << "export PYTHONPATH=" << curModulePath << "/bin/salome:" << curModulePath << "/lib/python2.2/site-packages/salome:";
200       tempOutputFile << curModulePath << "/lib/python2.2/site-packages/salome/shared_modules:${PYTHONPATH}" << endl;
201     }
202   tempOutputFile << "source " << resInfo.PreReqFilePath << endl;
203   // ! env vars
204   tempOutputFile << (*(resInfo.ModulesPath.find("KERNEL"))).second << "/bin/salome/";
205   if(Engines_Container_i::isPythonContainer(containerName))
206     tempOutputFile << "SALOME_ContainerPy.py ";
207   else
208     tempOutputFile << "SALOME_Container ";
209   tempOutputFile << containerName << " -";
210   AddOmninamesParams(tempOutputFile);
211   tempOutputFile << " > /tmp/" << containerName << "_" << machine << ".log 2>&1 &" << endl;
212   tempOutputFile << "EOF" << endl;
213   tempOutputFile.flush();
214   tempOutputFile.close();
215   //Build command
216   string command;
217   if(resInfo.Protocol==rsh)
218     command = "rsh -n ";
219   else if(resInfo.Protocol==ssh)
220     command = "ssh -n ";
221   else
222     throw SALOME_Exception("Unknown protocol");
223   command+=machine;
224   _CommandForRemAccess=command;
225   command+=" < ";
226   command+=_TmpFileName;
227   return command;
228 }
229
230 string SALOME_ResourcesManager::BuildCommandToLaunchLocalContainer(const char *containerName)
231 {
232   _TmpFileName="";
233   string command;
234   if(Engines_Container_i::isPythonContainer(containerName))
235     command="SALOME_ContainerPy.py ";
236   else
237     command="SALOME_Container ";
238   command+=containerName;
239   command+=" -";
240   AddOmninamesParams(command);
241   command+=" > /tmp/";
242   command+=containerName;
243   command += "_";
244   command += GetHostname();
245   command += ".log 2>&1 &" ;
246   return command;
247 }
248
249 void SALOME_ResourcesManager::RmTmpFile()
250 {
251   if(_TmpFileName!="")
252     {
253       string command="rm ";
254       command+=_TmpFileName;
255       system(command.c_str());
256     }
257 }
258
259 string SALOME_ResourcesManager::BuildCommand(const string& machine,const char *containerName)
260 {
261 // rsh -n ikkyo /export/home/rahuel/SALOME_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515 &
262   const ParserResourcesType& resInfo=_resourcesList[machine];
263   bool pyCont=Engines_Container_i::isPythonContainer(containerName);
264   string command;
265   if(resInfo.Protocol==rsh)
266     command = "rsh -n " ;
267   else if(resInfo.Protocol==ssh)
268     command = "ssh -f -n ";
269   else
270     throw SALOME_Exception("Not implemented yet...");
271       command += machine;
272   command += " ";
273   string path = (*(resInfo.ModulesPath.find("KERNEL"))).second;
274   command +=path;
275   command += "/bin/salome/";
276   if ( pyCont )
277     command += "SALOME_ContainerPy.py ";
278   else
279     command += "SALOME_Container ";
280   command += containerName;
281   command += " -";
282   AddOmninamesParams(command);
283   command += " > /tmp/";
284   command += containerName;
285   command += "_";
286   command += machine;
287   command += ".log 2>&1 &" ;
288   SCRUTE( command );
289   return command;
290 //     int status = system( command.c_str() ) ;
291 //     if (status == -1) {
292 //       MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status -1)") ;
293 //       }
294 //       else if (status == 217) {
295 //         MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status 217)") ;
296 //       }
297 //       else {
298 //         int count = 21 ;
299 //         while ( CORBA::is_nil( aFactoryServer ) && count ) {
300 //           sleep( 1 ) ;
301 //           count-- ;
302 //           if ( count != 10 )
303 //             MESSAGE( count << ". Waiting for FactoryServer on " << machine)
304 //           aFactoryServer = FindContainer( FactoryServer.c_str() ) ;
305 //      }
306 //         if ( CORBA::is_nil( aFactoryServer ) ) {
307 //           MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed") ;
308 //      }
309 //         else if ( strcmp( theComputer.c_str() , GetHostname().c_str() ) ) {
310 //           _FactoryServer = aFactoryServer ;
311 //      }
312 //       }
313 }
314
315 // Warning need an updated parsed list : _resourcesList
316 void SALOME_ResourcesManager::SelectOnlyResourcesWithOS(vector<string>& hosts,const char *OS) const throw(SALOME_Exception)
317 {
318   string base(OS);
319   for(map<string, ParserResourcesType>::const_iterator iter=_resourcesList.begin();iter!=_resourcesList.end();iter++)
320     if((*iter).second.OS==base)
321       hosts.push_back((*iter).first);
322 }
323
324 //Warning need an updated parsed list : _resourcesList
325 void SALOME_ResourcesManager::KeepOnlyResourcesWithModule(vector<string>& hosts,const char *moduleName) const throw(SALOME_Exception)
326 {
327    for(vector<string>::iterator iter=hosts.begin();iter!=hosts.end();iter++)
328      {
329        MapOfParserResourcesType::const_iterator it=_resourcesList.find(*iter);
330        const map<string,string>& mapOfModulesOfCurrentHost=(((*it).second).ModulesPath);
331        if(mapOfModulesOfCurrentHost.find(moduleName)==mapOfModulesOfCurrentHost.end())
332          {
333            hosts.erase(iter);
334          }
335      }
336 }
337
338 void SALOME_ResourcesManager::AddOmninamesParams(string& command) const
339 {
340   string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ;
341   ifstream omniORBfile( omniORBcfg.c_str() ) ;
342   char ORBInitRef[12] ;
343   char nameservice[132] ;
344   omniORBfile >> ORBInitRef ;
345   command += ORBInitRef ;
346   command += " " ;
347   omniORBfile >> nameservice ;
348   omniORBfile.close() ;
349   char * bsn = strchr( nameservice , '\n' ) ;
350   if ( bsn ) {
351     bsn[ 0 ] = '\0' ;
352   }
353   command += nameservice ;
354 }
355
356 void SALOME_ResourcesManager::AddOmninamesParams(ofstream& fileStream) const
357 {
358   string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ;
359   ifstream omniORBfile( omniORBcfg.c_str() ) ;
360   char ORBInitRef[12] ;
361   char nameservice[132] ;
362   omniORBfile >> ORBInitRef ;
363   fileStream << ORBInitRef;
364   fileStream << " ";
365   omniORBfile >> nameservice ;
366   omniORBfile.close() ;
367   char * bsn = strchr( nameservice , '\n' ) ;
368   if ( bsn ) {
369     bsn[ 0 ] = '\0' ;
370   }
371   fileStream << nameservice;
372 }
373
374 string SALOME_ResourcesManager::BuildTemporaryFileName() const
375 {
376   //build more complex file name to support multiple salome session
377   return "/tmp/command.sh";
378 }
379
380