]> SALOME platform Git repositories - modules/kernel.git/blob - src/Launcher/Launcher_Job.cxx
Salome HOME
835d752f7c730696167475c99fb1209f7a5d2ad2
[modules/kernel.git] / src / Launcher / Launcher_Job.cxx
1 //  Copyright (C) 2009 CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author: André RIBES - EDF R&D
20
21 #include "Launcher_Job.hxx"
22 #include "Launcher.hxx"
23
24 Launcher::Job::Job()
25 {
26   _number = -1;
27   _state = "CREATED";
28   _launch_date = getLaunchDate();
29
30   _env_file = "";
31   _job_file = "";
32   _job_file_name = "";
33   _job_file_name_complete = "";
34   _work_directory = "";
35   _local_directory = "";
36   _result_directory = "";
37   _maximum_duration = "";
38   _maximum_duration_in_second = -1;
39   _resource_required_params.name = "";
40   _resource_required_params.hostname = "";
41   _resource_required_params.OS = "";
42   _resource_required_params.nb_proc = -1;
43   _resource_required_params.nb_node = -1;
44   _resource_required_params.nb_proc_per_node = -1;
45   _resource_required_params.cpu_clock = -1;
46   _resource_required_params.mem_mb = -1;
47   _queue = "";
48
49 #ifdef WITH_LIBBATCH
50   _batch_job = new Batch::Job();
51 #endif
52 }
53
54 Launcher::Job::~Job() 
55 {
56   LAUNCHER_MESSAGE("Deleting job number: " << _number);
57 #ifdef WITH_LIBBATCH
58   if (_batch_job_id.getReference() != "undefined")
59   {
60     try 
61     {
62       _batch_job_id.deleteJob();
63     }
64     catch (const Batch::EmulationException &ex)
65     {
66       LAUNCHER_INFOS("WARNING: exception when deleting the job: " << ex.message);
67     }
68   }
69   if (_batch_job)
70     delete _batch_job;
71 #endif
72 }
73
74 void 
75 Launcher::Job::setState(const std::string & state)
76 {
77   // State of a Job: CREATED, QUEUED, RUNNING, FINISHED, ERROR
78   if (state != "CREATED" and
79       state != "QUEUED" and
80       state != "RUNNING" and
81       state != "FINISHED" and
82       state != "ERROR")
83   {
84     throw LauncherException("Bad state, this state does not exist: " + state);
85   }
86   _state = state;
87 }
88
89 std::string 
90 Launcher::Job::getState()
91 {
92   return _state;
93 }
94
95 void 
96 Launcher::Job::setNumber(const int & number)
97 {
98   if (_number != -1)
99     std::cerr << "Launcher::Job::setNumber -- Job number was already defined, before: " << _number << " now: " << number << std::endl;
100   _number = number;
101 }
102
103 int
104 Launcher::Job::getNumber()
105 {
106   return _number;
107 }
108
109 void 
110 Launcher::Job::setResourceDefinition(const ParserResourcesType & resource_definition)
111 {
112   // Check machine_definition
113   std::string user_name = "";
114   if (resource_definition.UserName == "")
115   {
116     user_name = getenv("USER");
117     if (user_name == "")
118     {
119       std::string mess = "You must define a user name: into your resource description or with env variable USER";
120       throw LauncherException(mess);
121     }
122   }
123   else
124     user_name = resource_definition.UserName;
125
126   _resource_definition = resource_definition;
127   _resource_definition.UserName = user_name;
128 }
129
130 ParserResourcesType 
131 Launcher::Job::getResourceDefinition()
132 {
133   return _resource_definition;
134 }
135
136 void 
137 Launcher::Job::setJobFile(const std::string & job_file)
138 {
139   // Check job file
140   if (job_file == "")
141   {
142     std::string mess = "Empty Job File is forbidden !";
143     throw LauncherException(mess);
144   }
145
146   _job_file = job_file;
147   std::string::size_type p1 = _job_file.find_last_of("/");
148   std::string::size_type p2 = _job_file.find_last_of(".");
149   _job_file_name_complete = _job_file.substr(p1+1);
150   _job_file_name = _job_file.substr(p1+1,p2-p1-1);
151
152   if (_job_file != "")
153     add_in_file(_job_file);
154 }
155
156 std::string
157 Launcher::Job::getJobFile()
158 {
159   return _job_file;
160 }
161 void 
162 Launcher::Job::setEnvFile(const std::string & env_file)
163 {
164   _env_file = env_file;
165   if (_env_file != "")
166     add_in_file(_env_file);
167 }
168
169 std::string
170 Launcher::Job::getEnvFile()
171 {
172   return _env_file;
173 }
174
175 void 
176 Launcher::Job::setWorkDirectory(const std::string & work_directory)
177 {
178   _work_directory = work_directory;
179 }
180
181 void 
182 Launcher::Job::setLocalDirectory(const std::string & local_directory)
183 {
184   _local_directory = local_directory;
185 }
186
187 void 
188 Launcher::Job::setResultDirectory(const std::string & result_directory)
189 {
190   _result_directory = result_directory;
191 }
192
193 void 
194 Launcher::Job::add_in_file(const std::string & file)
195 {
196   std::list<std::string>::iterator it = std::find(_in_files.begin(), _in_files.end(), file);
197   if (it == _in_files.end())
198     _in_files.push_back(file);
199   else
200     std::cerr << "Launcher::Job::add_in_file -- Warning file was already entered in in_files: " << file << std::endl;
201 }
202
203 void 
204 Launcher::Job::add_out_file(const std::string & file)
205 {
206   std::list<std::string>::iterator it = std::find(_out_files.begin(), _out_files.end(), file);
207   if (it == _out_files.end())
208     _out_files.push_back(file);
209   else
210     std::cerr << "Launcher::Job::add_out_file -- Warning file was already entered in out_files: " << file << std::endl;
211 }
212
213 void 
214 Launcher::Job::setMaximumDuration(const std::string & maximum_duration)
215 {
216   checkMaximumDuration(maximum_duration);
217   _maximum_duration_in_second = convertMaximumDuration(maximum_duration);
218   _maximum_duration = maximum_duration;
219 }
220
221 void 
222 Launcher::Job::setResourceRequiredParams(const resourceParams & resource_required_params)
223 {
224   checkResourceRequiredParams(resource_required_params);
225   _resource_required_params = resource_required_params;
226 }
227
228 void 
229 Launcher::Job::setQueue(const std::string & queue)
230 {
231   _queue = queue;
232 }
233
234 std::string 
235 Launcher::Job::getWorkDirectory()
236 {
237   return _work_directory;
238 }
239
240 std::string 
241 Launcher::Job::getLocalDirectory()
242 {
243   return _local_directory;
244 }
245
246 std::string
247 Launcher::Job::getResultDirectory()
248 {
249   return _result_directory;
250 }
251
252 const std::list<std::string> & 
253 Launcher::Job::get_in_files()
254 {
255   return _in_files;
256 }
257
258 const std::list<std::string> & 
259 Launcher::Job::get_out_files()
260 {
261   return _out_files;
262 }
263
264 std::string 
265 Launcher::Job::getMaximumDuration()
266 {
267   return _maximum_duration;
268 }
269
270 resourceParams 
271 Launcher::Job::getResourceRequiredParams()
272 {
273   return _resource_required_params;
274 }
275
276 std::string 
277 Launcher::Job::getQueue()
278 {
279   return _queue;
280 }
281
282 void 
283 Launcher::Job::checkMaximumDuration(const std::string & maximum_duration)
284 {
285   std::string result("");
286   std::string edt_value = maximum_duration;
287   if (edt_value != "") {
288     std::string begin_edt_value = edt_value.substr(0, 2);
289     std::string mid_edt_value = edt_value.substr(2, 1);
290     std::string end_edt_value = edt_value.substr(3);
291   
292     long value;
293     std::istringstream iss(begin_edt_value);
294     if (!(iss >> value)) {
295       result = "[Launcher::Job::checkExpectedDuration] Error on definition ! : " + edt_value;
296     }
297     else if (value < 0) {
298       result = "[Launcher::Job::checkExpectedDuration] Error on definition time is negative ! : " + value;
299     }
300     std::istringstream iss_2(end_edt_value);
301     if (!(iss_2 >> value)) {
302       result = "[Launcher::Job::checkExpectedDuration] Error on definition ! : " + edt_value;
303     }
304     else if (value < 0) {
305       result = "[Launcher::Job::checkExpectedDuration] Error on definition time is negative ! : " + value;
306     }
307     if (mid_edt_value != ":") {
308       result = "[Launcher::Job::checkExpectedDuration] Error on definition ! :" + edt_value;
309     }
310   }
311   if (result != "")
312     throw LauncherException(result);
313 }
314
315 void 
316 Launcher::Job::checkResourceRequiredParams(const resourceParams & resource_required_params)
317 {
318   // nb_proc has be to > 0
319   if (resource_required_params.nb_proc <= 0)
320   {
321     std::string message("[Launcher::Job::checkResourceRequiredParams] proc number is not > 0 ! ");
322     throw LauncherException(message);
323   }
324 }
325
326 long 
327 Launcher::Job::convertMaximumDuration(const std::string & edt)
328 {
329   long hh, mm, ret;
330
331   if( edt.size() == 0 )
332     return -1;
333
334   std::string::size_type pos = edt.find(":");
335   std::string h = edt.substr(0,pos);
336   std::string m = edt.substr(pos+1,edt.size()-pos+1);
337   std::istringstream issh(h);
338   issh >> hh;
339   std::istringstream issm(m);
340   issm >> mm;
341   ret = hh*60 + mm;
342   ret = ret * 60;
343
344   return ret;
345 }
346
347 std::string 
348 Launcher::Job::getLaunchDate()
349 {
350   time_t rawtime;
351   time(&rawtime);
352   std::string launch_date = ctime(&rawtime);
353   int i = 0 ;
354   for (;i < launch_date.size(); i++) 
355     if (launch_date[i] == '/' or 
356         launch_date[i] == '-' or 
357         launch_date[i] == ':' or
358         launch_date[i] == ' ') 
359       launch_date[i] = '_';
360   launch_date.erase(--launch_date.end()); // Last caracter is a \n
361
362   return launch_date;
363 }
364
365 std::string
366 Launcher::Job::updateJobState()
367 {
368 #ifdef WITH_LIBBATCH
369   if (_batch_job_id.getReference() != "undefined")
370   {
371     // A batch manager has been affected to the job
372     Batch::JobInfo job_info = _batch_job_id.queryJob();
373     Batch::Parametre par = job_info.getParametre();
374
375     LAUNCHER_MESSAGE("State received is: " << par[STATE].str());
376
377     // Patch until new LIBBATCH version
378     // eSSH Client and ePBS Client and eSGE
379     if (par[STATE].str() == "Running" or par[STATE].str() == "E" or par[STATE].str() == "R" or par[STATE].str() == "r" or par[STATE].str() == "RUN")
380       _state = "RUNNING";
381     else if (par[STATE].str() == "Stopped")
382       _state = "PAUSED";
383     else if (par[STATE].str() == "Done" or par[STATE].str() == "U" or par[STATE].str() == "e" or par[STATE].str() == "DONE" or par[STATE].str() == "EXIT")
384       _state = "FINISHED";
385     else if (par[STATE].str() == "Dead" or par[STATE].str() == "Eqw")
386       _state = "ERROR";
387     else if (par[STATE].str() == "Q" or par[STATE].str() == "qw" or par[STATE].str() == "PEN")
388       _state = "QUEUED";
389   }
390 #endif
391   return _state;
392 }
393
394 #ifdef WITH_LIBBATCH
395 Batch::Job * 
396 Launcher::Job::getBatchJob()
397 {
398   update_job();
399   return _batch_job;
400 }
401
402 Batch::Parametre
403 Launcher::Job::common_job_params()
404 {
405   Batch::Parametre params;
406
407   params[USER] = _resource_definition.UserName;
408   params[NBPROC] = _resource_required_params.nb_proc;
409
410   // Memory
411   if (_resource_required_params.mem_mb > 0)
412   {
413     // Memory is in kilobytes
414     params[MAXRAMSIZE] = _resource_required_params.mem_mb * 1024;
415   }
416
417   // We define a default directory based on user time
418   if (_work_directory == "")
419   {
420     std::string thedate;
421     Batch::Date date = Batch::Date(time(0));
422     thedate = date.str();
423     int lend = thedate.size() ;
424     int i = 0 ;
425     while ( i < lend ) {
426       if ( thedate[i] == '/' || thedate[i] == '-' || thedate[i] == ':' ) {
427         thedate[i] = '_' ;
428       }
429       i++ ;
430     }
431     _work_directory = std::string("$HOME/Batch/");
432     _work_directory += thedate;
433   }
434   params[WORKDIR] = _work_directory;
435   params[TMPDIR] = _work_directory; // To Compatibility -- remove ??? TODO
436
437   // If result_directory is not defined, we use HOME environnement
438   if (_result_directory == "")
439     _result_directory = getenv("HOME");
440
441   // _in_files
442   for(std::list<std::string>::iterator it = _in_files.begin(); it != _in_files.end(); it++)
443   {
444     std::string file = *it;
445
446     // local file -> If file is not an absolute path, we apply _local_directory
447     std::string local_file;
448     if (file.substr(0, 1) == std::string("/"))
449       local_file = file;
450     else
451       local_file = _local_directory + "/" + file;
452     
453     // remote file -> get only file name from _in_files
454     size_t found = file.find_last_of("/");
455     std::string remote_file = _work_directory + "/" + file.substr(found+1);
456
457     params[INFILE] += Batch::Couple(local_file, remote_file);
458   }
459    
460   // _out_files
461   for(std::list<std::string>::iterator it = _out_files.begin(); it != _out_files.end(); it++)
462   {
463     std::string file = *it;
464
465     // local file 
466     size_t found = file.find_last_of("/");
467     std::string local_file = _result_directory +  "/" + file.substr(found+1);
468
469     // remote file -> If file is not an absolute path, we apply _work_directory
470     std::string remote_file;
471     if (file.substr(0, 1) == std::string("/"))
472       remote_file = file;
473     else
474       remote_file = _work_directory + "/" + file;
475
476     params[OUTFILE] += Batch::Couple(local_file, remote_file);
477   }
478
479   // Time
480   if (_maximum_duration_in_second != -1)
481     params[MAXWALLTIME] = _maximum_duration_in_second;
482
483   // Queue
484   if (_queue != "")
485     params[QUEUE] = _queue;
486
487   return params;
488 }
489
490 void 
491 Launcher::Job::setBatchManagerJobId(Batch::JobId batch_manager_job_id)
492 {
493   _batch_job_id = batch_manager_job_id;
494 }
495
496 Batch::JobId 
497 Launcher::Job::getBatchManagerJobId()
498 {
499   return _batch_job_id;
500 }
501 #endif