]> SALOME platform Git repositories - modules/jobmanager.git/blob - src/genericgui/JM_EditSalomeResource.cxx
Salome HOME
Merge relevant changes from V8_0_0_BR branch
[modules/jobmanager.git] / src / genericgui / JM_EditSalomeResource.cxx
1 // Copyright (C) 2009-2015  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, or (at your option) any later version.
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
20 #include "JM_EditSalomeResource.hxx"
21 #include "BL_Traces.hxx"
22
23 #include <QCheckBox>
24 #include <QComboBox>
25 #include <QDialogButtonBox>
26 #include <QGridLayout>
27 #include <QGroupBox>
28 #include <QInputDialog>
29 #include <QLabel>
30 #include <QLineEdit>
31 #include <QListWidget>
32 #include <QMessageBox>
33 #include <QPushButton>
34 #include <QSpinBox>
35 #include <QVBoxLayout>
36
37 using namespace std;
38
39 JM::EditSalomeResource::EditSalomeResource(QWidget *parent, BL::SALOMEServices * salome_services,
40                                            const std::string & resource_name) : QDialog(parent)
41 {
42   DEBTRACE("Creating JM::EditSalomeResource");
43   BL_ASSERT(parent);
44   BL_ASSERT(salome_services);
45   _parent = parent;
46   _salome_services = salome_services;
47   _resource_name = resource_name;
48
49   //setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
50
51   // Widget code
52
53   // Part 1
54   QGroupBox * main_groupBox = new QGroupBox("Main values");
55   QLabel * name_label = new QLabel("Name:");
56   _name_line = new QLineEdit(this);
57   QLabel * hostname_label = new QLabel("Hostname:");
58   _hostname_line = new QLineEdit(this);
59   QLabel * username_label = new QLabel("Username:");
60   _username_line = new QLineEdit(this);
61   QLabel * applipath_label = new QLabel("Applipath:");
62   _applipath_line = new QLineEdit(this);
63
64   QLabel * protocol_label = new QLabel("Protocol:");
65   _protocol_line = new QComboBox(this);
66   _protocol_line->addItem("ssh");
67   _protocol_line->addItem("rsh");
68   _protocol_line->addItem("sh");
69   _protocol_line->setCurrentIndex(0);
70
71   QLabel * componentList_label = new QLabel("Component List:");
72   _add_button = new QPushButton("Add");
73   _remove_button = new QPushButton("Remove");
74   _remove_button->setEnabled(false);
75   QWidget * component_widget = new QWidget(this);
76   _componentList = new QListWidget(this);
77   _componentList->setSelectionMode(QAbstractItemView::MultiSelection);
78   QGridLayout * input_box = new QGridLayout(this);
79   input_box->addWidget(_add_button, 0, 0);
80   input_box->addWidget(_remove_button, 0, 1);
81   input_box->addWidget(_componentList, 1, 0, 1, -1);
82   component_widget->setLayout(input_box);
83   connect(_add_button, SIGNAL(clicked()), this, SLOT(add_component()));
84   connect(_remove_button, SIGNAL(clicked()), this, SLOT(remove_components()));
85   connect(_componentList, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
86
87   QLabel * working_directory_label = new QLabel("Working Directory:");
88   _working_directory = new QLineEdit(this);
89   _can_launch_batch_jobs = new QCheckBox("This resource can be used to launch batch jobs", this);
90   _can_launch_batch_jobs->setCheckState(Qt::Checked);
91   _can_run_containers = new QCheckBox("This resource can be used to run interactive containers", this);
92
93   QGridLayout * m_layout = new QGridLayout;
94   m_layout->addWidget(name_label, 0, 0);
95   m_layout->addWidget(_name_line, 0, 1);
96   m_layout->addWidget(hostname_label, 1, 0);
97   m_layout->addWidget(_hostname_line, 1, 1);
98   m_layout->addWidget(protocol_label, 2, 0);
99   m_layout->addWidget(_protocol_line, 2, 1);
100   m_layout->addWidget(username_label, 3, 0);
101   m_layout->addWidget(_username_line, 3, 1);
102   m_layout->addWidget(applipath_label, 4, 0);
103   m_layout->addWidget(_applipath_line, 4, 1);
104   m_layout->addWidget(componentList_label, 5, 0);
105   m_layout->addWidget(component_widget, 5, 1);
106   m_layout->addWidget(working_directory_label, 6, 0);
107   m_layout->addWidget(_working_directory, 6, 1);
108   m_layout->addWidget(_can_launch_batch_jobs, 7, 1);
109   m_layout->addWidget(_can_run_containers, 8, 1);
110   main_groupBox->setLayout(m_layout);
111
112   // Part 2
113   QGroupBox * config_groupBox = new QGroupBox("Configuration values");
114   QLabel * os_label = new QLabel("OS:");
115   _os_line = new QLineEdit(this);
116
117   QLabel * mem_mb_label = new QLabel("Memory (mb):");
118   _mem_mb_line = new QSpinBox(this);
119   _mem_mb_line->setMinimum(0);
120   _mem_mb_line->setMaximum(1000000);
121   _mem_mb_line->setValue(0);
122   QLabel * cpu_clock_label = new QLabel("CPU Clock:");
123   _cpu_clock_line = new QSpinBox(this);
124   _cpu_clock_line->setMinimum(0);
125   _cpu_clock_line->setMaximum(1000000);
126   _cpu_clock_line->setValue(0);
127   QLabel * nb_node_label = new QLabel("Nb node:");
128   _nb_node_line = new QSpinBox(this);
129   _nb_node_line->setMinimum(1);
130   _nb_node_line->setMaximum(1000000);
131   _nb_node_line->setValue(1);
132   QLabel * nb_proc_per_node_label = new QLabel("Nb proc/node:");
133   _nb_proc_per_node_line = new QSpinBox(this);
134   _nb_proc_per_node_line->setMinimum(1);
135   _nb_proc_per_node_line->setMaximum(1000000);
136   _nb_proc_per_node_line->setValue(1);
137
138   QLabel * iprotocol_label = new QLabel("Internal protocol:");
139   _iprotocol_line = new QComboBox(this);
140   _iprotocol_line->addItem("ssh");
141   _iprotocol_line->addItem("rsh");
142   _iprotocol_line->addItem("srun");
143   _iprotocol_line->addItem("pbsdsh");
144   _iprotocol_line->addItem("blaunch");
145   _iprotocol_line->setCurrentIndex(0);
146
147   QLabel * batch_label = new QLabel("Batch Manager:");
148   _batch_line = new QComboBox(this);
149   _batch_line->addItem("None", "none");
150   _batch_line->addItem("CCC", "ccc");
151   _batch_line->addItem("LSF", "lsf");
152   _batch_line->addItem("SGE", "sge");
153   _batch_line->addItem("SLURM", "slurm");
154   _batch_line->addItem("CooRM (limited support)", "coorm");
155   _batch_line->addItem("LoadLeveler (limited support)", "ll");
156   _batch_line->addItem("OAR (limited support)", "oar");
157   _batch_line->addItem("PBS (limited support)", "pbs");
158   _batch_line->addItem("VISHNU (limited support)", "vishnu");
159   _batch_line->setCurrentIndex(0);
160
161   QLabel * mpiImpl_label = new QLabel("MPI impl:");
162   _mpiImpl_line = new QComboBox(this);
163   _mpiImpl_line->addItem("lam");
164   _mpiImpl_line->addItem("mpich1");
165   _mpiImpl_line->addItem("mpich2");
166   _mpiImpl_line->addItem("openmpi");
167   _mpiImpl_line->addItem("slurmmpi");
168   _mpiImpl_line->addItem("prun");
169   _mpiImpl_line->setCurrentIndex(-1);
170
171   QGridLayout * c_layout = new QGridLayout;
172   c_layout->addWidget(os_label, 0, 0);
173   c_layout->addWidget(_os_line, 0, 1);
174   c_layout->addWidget(mem_mb_label, 1, 0);
175   c_layout->addWidget(_mem_mb_line, 1, 1);
176   c_layout->addWidget(cpu_clock_label, 2, 0);
177   c_layout->addWidget(_cpu_clock_line, 2, 1);
178   c_layout->addWidget(nb_node_label, 3, 0);
179   c_layout->addWidget(_nb_node_line, 3, 1);
180   c_layout->addWidget(nb_proc_per_node_label, 4, 0);
181   c_layout->addWidget(_nb_proc_per_node_line, 4, 1);
182   c_layout->addWidget(batch_label, 5, 0);
183   c_layout->addWidget(_batch_line, 5, 1);
184   c_layout->addWidget(mpiImpl_label, 6, 0);
185   c_layout->addWidget(_mpiImpl_line, 6, 1);
186   c_layout->addWidget(iprotocol_label, 7, 0);
187   c_layout->addWidget(_iprotocol_line, 7, 1);
188   config_groupBox->setLayout(c_layout);
189
190   // Part 3
191   QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
192                                                       | QDialogButtonBox::Cancel);
193
194   connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
195   connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
196
197   // Main Layout
198   QVBoxLayout * mainLayout = new QVBoxLayout(this);
199   mainLayout->addWidget(main_groupBox);
200   mainLayout->addWidget(config_groupBox);
201   mainLayout->addWidget(buttonBox);
202   setLayout(mainLayout);
203
204   setWindowTitle("Edit/Add a resource");
205   if (_resource_name != "")
206     get_infos();
207 }
208
209 JM::EditSalomeResource::~EditSalomeResource()
210 {
211   DEBTRACE("Destroying JM::EditSalomeResource");
212 }
213
214 void
215 JM::EditSalomeResource::get_infos()
216 {
217   BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(_resource_name);
218
219   _name_line->setText(QString(resource_descr.name.c_str()));
220   _hostname_line->setText(QString(resource_descr.hostname.c_str()));
221   _username_line->setText(QString(resource_descr.username.c_str()));
222   _applipath_line->setText(QString(resource_descr.applipath.c_str()));
223   _os_line->setText(QString(resource_descr.OS.c_str()));
224   _working_directory->setText(QString(resource_descr.working_directory.c_str()));
225
226   if (resource_descr.can_launch_batch_jobs)
227     _can_launch_batch_jobs->setCheckState(Qt::Checked);
228   else
229     _can_launch_batch_jobs->setCheckState(Qt::Unchecked);
230
231   if (resource_descr.can_run_containers)
232     _can_run_containers->setCheckState(Qt::Checked);
233   else
234     _can_run_containers->setCheckState(Qt::Unchecked);
235
236   std::string protocol = resource_descr.protocol.c_str();
237   if (protocol == "ssh")
238     _protocol_line->setCurrentIndex(0);
239   else if(protocol == "rsh")
240     _protocol_line->setCurrentIndex(1);
241   else if(protocol == "sh")
242     _protocol_line->setCurrentIndex(2);
243   else
244     _protocol_line->setCurrentIndex(-1);
245
246   std::string iprotocol = resource_descr.iprotocol.c_str();
247   if (iprotocol == "ssh")
248     _iprotocol_line->setCurrentIndex(0);
249   else if (iprotocol == "rsh")
250     _iprotocol_line->setCurrentIndex(1);
251   else if (iprotocol == "srun")
252     _iprotocol_line->setCurrentIndex(2);
253   else if (iprotocol == "pbsdsh")
254     _iprotocol_line->setCurrentIndex(3);
255   else if (iprotocol == "blaunch")
256     _iprotocol_line->setCurrentIndex(4);
257   else
258     _iprotocol_line->setCurrentIndex(-1);
259
260   for (int i=0 ; i<_batch_line->count() ; i++)
261   {
262     if (_batch_line->itemData(i).toString().toStdString() == resource_descr.batch)
263     {
264       _batch_line->setCurrentIndex(i);
265     }
266   }
267
268   std::string mpiImpl = resource_descr.mpiImpl.c_str();
269   if (mpiImpl == "lam")
270     _mpiImpl_line->setCurrentIndex(0);
271   else if (mpiImpl == "mpich1")  
272     _mpiImpl_line->setCurrentIndex(1);
273   else if (mpiImpl == "mpich2")  
274     _mpiImpl_line->setCurrentIndex(2);
275   else if (mpiImpl == "openmpi")
276     _mpiImpl_line->setCurrentIndex(3);
277   else if (mpiImpl == "slurmmpi")
278     _mpiImpl_line->setCurrentIndex(4);
279   else if (mpiImpl == "prun")
280     _mpiImpl_line->setCurrentIndex(5);
281   else  
282     _mpiImpl_line->setCurrentIndex(-1);
283
284   int value = resource_descr.mem_mb;
285   if (value > 0)
286     _mem_mb_line->setValue(value);
287   value = resource_descr.cpu_clock;
288   if (value > 0)
289     _cpu_clock_line->setValue(value);
290   value = resource_descr.nb_node;
291   if (value > 1)
292     _nb_node_line->setValue(value);
293   value = resource_descr.nb_proc_per_node;
294   if (value > 1)
295     _nb_proc_per_node_line->setValue(value);
296
297    std::list<std::string>::iterator it = resource_descr.componentList.begin();
298    for(; it != resource_descr.componentList.end(); it++)
299      _componentList->addItem(QString((*it).c_str()));
300    
301   // Better if string's length is bigger than the widget
302   _name_line->setCursorPosition(0);
303   _hostname_line->setCursorPosition(0);
304   _username_line->setCursorPosition(0);
305   _applipath_line->setCursorPosition(0);
306   _os_line->setCursorPosition(0);
307   _working_directory->setCursorPosition(0);
308 }
309
310
311 void 
312 JM::EditSalomeResource::itemSelectionChanged()
313 {
314   if (_componentList->selectedItems().size() > 0)
315     _remove_button->setEnabled(true);
316   else
317     _remove_button->setEnabled(false);
318 }
319
320 void 
321 JM::EditSalomeResource::add_component()
322 {
323   bool ok;
324   QString text = QInputDialog::getText(this, "Add a component",
325                                        "Component name:", QLineEdit::Normal,
326                                        "", &ok);
327   if (ok && !text.isEmpty())
328     _componentList->addItem(text);
329 }
330
331 void 
332 JM::EditSalomeResource::remove_components()
333 {
334   QList<QListWidgetItem *> list = _componentList->selectedItems();
335   for (int i = 0; i < list.size(); ++i)
336   {
337     int row = _componentList->row( list.at(i) );
338     delete _componentList->takeItem(row);
339   }
340 }
341
342 void
343 JM::EditSalomeResource::accept()
344 {
345   BL::ResourceDescr resource;
346
347   // Text
348   resource.name = _name_line->text().trimmed().toUtf8().constData();
349   resource.hostname = _hostname_line->text().trimmed().toStdString();
350   resource.username = _username_line->text().trimmed().toStdString();
351   resource.applipath = _applipath_line->text().trimmed().toUtf8().constData();
352   resource.OS = _os_line->text().trimmed().toStdString();
353   resource.working_directory = _working_directory->text().trimmed().toUtf8().constData();
354   resource.can_launch_batch_jobs = (_can_launch_batch_jobs->checkState() == Qt::Checked);
355   resource.can_run_containers = (_can_run_containers->checkState() == Qt::Checked);
356
357   // Components
358   int count = _componentList->count();
359   for (int i = 0; i < count; i++)
360     resource.componentList.push_back(_componentList->item(i)->text().trimmed().toStdString());
361
362   // ComboBox
363   resource.protocol = _protocol_line->currentText().toStdString();
364   resource.iprotocol = _iprotocol_line->currentText().toStdString();
365   resource.batch = _batch_line->itemData(_batch_line->currentIndex()).toString().toStdString();
366   resource.mpiImpl = _mpiImpl_line->currentText().toStdString();
367
368   // QSpinBox
369   resource.mem_mb = _mem_mb_line->value();
370   resource.cpu_clock = _cpu_clock_line->value();
371   resource.nb_node = _nb_node_line->value();
372   resource.nb_proc_per_node = _nb_proc_per_node_line->value();
373
374   if (resource.name != "" &&
375       resource.hostname != "" &&
376       resource.protocol != "")
377   {
378     try
379     {
380       _salome_services->addResource(resource);
381       QDialog::accept();
382     }
383     catch (const BL::Exception & ex)
384     {
385       QMessageBox::critical(this, "Error", QString("Cannot add resource: ") + ex.what());
386     }
387   }
388   else
389   {
390     QMessageBox::warning(NULL, "Values missing", "name, hostname and protocol are mandatory! Cancel or add values!");
391   }
392 }