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