Salome HOME
PR: resource list of machines must contain actual hostname, not only localhost
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesCatalog_Handler.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  SALOME ResourcesCatalog : implementation of catalog resources parsing (SALOME_ModuleCatalog.idl)
23 //  File   : SALOME_ResourcesCatalog_Handler.cxx
24 //  Author : Estelle Deville
25 //  Module : SALOME
26 //$Header$
27 //
28 #include "SALOME_ResourcesCatalog_Handler.hxx"
29 #include "Basics_Utils.hxx"
30 #include <iostream>
31 #include <map>
32
33 using namespace std;
34
35 //=============================================================================
36 /*!
37  *  Constructor
38  *  \param listOfResources: map of ParserResourcesType to fill when parsing
39  */ 
40 //=============================================================================
41
42 SALOME_ResourcesCatalog_Handler::
43 SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& resources_list,
44                                 MapOfParserResourcesType& resources_batch_list):
45     _resources_list(resources_list),
46     _resources_batch_list(resources_batch_list)
47 {
48   //XML tags initialisation
49   test_machine = "machine";
50   test_resources = "resources";
51
52   test_hostname = "hostname";
53   test_alias = "alias";
54   test_protocol = "protocol";
55   test_mode = "mode";
56   test_batch = "batch";
57   test_mpi = "mpi";
58   test_user_name = "userName";
59   test_appli_path = "appliPath";
60   test_modules = "modules";
61   test_module_name = "moduleName";
62   test_os = "OS";
63   test_mem_in_mb = "memInMB";
64   test_cpu_freq_mhz = "CPUFreqMHz";
65   test_nb_of_nodes = "nbOfNodes";
66   test_nb_of_proc_per_node = "nbOfProcPerNode";
67   test_batch_queue = "batchQueue";
68   test_user_commands = "userCommands";
69 }
70
71 //=============================================================================
72 /*!
73  *  Destructor
74  */ 
75 //=============================================================================
76
77 SALOME_ResourcesCatalog_Handler::~SALOME_ResourcesCatalog_Handler()
78 {
79   //  cout << "SALOME_ResourcesCatalog_Handler destruction") << endl;
80 }
81
82 //=============================================================================
83 /*!
84  *  Retrieves DS after the file parse.
85  */ 
86 //=============================================================================
87
88 const MapOfParserResourcesType&
89 SALOME_ResourcesCatalog_Handler::GetResourcesAfterParsing() const
90 {
91   return _resources_list;
92 }
93
94 //=============================================================================
95 /*!
96  *  Processes XML document and fills the list of resources
97  */ 
98 //=============================================================================
99
100 void SALOME_ResourcesCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc)
101 {
102   // Empty private elements
103   _resources_list.clear();
104
105   // Get the document root node
106   xmlNodePtr aCurNode = xmlDocGetRootElement(theDoc);
107
108   aCurNode = aCurNode->xmlChildrenNode;
109   
110   // Processing the document nodes
111   while(aCurNode != NULL)
112     {
113       if ( !xmlStrcmp(aCurNode->name,(const xmlChar*)test_machine) )
114         {
115           _resource.Clear();
116           if (xmlHasProp(aCurNode, (const xmlChar*)test_hostname))
117             {
118               xmlChar* hostname = xmlGetProp(aCurNode, (const xmlChar*)test_hostname);
119               _resource.DataForSort._hostName = (const char*)hostname;
120               _resource.HostName = (const char*)hostname;
121               xmlFree(hostname);
122             }
123           else
124             break;
125
126           if (xmlHasProp(aCurNode, (const xmlChar*)test_alias))
127             {
128               xmlChar* alias = xmlGetProp(aCurNode, (const xmlChar*)test_alias);
129               _resource.Alias = (const char*)alias;
130               xmlFree(alias);
131             }
132           else
133             _resource.Alias = "";
134
135           if (xmlHasProp(aCurNode, (const xmlChar*)test_batch_queue))
136             {
137               xmlChar* batch_queue = xmlGetProp(aCurNode, (const xmlChar*)test_batch_queue);
138               _resource.batchQueue = (const char*)batch_queue;
139               xmlFree(batch_queue);
140             }
141           else
142             _resource.batchQueue = "";
143
144           if (xmlHasProp(aCurNode, (const xmlChar*)test_user_commands))
145             {
146               xmlChar* user_commands= xmlGetProp(aCurNode, (const xmlChar*)test_user_commands);
147               _resource.userCommands = (const char*)user_commands;
148               xmlFree(user_commands);
149             }
150           else
151             _resource.userCommands = "";
152           
153           if (xmlHasProp(aCurNode, (const xmlChar*)test_protocol))
154             {
155               xmlChar* protocol= xmlGetProp(aCurNode, (const xmlChar*)test_protocol);
156               switch ( protocol[0])
157                 {
158                 case 'r':
159                   _resource.Protocol = rsh;
160                   break;
161                 case 's':
162                   _resource.Protocol = ssh;
163                   break;
164                 default:
165                   // If it'not in all theses cases, the protocol is affected to rsh
166                   _resource.Protocol = rsh;
167                   break;
168                 }
169               xmlFree(protocol);
170             }
171           else
172             _resource.Protocol = rsh;
173           
174           if (xmlHasProp(aCurNode, (const xmlChar*)test_mode))
175             {
176               xmlChar* mode=xmlGetProp(aCurNode, (const xmlChar*)test_mode);
177               switch ( mode[0] )
178                 {
179                 case 'i':
180                   _resource.Mode = interactive;
181                   break;
182                 case 'b':
183                   _resource.Mode = batch;
184                   break;
185                 default:
186                   // If it'not in all theses cases, the mode is affected to interactive
187                   _resource.Mode = interactive;
188                   break;
189                 }
190               xmlFree(mode);
191             }
192           else
193             _resource.Mode = interactive;
194
195           if (xmlHasProp(aCurNode, (const xmlChar*)test_batch))
196             {
197               xmlChar* batch = xmlGetProp(aCurNode, (const xmlChar*)test_batch);
198               std::string aBatch = (const char*)batch;
199               xmlFree(batch);
200               if (aBatch == "pbs")
201                 _resource.Batch = pbs;
202               else if  (aBatch == "lsf")
203                 _resource.Batch = lsf;
204               else if  (aBatch == "sge")
205                 _resource.Batch = sge;
206               else
207                 _resource.Batch = none;
208             }
209
210           if (xmlHasProp(aCurNode, (const xmlChar*)test_mpi))
211             {
212               xmlChar* mpi = xmlGetProp(aCurNode, (const xmlChar*)test_mpi);
213               std::string anMpi = (const char*)mpi;
214               xmlFree(mpi);
215               if (anMpi == "lam")
216                 _resource.mpi = lam;
217               else if (anMpi == "mpich1")
218                 _resource.mpi = mpich1;
219               else if (anMpi == "mpich2")
220                 _resource.mpi = mpich2;
221               else if (anMpi == "openmpi")
222                 _resource.mpi = openmpi;
223               else if  (anMpi == "slurm")
224                 _resource.mpi = slurm;
225               else if  (anMpi == "prun")
226                 _resource.mpi = prun;
227               else
228                 _resource.mpi = nompi;
229             }
230
231           if (xmlHasProp(aCurNode, (const xmlChar*)test_user_name))
232             {
233               xmlChar* user_name= xmlGetProp(aCurNode, (const xmlChar*)test_user_name);
234               _resource.UserName = (const char*)user_name;
235               xmlFree(user_name);
236             }
237           
238           if (xmlHasProp(aCurNode, (const xmlChar*)test_appli_path))
239             {
240               xmlChar* appli_path = xmlGetProp(aCurNode, (const xmlChar*)test_appli_path);
241               _resource.AppliPath = (const char*)appli_path;
242               xmlFree(appli_path);
243             }
244           
245           if (xmlHasProp(aCurNode, (const xmlChar*)test_os))
246             {
247               xmlChar* os = xmlGetProp(aCurNode, (const xmlChar*)test_os);
248               _resource.OS = (const char*)os;
249               xmlFree(os);
250             }
251           
252           if (xmlHasProp(aCurNode, (const xmlChar*)test_mem_in_mb))
253             {
254               xmlChar* mem_in_mb = xmlGetProp(aCurNode, (const xmlChar*)test_mem_in_mb);
255               _resource.DataForSort._memInMB = atoi((const char*)mem_in_mb);
256               xmlFree(mem_in_mb);
257             }
258           
259           if (xmlHasProp(aCurNode, (const xmlChar*)test_cpu_freq_mhz))
260             {
261               xmlChar* cpu_freq_mhz = xmlGetProp(aCurNode, (const xmlChar*)test_cpu_freq_mhz);
262               _resource.DataForSort._CPUFreqMHz = atoi((const char*)cpu_freq_mhz);
263               xmlFree(cpu_freq_mhz);
264             }
265           
266           if (xmlHasProp(aCurNode, (const xmlChar*)test_nb_of_nodes))
267             {
268               xmlChar* nb_of_nodes = xmlGetProp(aCurNode, (const xmlChar*)test_nb_of_nodes);
269               _resource.DataForSort._nbOfNodes = atoi((const char*)nb_of_nodes);
270               xmlFree(nb_of_nodes);
271             }
272           
273           if (xmlHasProp(aCurNode, (const xmlChar*)test_nb_of_proc_per_node))
274             {
275               xmlChar* nb_of_proc_per_node = xmlGetProp(aCurNode, (const xmlChar*)test_nb_of_proc_per_node);
276               _resource.DataForSort._nbOfProcPerNode = atoi((const char*)nb_of_proc_per_node);
277               xmlFree(nb_of_proc_per_node);
278             }
279           
280           // Process modules
281           xmlNodePtr aCurSubNode = aCurNode->xmlChildrenNode;
282           while(aCurSubNode != NULL)
283             {
284               if ( !xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_modules) )
285                 {
286                   if (xmlHasProp(aCurSubNode, (const xmlChar*)test_module_name)) 
287                     {
288                       xmlChar* module_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_module_name);
289                       std::string aModuleName = (const char*)module_name;
290                       _resource.ModulesList.push_back(aModuleName);
291                       xmlFree(module_name);
292                     }
293                 }
294               aCurSubNode = aCurSubNode->next;
295             }
296          
297           // There is two lists
298           // _resources_list for interactive resources
299           // _resources_batch_list for batch resources
300           // This choice is done with Mode parameter
301           if (_resource.Mode == interactive)
302           {
303             int aNbNodes = _resource.DataForSort._nbOfNodes;
304             if( aNbNodes > 1 ){
305               string clusterNode = _resource.DataForSort._hostName ;
306               for( int i=0; i < aNbNodes; i++ ){
307                 char inode[64];
308                 inode[0] = '\0' ;
309                 sprintf(inode,"%s%d",clusterNode.c_str(),i+1);
310                 std::string nodeName(inode);
311                 _resource.DataForSort._hostName = nodeName ;
312                 _resource.HostName = nodeName ;
313                 _resources_list[nodeName] = _resource;
314               }
315             }
316             else
317               {
318                 _resources_list[_resource.HostName] = _resource;
319                 if(_resource.HostName == "localhost")
320                   {
321                     _resource.HostName = Kernel_Utils::GetHostname();
322                     _resource.DataForSort._hostName = Kernel_Utils::GetHostname();
323                     _resources_list[Kernel_Utils::GetHostname()] = _resource;
324                   }
325               }
326           }
327           else
328             _resources_batch_list[_resource.HostName] = _resource;
329         }
330       aCurNode = aCurNode->next;
331     }
332
333 #ifdef _DEBUG_
334     for (map<string, ParserResourcesType>::const_iterator iter =
335            _resources_list.begin();
336          iter != _resources_list.end();
337          iter++)
338       {
339         std::cerr << (*iter).first << std::endl;
340         std::cerr << (*iter).second.HostName << std::endl;
341         std::cerr << (*iter).second.Alias << std::endl;
342         std::cerr << (*iter).second.UserName << std::endl;
343         std::cerr << (*iter).second.AppliPath << std::endl;
344         std::cerr << (*iter).second.OS << std::endl;
345         std::cerr << (*iter).second.Protocol << std::endl;
346         std::cerr << (*iter).second.Mode << std::endl;
347       }
348 #endif
349
350 }
351
352
353 //=============================================================================
354 /*!
355  *  Fill the document tree in xml file, used to write in an xml file.
356  *  \param theDoc document to fill.
357  */ 
358 //=============================================================================
359
360 void SALOME_ResourcesCatalog_Handler::PrepareDocToXmlFile(xmlDocPtr theDoc)
361 {
362   // Node pointers
363   xmlNodePtr root_node = NULL, node = NULL, node1 = NULL;
364   char string_buf[80];
365
366   root_node = xmlNewNode(NULL, BAD_CAST "resources");
367   xmlDocSetRootElement(theDoc, root_node);
368     
369   for (map<string, ParserResourcesType>::iterator iter =
370          _resources_list.begin();
371        iter != _resources_list.end();
372        iter++)
373     {
374       node = xmlNewChild(root_node, NULL, BAD_CAST test_machine, NULL);
375       xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).second.HostName.c_str());
376       xmlNewProp(node, BAD_CAST test_alias, BAD_CAST (*iter).second.Alias.c_str());
377       xmlNewProp(node, BAD_CAST test_batch_queue, BAD_CAST (*iter).second.batchQueue.c_str());
378       xmlNewProp(node, BAD_CAST test_user_commands, BAD_CAST (*iter).second.userCommands.c_str());
379   
380       switch ((*iter).second.Protocol)
381         {
382         case rsh:
383           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh");
384           break;
385         case ssh:
386           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "ssh");
387           break;
388         default:
389           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh");
390         }
391
392       switch ((*iter).second.Mode)
393         {
394         case interactive:
395           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
396           break;
397         case batch:
398           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "batch");
399           break;
400         default:
401           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
402         }
403
404       switch ((*iter).second.Batch)
405         {
406         case pbs:
407           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "pbs");
408           break;
409         case lsf:
410           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "lsf");
411           break;
412         case sge:
413           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "sge");
414           break;
415         default:
416           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "");
417         }
418
419       switch ((*iter).second.mpi)
420         {
421         case lam:
422           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "lam");
423           break;
424         case mpich1:
425           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich1");
426           break;
427         case mpich2:
428           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich2");
429           break;
430         case openmpi:
431           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "openmpi");
432           break;
433         case slurm:
434           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "slurm");
435           break;
436         case prun:
437           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "prun");
438           break;
439         default:
440           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "");
441         }
442
443       xmlNewProp(node, BAD_CAST test_user_name, BAD_CAST (*iter).second.UserName.c_str());
444
445      for (vector<string>::const_iterator iter2 =
446              (*iter).second.ModulesList.begin();
447            iter2 != (*iter).second.ModulesList.end();
448            iter2++)
449         {
450           node1 = xmlNewChild(node, NULL, BAD_CAST test_modules, NULL);
451           xmlNewProp(node1, BAD_CAST test_module_name, BAD_CAST (*iter2).c_str());
452         }
453
454       xmlNewProp(node, BAD_CAST test_os, BAD_CAST (*iter).second.OS.c_str());
455       xmlNewProp(node, BAD_CAST test_mem_in_mb, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._memInMB));
456       xmlNewProp(node, BAD_CAST test_cpu_freq_mhz, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._CPUFreqMHz));
457       xmlNewProp(node, BAD_CAST test_nb_of_nodes, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfNodes));
458       xmlNewProp(node, BAD_CAST test_nb_of_proc_per_node, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfProcPerNode));
459     }
460   for (map<string, ParserResourcesType>::iterator iter =
461          _resources_batch_list.begin();
462        iter != _resources_batch_list.end();
463        iter++)
464     {
465       node = xmlNewChild(root_node, NULL, BAD_CAST test_machine, NULL);
466       xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).second.HostName.c_str());
467       xmlNewProp(node, BAD_CAST test_alias, BAD_CAST (*iter).second.Alias.c_str());
468       
469       switch ((*iter).second.Protocol)
470         {
471         case rsh:
472           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh");
473           break;
474         case ssh:
475           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "ssh");
476           break;
477         default:
478           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh");
479         }
480
481       switch ((*iter).second.Mode)
482         {
483         case interactive:
484           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
485           break;
486         case batch:
487           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "batch");
488           break;
489         default:
490           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
491         }
492
493       switch ((*iter).second.Batch)
494         {
495         case pbs:
496           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "pbs");
497           break;
498         case lsf:
499           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "lsf");
500           break;
501         case sge:
502           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "sge");
503           break;
504         default:
505           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "");
506         }
507
508       switch ((*iter).second.mpi)
509         {
510         case lam:
511           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "lam");
512           break;
513         case mpich1:
514           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich1");
515           break;
516         case mpich2:
517           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich2");
518           break;
519         case openmpi:
520           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "openmpi");
521           break;
522         case slurm:
523           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "slurm");
524           break;
525         case prun:
526           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "prun");
527           break;
528         default:
529           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "");
530         }
531
532       xmlNewProp(node, BAD_CAST test_user_name, BAD_CAST (*iter).second.UserName.c_str());
533
534      for (vector<string>::const_iterator iter2 =
535              (*iter).second.ModulesList.begin();
536            iter2 != (*iter).second.ModulesList.end();
537            iter2++)
538         {
539           node1 = xmlNewChild(node, NULL, BAD_CAST test_modules, NULL);
540           xmlNewProp(node1, BAD_CAST test_module_name, BAD_CAST (*iter2).c_str());
541         }
542
543       xmlNewProp(node, BAD_CAST test_os, BAD_CAST (*iter).second.OS.c_str());
544       xmlNewProp(node, BAD_CAST test_mem_in_mb, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._memInMB));
545       xmlNewProp(node, BAD_CAST test_cpu_freq_mhz, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._CPUFreqMHz));
546       xmlNewProp(node, BAD_CAST test_nb_of_nodes, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfNodes));
547       xmlNewProp(node, BAD_CAST test_nb_of_proc_per_node, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfProcPerNode));
548     }
549 }