Salome HOME
Issue 0020194: EDF 977 ALL: Get rid of warnings PACKAGE_VERSION already defined
[modules/kernel.git] / src / Batch / Batch_BatchManager_eClient.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 /*
23 * BatchManager_eLSF.cxx : emulation of LSF client
24 *
25 * Auteur : Bernard SECHER - CEA DEN
26 * Mail   : mailto:bernard.secher@cea.fr
27 * Date   : Thu Apr 24 10:17:22 2008
28 * Projet : PAL Salome
29 *
30 */
31
32 #include "Batch_BatchManager_eClient.hxx"
33 #include "Batch_RunTimeException.hxx"
34 #include "Batch_NotYetImplementedException.hxx"
35
36 #include <iostream>
37 #include <fstream>
38 #include <sstream>
39 #include <sys/stat.h>
40 #include <string.h>
41 #include <stdlib.h>
42
43 using namespace std;
44
45
46 namespace Batch {
47
48   BatchManager_eClient::BatchManager_eClient(const Batch::FactBatchManager * parent, const char* host, const char* protocol, const char* mpiImpl) : BatchManager(parent, host), _protocol(protocol), _username("")
49   {
50     // instanciation of mpi implementation needed to launch executable in batch script
51     _mpiImpl = FactoryMpiImpl(mpiImpl);
52   }
53
54   // Destructeur
55   BatchManager_eClient::~BatchManager_eClient()
56   {
57     // Nothing to do
58     delete _mpiImpl;
59   }
60
61   void BatchManager_eClient::exportInputFiles(const Job& job) throw(EmulationException)
62   {
63     int status;
64     Parametre params = job.getParametre();
65     Versatile V = params[INFILE];
66     Versatile::iterator Vit;
67     string command;
68     string copy_command;
69     _username = string(params[USER]);
70
71     // Test protocol
72     if( _protocol == "rsh" )
73       copy_command = "rcp ";
74     else if( _protocol == "ssh" )
75       copy_command = "scp ";
76     else
77       throw EmulationException("Unknown protocol : only rsh and ssh are known !");
78
79     // First step : creating batch tmp files directory
80     command = _protocol;
81     command += " ";
82     if(_username != ""){
83       command += _username;
84       command += "@";
85     }
86     command += _hostname;
87     command += " \"mkdir -p ";
88     command += string(params[TMPDIR]);
89     command += "\"" ;
90     cerr << command.c_str() << endl;
91     status = system(command.c_str());
92     if(status) {
93       std::ostringstream oss;
94       oss << status;
95       std::string ex_mess("Error of connection on remote host ! status = ");
96       ex_mess += oss.str();
97       throw EmulationException(ex_mess.c_str());
98     }
99
100     // Second step : copy fileToExecute into
101     // batch tmp files directory
102     string executeFile = params[EXECUTABLE];
103     if( executeFile.size() > 0 ){
104       command = copy_command;
105       command += string(params[EXECUTABLE]);
106       command += " ";
107       if(_username != ""){
108         command += _username;
109         command += "@";
110       }
111       command += _hostname;
112       command += ":";
113       command += string(params[TMPDIR]);
114       cerr << command.c_str() << endl;
115       status = system(command.c_str());
116       if(status) {
117         std::ostringstream oss;
118         oss << status;
119         std::string ex_mess("Error of connection on remote host ! status = ");
120         ex_mess += oss.str();
121         throw EmulationException(ex_mess.c_str());
122       }
123     }
124
125     // Third step : copy filesToExportList into
126     // batch tmp files directory
127     for(Vit=V.begin(); Vit!=V.end(); Vit++) {
128       CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
129       Couple inputFile = cpt;
130       command = copy_command;
131       command += inputFile.getLocal();
132       command += " ";
133       if(_username != ""){
134         command += _username;
135         command += "@";
136       }
137       command += _hostname;
138       command += ":";
139       command += inputFile.getRemote();
140       cerr << command.c_str() << endl;
141       status = system(command.c_str());
142       if(status) {
143         std::ostringstream oss;
144         oss << status;
145         std::string ex_mess("Error of connection on remote host ! status = ");
146         ex_mess += oss.str();
147         throw EmulationException(ex_mess.c_str());
148       }
149     }
150
151   }
152
153   void BatchManager_eClient::importOutputFiles( const Job & job, const string directory ) throw(EmulationException)
154   {
155     string command;
156     int status;
157
158     Parametre params = job.getParametre();
159     Versatile V = params[OUTFILE];
160     Versatile::iterator Vit;
161
162     for(Vit=V.begin(); Vit!=V.end(); Vit++) {
163       CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
164       Couple outputFile = cpt;
165       if( _protocol == "rsh" )
166         command = "rcp ";
167       else if( _protocol == "ssh" )
168         command = "scp ";
169       else
170         throw EmulationException("Unknown protocol");
171
172       if (_username != ""){
173         command += _username;
174         command += "@";
175       }
176       command += _hostname;
177       command += ":";
178       command += outputFile.getRemote();
179       command += " ";
180       command += directory;
181       cerr << command.c_str() << endl;
182       status = system(command.c_str());
183       if(status)
184       {
185         // Try to get what we can (logs files)
186         // throw BatchException("Error of connection on remote host");
187         std::string mess("Copy command failed ! status is :");
188         ostringstream status_str;
189         status_str << status;
190         mess += status_str.str();
191         cerr << mess << endl;
192       }
193     }
194
195   }
196
197   MpiImpl *BatchManager_eClient::FactoryMpiImpl(string mpiImpl) throw(EmulationException)
198   {
199     if(mpiImpl == "lam")
200       return new MpiImpl_LAM();
201     else if(mpiImpl == "mpich1")
202       return new MpiImpl_MPICH1();
203     else if(mpiImpl == "mpich2")
204       return new MpiImpl_MPICH2();
205     else if(mpiImpl == "openmpi")
206       return new MpiImpl_OPENMPI();
207     else if(mpiImpl == "slurm")
208       return new MpiImpl_SLURM();
209     else if(mpiImpl == "prun")
210       return new MpiImpl_PRUN();
211     else if(mpiImpl == "nompi")
212       throw EmulationException("you must specified an mpi implementation for batch manager");
213     else{
214       ostringstream oss;
215       oss << mpiImpl << " : not yet implemented";
216       throw EmulationException(oss.str().c_str());
217     }
218   }
219
220   /**
221    * This method creates a temporary file and opens an output stream to write into this file.
222    * The file is created with the pattern "/tmp/batch_XXXXXX" where the X's are replaced by random
223    * characters. The caller is responsible for closing and deleting the file when it is no more used.
224    * \param outputStream an output stream that will be opened for writing in the temporary file. If
225    * the stream is already open, it will be closed first.
226    * \return the name of the created file.
227    */
228   string BatchManager_eClient::createAndOpenTemporaryFile(ofstream & outputStream) const
229   {
230     string fileName;
231 #ifdef WIN32
232     throw NotYetImplementedException("Temporary file creation in Batch library has not been ported to Windows yet");
233 #else
234     char * tmpFileName = strdup("/tmp/batch_XXXXXX");
235     int fd = mkstemp(tmpFileName);
236     if (fd == -1)
237     {
238       throw RunTimeException("Can't create temporary file");
239     }
240
241     if (outputStream.is_open())
242       outputStream.close();
243     outputStream.open(tmpFileName);
244     close(fd);  // Close the file descriptor so that the file is not opened twice
245
246     fileName = tmpFileName;
247     delete[] tmpFileName;
248 #endif
249     return fileName;
250   }
251
252 }