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