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