Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Palacios GUI Added
[palacios.git] / linux_usr / gui / palacios / newpalacios.cpp
1 #include <QMessageBox>
2 #include <QDebug>
3 #include <QtGui>
4 #include <QtAlgorithms>
5
6 #include "newpalacios.h"
7 #include "defs.h"
8
9 NewPalacios::NewPalacios(QWidget *parent) :
10                 QMainWindow(parent) {
11
12         // Call UI setup methods
13         createWizard();
14         createCentralWidget();
15         createActions();
16         createMenus();
17         createToolBars();
18         createStatusBar();
19         createDockWindows();
20         readExistingVmsFile();
21
22         setWindowTitle(tr(TITLE_MAIN_WINDOW));
23
24         mExitAppFromMenu = false;
25 }
26
27 NewPalacios::~NewPalacios() {
28     // Cleanup actions
29     delete mExitApp;
30     delete mVmNew;
31     delete mVmStop;
32     delete mVmPause;
33     delete mVmStart;
34     delete mVmActivate;
35     delete mReloadVms;
36     delete mAboutApp;
37
38     // Clean up menu
39     delete mFileMenu;
40     delete mViewMenu;
41     delete mVmMenu;
42     delete mHelpMenu;
43
44     // Clean up toolbar
45     delete mVmToolBar;
46     delete mVmCtrlToolBar;
47
48     /*if (mLoadVmsThread != NULL)
49         delete mLoadVmsThread;
50     if (mAddVmThread != NULL)
51         delete mAddVmThread;
52     if (mDeleteVmThread != NULL)
53         delete mDeleteVmThread;*/
54
55     delete mVmTreeView;
56     delete mVmTelemetryView;
57     delete mVmWizard;
58     delete mVmInfoWidget;
59
60     // Delete the central widget at the end
61     delete mVmControlPanel;
62 }
63
64 void NewPalacios::createCentralWidget() {
65         // The VM View will be the central widget
66         // of this window. The List of VMs will
67         // be docked in the left corner
68         mVmControlPanel = new QTabWidget();
69         mVmControlPanel->setTabsClosable(true);
70         connect(mVmControlPanel, SIGNAL(tabCloseRequested(int)), 
71                 this, SLOT(vmTabClosed(int)));
72
73         mVmInfoWidget = new VmInfoWidget(mVmControlPanel);
74         
75         // Set the widget to the window
76         this->setCentralWidget(mVmControlPanel);
77 }
78
79 void NewPalacios::createActions() {
80         mVmNew = new QAction(QIcon(":/images/images/new_vm.png"),
81                         tr(FILE_MENU_NEW_VM), this);
82         connect(mVmNew, SIGNAL(triggered()), this, SLOT(createVmInstance()));
83
84         mExitApp = new QAction(QIcon(":/images/images/exit.png"),
85                         tr(FILE_MENU_EXIT), this);
86         connect(mExitApp, SIGNAL(triggered()), this, SLOT(exitApplication()));
87
88         mVmStart = new QAction(QIcon(":/images/images/start_vm.png"),
89                         tr(VM_MENU_START), this);
90         connect(mVmStart, SIGNAL(triggered()), this, SLOT(selectVmMode()));
91
92         mVmStop = new QAction(QIcon(":/images/images/stop_vm.png"),
93                         tr(VM_MENU_STOP), this);
94         connect(mVmStop, SIGNAL(triggered()), this, SLOT(stopVm()));
95
96         mVmPause = new QAction(QIcon(":/images/images/pause_vm.png"),
97                         tr(VM_MENU_PAUSE), this);
98         connect(mVmPause, SIGNAL(triggered()), this, SLOT(pauseVm()));
99
100         mVmActivate = new QAction(QIcon(":/images/images/activate_vm.png"),
101                         tr(VM_MENU_ACTIVATE), this);
102         connect(mVmActivate, SIGNAL(triggered()), this, SLOT(activateVm()));
103
104         mAboutApp = new QAction(tr(HELP_MENU_ABOUT), this);
105         connect(mAboutApp, SIGNAL(triggered()), this, SLOT(aboutPalacios()));
106         
107         mReloadVms = new QAction(QIcon(":/images/images/reload_vm.png"), tr(VM_MENU_RELOAD), this);
108         connect(mReloadVms, SIGNAL(triggered()), this, SLOT(reloadVms()));
109
110         connect(mVmWizard, SIGNAL(accepted()), this, SLOT(addNewVm()));
111 }
112
113 void NewPalacios::createMenus() {
114         mFileMenu = menuBar()->addMenu(tr(MENU_FILE));
115         mFileMenu->addAction(mVmNew);
116         mFileMenu->addSeparator();
117         mFileMenu->addAction(mExitApp);
118
119         mViewMenu = menuBar()->addMenu(tr(MENU_VIEW));
120
121         mVmMenu = menuBar()->addMenu(tr(MENU_VM));
122         mVmMenu->addAction(mVmStart);
123         mVmMenu->addAction(mVmStop);
124         mVmMenu->addAction(mVmPause);
125         mVmMenu->addAction(mVmActivate);
126         mVmMenu->addAction(mReloadVms);
127
128         mHelpMenu = menuBar()->addMenu(tr(MENU_HELP));
129         mHelpMenu->addAction(mAboutApp);
130 }
131
132 void NewPalacios::createToolBars() {
133         mVmToolBar = addToolBar(tr(MENU_FILE));
134         mVmToolBar->addAction(mVmNew);
135
136         mVmCtrlToolBar = addToolBar(tr(MENU_VM));
137         mVmCtrlToolBar->addAction(mVmStart);
138         mVmCtrlToolBar->addAction(mVmStop);
139         mVmCtrlToolBar->addAction(mVmPause);
140         mVmCtrlToolBar->addAction(mVmActivate);
141         mVmCtrlToolBar->addAction(mReloadVms);
142 }
143
144 void NewPalacios::createStatusBar() {
145         statusBar()->showMessage(tr(STATUS_BAR_MSG_READY));
146 }
147
148 void NewPalacios::createDockWindows() {
149         QDockWidget* dockVmList = new QDockWidget(tr(TITLE_DOCK_VM_LIST), this);
150                
151         // Setup VM instance tree view
152         mVmTreeView = new QTreeWidget(dockVmList);
153         mVmTreeView->setColumnCount(1);
154         mVmTreeView->headerItem()->setHidden(true);
155         // Header for active VMs
156         QTreeWidgetItem* activeVms = new QTreeWidgetItem(mVmTreeView);
157         activeVms->setText(0, tr(LABEL_ACTIVE_INVENTORY));
158         mVmTreeView->addTopLevelItem(activeVms);
159         
160         // Header for inactive VMs in the inventory
161         QTreeWidgetItem* inactiveVms = new QTreeWidgetItem(mVmTreeView);
162         inactiveVms->setText(0, tr(LABEL_INACTIVE_INVENTORY));
163         mVmTreeView->addTopLevelItem(inactiveVms);
164         
165         // Header for active VMs not in inventory
166         QTreeWidgetItem* activeNotInventoryVms = new QTreeWidgetItem(mVmTreeView);
167         activeNotInventoryVms->setText(0, tr(LABEL_ACTIVE_NOT_INVENTORY));
168         mVmTreeView->addTopLevelItem(activeNotInventoryVms);
169         
170         mVmTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
171         connect(mVmTreeView, SIGNAL(customContextMenuRequested(const QPoint &)),
172                     this, SLOT(vmContextMenu(const QPoint &)));
173         connect(mVmTreeView, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this,
174                     SLOT(vmItemClickListener(QTreeWidgetItem*, int)));
175
176         dockVmList->setAllowedAreas(Qt::LeftDockWidgetArea);
177         dockVmList->setFeatures(QDockWidget::DockWidgetClosable);
178         dockVmList->setWidget(mVmTreeView);
179         addDockWidget(Qt::LeftDockWidgetArea, dockVmList);
180         mViewMenu->addAction(dockVmList->toggleViewAction());
181         
182         // Telemetry dock
183         QDockWidget* dockTelemetry = new QDockWidget(tr(TITLE_DOCK_TELEMETRY), this);
184         mVmTelemetryView = new QTextEdit(dockTelemetry);
185         mVmTelemetryView->setReadOnly(true);
186         dockTelemetry->setAllowedAreas(Qt::BottomDockWidgetArea);
187         dockTelemetry->setFeatures(QDockWidget::NoDockWidgetFeatures);
188         dockTelemetry->setWidget(mVmTelemetryView);
189         addDockWidget(Qt::BottomDockWidgetArea, dockTelemetry);
190         connect(dockTelemetry, SIGNAL(visibilityChanged(bool)), this, SLOT(updateTelemetry(bool)));
191 }
192
193 void NewPalacios::updateTelemetry(bool visible) {
194         if (visible) {
195                 mTelemProc = new QProcess();
196                 mTelemProc->setProcessChannelMode(QProcess::MergedChannels);
197                 QStringList args;
198                 args << "-c" << "tail -f /var/log/messages";
199                 
200                 // Slots used for debugging
201                 //connect(mTelemProc, SIGNAL(started()), this, SLOT(processStarted()));
202                 //connect(mTelemProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processExit(int, QProcess::ExitStatus)));
203                 //connect(mTelemProc, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
204                 
205                 // Connect output of dmesg to text widget
206                 connect(mTelemProc, SIGNAL(readyReadStandardOutput()), this, SLOT(updateTelemetryView()));
207                 
208                 mTelemProc->start("sh", args);
209                 if (!mTelemProc->waitForStarted()) {
210                         if (mVmTelemetryView != NULL) {
211                                 mVmTelemetryView->setText(tr(ERROR_TELEMETRY));
212                         }
213                 }
214         } else {
215                 /*if (mTelemProc != NULL) {
216                         mTelemProc->close();
217                         mTelemProc->terminate();
218                         delete mTelemProc;
219                 }*/
220         }
221 }
222
223 void NewPalacios::updateTelemetryView() {
224         if (mVmTelemetryView != NULL && mTelemProc != NULL) {
225                 mVmTelemetryView->setText(mTelemProc->readAllStandardOutput());
226         }
227 }
228
229 void NewPalacios::createWizard() {
230         mVmWizard = new NewVmWizard();
231 }
232
233 // Listener for VM item clicks
234 void NewPalacios::vmItemClickListener(QTreeWidgetItem* item, int col) {
235         if (item->text(0).compare(LABEL_ACTIVE_INVENTORY) == 0
236                 || item->text(0).compare(LABEL_INACTIVE_INVENTORY) == 0
237                 || item->text(0).compare(LABEL_ACTIVE_NOT_INVENTORY) == 0) {
238                 // If user clicks on the main headers
239                 // do nothing
240                 isHeaderClicked = true;
241                 return;
242         }
243         
244         isHeaderClicked = false;
245
246         QString vmName = item->text(col);
247         mVmName = vmName;
248         
249         // Locate the VM clicked in the list. This is inefficient because each time we need 
250         // to search the list. If a better way is found. replace here
251         VmInfo* vm = NULL;
252         for (int i = 0; i < mVmList.size(); i++) {
253                 if (vmName.compare(mVmList[i]->getVmName()) == 0) {
254                         mVmPos = i;
255                         vm = mVmList[i];
256                         break;
257                 }
258         }
259         // Load the details of the seleted VM
260         if (vm != NULL) {
261             mVmInfoWidget->updateInfoView(vm);
262         }
263 }
264
265 void NewPalacios::vmContextMenu(const QPoint &pos) {
266         //QPoint globalPos = mVmListView->mapToGlobal(pos);
267         QPoint globalPos = mVmTreeView->mapToGlobal(pos);
268         
269         QTreeWidgetItem* item = mVmTreeView->itemAt(pos);
270         if (item->text(0).compare(LABEL_ACTIVE_INVENTORY) == 0
271                 || item->text(0).compare(LABEL_INACTIVE_INVENTORY) == 0
272                 || item->text(0).compare(LABEL_ACTIVE_NOT_INVENTORY) == 0) {
273                 // Clicked on the headers
274                 // do nothing
275                 isHeaderClicked = true;
276                 return;
277         }
278         
279         isHeaderClicked = false;
280         
281         // Update VM pos, the global index locator for VMs
282         QString vmName = item->text(0);
283         // Update global VM name
284         mVmName = vmName;
285         for (int i=0; i<mVmList.size(); i++) {
286                 if (vmName.compare(mVmList[i]->getVmName()) == 0) {
287                         mVmPos = i;
288                         break;
289                 }
290         }
291         
292         QMenu *menu = new QMenu();
293         if (mVmList[mVmPos]->getCategory() == VmInfo::INACTIVE_INVENTORY
294                 || mVmList[mVmPos]->getCategory() == VmInfo::ACTIVE_NOT_INVENTORY) {
295                 
296                 menu->addAction(new QAction(tr(VM_MENU_ACTIVATE), this));
297         } else {
298                 if (mVmList[mVmPos]->getState() == VmInfo::RUNNING) {
299                         menu->addAction(new QAction(tr(VM_MENU_PAUSE), this));
300
301                 } else if (mVmList[mVmPos]->getState() == VmInfo::PAUSED) {
302                         menu->addAction(new QAction(tr(VM_MENU_RESTART), this));
303         
304                 } else if (mVmList[mVmPos]->getState() == VmInfo::STOPPED) {
305                         menu->addAction(new QAction(tr(VM_MENU_START), this));
306         
307                 }
308  
309                 menu->addAction(new QAction(tr(VM_MENU_STOP), this));
310        }
311         
312         menu->addAction(new QAction(tr(VM_MENU_REMOVE), this));
313         
314         QAction* selectedAction = menu->exec(globalPos);
315         if (selectedAction == NULL) {
316                 // User did not select any option
317                 return;
318         }
319         
320         QString actionItem = selectedAction->text();
321         if (actionItem.compare(tr(VM_MENU_START)) == 0
322                     || actionItem.compare(tr(VM_MENU_RESTART)) == 0) {
323                 // If VM was stopped or paused
324                 selectVmMode();
325
326         } else if (actionItem.compare(tr(VM_MENU_PAUSE)) == 0) {
327                 // Pause VM
328                 pauseVm();
329
330         } else if (actionItem.compare(tr(VM_MENU_RESTART)) == 0) {
331                 // Restart VM
332                 restartVm();
333         
334         } else if (actionItem.compare(tr(VM_MENU_STOP)) == 0) {
335                 // Stop the VM if possible
336                 stopVm();
337
338         } else if (actionItem.compare(tr(VM_MENU_REMOVE)) == 0) {
339                 bool isVmRunning = false;
340                 for (int i=0; i < mRunningVms.size(); i++) {
341                         if (mVmName.compare(mRunningVms[i]->getVmName()) == 0) {
342                                 isVmRunning = true;
343                                 break;
344                         }
345                 }
346                 
347                 QMessageBox vmDeleteWarningBox;
348
349                 if (isVmRunning) {
350                         vmDeleteWarningBox.setText(DELETE_RUNNING_VM_ERROR);
351                         vmDeleteWarningBox.setIcon(QMessageBox::Critical);
352                 } else {
353                         vmDeleteWarningBox.setText(VM_DELETE_WARNING_MESSAGE);
354                         vmDeleteWarningBox.setIcon(QMessageBox::Warning);
355                 }
356
357                 vmDeleteWarningBox.setStandardButtons(
358                                 QMessageBox::Ok | QMessageBox::Cancel);
359                 vmDeleteWarningBox.setDefaultButton(QMessageBox::Cancel);
360                 int retVal = vmDeleteWarningBox.exec();
361
362                 switch (retVal) {
363                 case QMessageBox::Ok:
364                         if (!isVmRunning) {
365                                 deleteVm(mVmName);
366                         }
367                         break;
368                 case QMessageBox::Cancel:
369                         break;
370                 }
371                 
372         } else if (actionItem.compare(tr(VM_MENU_ACTIVATE)) == 0) {
373                 activateVm();
374                 return;
375         }
376
377 }
378
379 void NewPalacios::aboutPalacios() {
380         QMessageBox::about(this, tr(HELP_MENU_ABOUT), tr(ABOUT_PALACIOS));
381 }
382
383 // This function checks for the necessary setup
384 // required by palacios to run. The setup for palacios
385 // includes:
386 // 1. Check for v3vee.ko module
387 // 2. Check if palacios has been allocated memory
388 void NewPalacios::checkPalacios() {
389         int err = 0;
390         QMessageBox setupError;
391         setupError.setStandardButtons(QMessageBox::Ok);
392         setupError.setIcon(QMessageBox::Critical);
393         
394         // v3vee.ko check
395         QProcess* v3 = new QProcess();
396         v3->setProcessChannelMode(QProcess::MergedChannels);
397         v3->start("lsmod");
398         v3->waitForFinished();
399         QByteArray reply = v3->readAllStandardOutput();
400
401         if (reply.isEmpty() || !reply.contains("v3vee")) {
402                 setupError.setText(tr(ERROR_SETUP_MODULE_INSTALL));
403                 err = -1;
404         }
405         
406         QFile file("/proc/v3vee/v3-mem");
407         if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
408                 setupError.setText(tr(ERROR_SETUP_MODULE_INSTALL_FAILED));
409                 err = -1;
410         }
411
412         QTextStream in(&file);
413
414         while(in.atEnd()) {
415                 QString line = in.readLine();
416                 if (line.contains("null")) {
417                         setupError.setText(tr(ERROR_SETUP_MEMORY));
418                         err = -1;
419                         break;
420                 }
421         }
422         
423         if (err != 0) {
424                 int ret = setupError.exec();
425                 
426                 if (ret == QMessageBox::Ok) {
427                         // Palacios not setup correctly, exit
428                         this->close();
429                 }
430         }
431 }
432
433 void NewPalacios::closeEvent(QCloseEvent* event) {
434         if (mExitAppFromMenu == true) {
435             event->accept();
436             return;
437         }
438
439         bool flag = false;
440
441         for (int i=0; i<mVmList.size(); i++) {
442                 if (mVmList[i]->getState() == VmInfo::RUNNING) {
443                         flag = true;
444                         break;
445                 }
446         }
447
448         if (!flag) {
449                 if (mTelemProc != NULL) {
450                         mTelemProc->close();
451                         mTelemProc->terminate();
452                         delete mTelemProc;
453                 }
454                 event->accept();
455         } else {
456                 
457                 QMessageBox appCloseWarning;
458                 appCloseWarning.setText(tr("There are still running VMs. It is suggested to close the running VMs tab before exiting. Click cancel to go back"));
459                 appCloseWarning.setIcon(QMessageBox::Warning);
460                 appCloseWarning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
461
462                 int ret = appCloseWarning.exec();
463                 switch (ret) {
464                 case QMessageBox::Ok:
465                     event->accept();
466                     break;
467                 case QMessageBox::Cancel:
468                     event->ignore();
469                     break;
470                 }
471         }
472 }
473
474 void NewPalacios::exitApplication() {
475         QMessageBox appCloseWarning;
476         appCloseWarning.setText(tr("There are still running VMs. It is suggested to close the running VMs tab before exiting. Click cancel to go back"));
477         appCloseWarning.setIcon(QMessageBox::Warning);
478         appCloseWarning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
479
480         bool flag = false;
481         
482         // Check if there are running VMs
483         for (int i=0; i<mVmList.size(); i++) {
484                 if (mVmList[i]->getState() == VmInfo::RUNNING) {
485                         flag = true;
486                         break;
487                 }
488         }
489         
490         // If there are no running VMs
491         // exit
492         if (!flag) {
493                 if (mTelemProc != NULL) {
494                         mTelemProc->close();
495                         mTelemProc->terminate();
496                         delete mTelemProc;
497                 }
498                 mExitAppFromMenu = true;
499                 this->close();
500         } else {
501                 // Inform user about running VMs and ask for consent
502                 // before closing application
503                 int ret = appCloseWarning.exec();
504                 switch (ret) {
505                 case QMessageBox::Ok:
506                     mExitAppFromMenu = true;
507                     this->close();
508                     break;
509                 case QMessageBox::Cancel:
510                     mExitAppFromMenu = false;
511                     break;
512                 }
513        }
514 }
515
516 // Convenience method for showing messages
517 void NewPalacios::showMessage(QString msg, bool err, bool warning) {
518         QMessageBox msgBox;
519         msgBox.setText(msg);
520         if (err == true) {
521                 msgBox.setIcon(QMessageBox::Critical);
522         } else if (warning == true) {
523                 msgBox.setIcon(QMessageBox::Warning);
524         }
525         
526         msgBox.setStandardButtons(QMessageBox::Ok);
527         msgBox.exec();
528 }
529
530 /*void NewPalacios::processStarted() {
531         //qDebug() << "Process started...";
532 }
533
534 void NewPalacios::processExit(int errorCode, QProcess::ExitStatus exitStatus) {
535         if (exitStatus == QProcess::CrashExit) {
536                 //qDebug() << "The process crashed!!";
537         } else {
538                 //qDebug() << "The process exited normally..";
539         }
540 }
541
542 void NewPalacios::processError(QProcess::ProcessError error) {
543         //qDebug() << "There was an error in the process execution...";
544         
545         switch (error) {
546         case QProcess::FailedToStart:
547                 //qDebug() << "Process failed to start...";
548                 break;
549         case QProcess::Crashed:
550                 //qDebug() << "Process crashed...";
551                 break;
552         case QProcess::Timedout:
553                 //qDebug() << "Process timed out...";
554                 break;
555         case QProcess::WriteError:
556                 //qDebug() << "Process had write error...";
557                 break;
558         case QProcess::ReadError:
559                 //qDebug() << "Process had read error...";
560                 break;
561         case QProcess::UnknownError:
562                 //qDebug() << "Process unknown error...";
563                 break;
564
565         }
566 }*/
567
568 void NewPalacios::createVmInstance() {
569         if (mVmWizard != NULL) {
570                 mVmWizard->restart();
571                 mVmWizard->show();
572         }
573 }
574
575 void NewPalacios::selectVmMode() {
576         if (isHeaderClicked) {
577                 return;
578         }
579         
580         if (mVmList[mVmPos]->getCategory() != VmInfo::ACTIVE_INVENTORY) {
581                 QMessageBox warning;
582                 showMessage(tr("VM is not active!"), true);
583                 return;
584         }
585            
586
587         if (mVmList[mVmPos]->getState() == VmInfo::PAUSED) {
588                 // If machine is paused, we just restart using the previous selected mode
589                 restartVm();
590         } else {
591                 // Machine is started fresh
592                 mVmModeDialog = new VmModeDialog(this);
593                 connect(mVmModeDialog, SIGNAL(setMode(int, QString)), 
594                         this, SLOT(getVmMode(int, QString)));
595                 mVmModeDialog->show();
596         }
597 }
598
599 void NewPalacios::getVmMode(int mode, QString streamName) {
600         mVmMode = mode;
601         mStreamName = streamName;
602         // Start VM
603         startVm();
604 }
605
606 void NewPalacios::startVm() {
607         if (mVmList.isEmpty()) {
608                 // There is no VM in the list
609                 return;
610         }
611         
612         // Check if we are trying to start an inactive VM
613         if (mVmList[mVmPos]->getCategory() == VmInfo::INACTIVE_INVENTORY) {
614                 showMessage(tr(ERROR_RUN_INACTIVE_INVENTORY), true);
615                 return;
616         }
617         
618         // Check if we are trying to start a VM not in the inventory
619         if (mVmList[mVmPos]->getCategory() == VmInfo::ACTIVE_NOT_INVENTORY) {
620                 showMessage(tr(ERROR_RUN_ACTIVE_NOT_INVENTORY), true);
621                 return;
622         }
623
624         int pos = 0;
625         // Check if the VM is already running        
626         for (int i=0; i < mRunningVms.size(); i++) {
627                 if (mVmName.compare(mRunningVms[i]->getVmName()) == 0 
628                         && mVmMode != VmConsoleWidget::STREAM) {
629                         // If we are running the VM in stream mode then we
630                         // can have multiple streams open simultaneously
631                         // For the other modes, only one instance can be running
632                         showMessage(tr(ERROR_VM_RUNNING), true);
633                         return;
634                 }
635         }
636         
637         QString v3_devfile = mVmList[mVmPos]->getVmDevFile();
638         if (v3_devfile == NULL) {
639                 showMessage(tr(ERROR_NO_DEVFILE_FOR_LAUNCH), true);
640                 return;
641         }
642         
643         int vm_status = mVmList[mVmPos]->getState();
644         
645         QProcess* v3LaunchProc = NULL;
646         QStringList args;
647         bool flag = false;
648         QByteArray message;
649
650         switch (vm_status) {
651             case VmInfo::STOPPED:
652                 // If VM is stopped, launch it <v3_launch>
653                 v3LaunchProc = new QProcess();
654                 v3LaunchProc->setProcessChannelMode(QProcess::MergedChannels);
655                 
656                 // Connect debug slots
657                 //connect(v3LaunchProc, SIGNAL(started()), this, SLOT(processStarted()));
658                 //connect(v3LaunchProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processExit(int, QProcess::ExitStatus)));
659                 //connect(v3LaunchProc, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
660                 
661                 args << v3_devfile;
662                 v3LaunchProc->start("v3_launch", args);
663
664                 flag = v3LaunchProc->waitForFinished();
665                 message = v3LaunchProc->readAllStandardOutput();
666
667                 if (!flag) {
668                         showMessage(tr(ERROR_VM_LAUNCH), true);
669                         delete v3LaunchProc;
670                         return;
671                         
672                 } else if (message.contains("Error opening V3Vee VM device")) {
673                         showMessage(tr(ERROR_LAUNCH_VM_DEVICE_NOT_FOUND), true);
674                         delete v3LaunchProc;
675                         return;
676                         
677                 } 
678
679                 break;
680             /*case VmInfo::PAUSED:
681                 // If VM is paused, call <v3_continue>
682                 restartVm();
683                 break;*/
684             case VmInfo::RUNNING:
685                 // If VM is running, do nothing
686                 // We will be just calling v3_cons_sc/v3_stream/vnc to
687                 // connect to it
688                 break;
689         }
690         
691         QString name = mVmList[mVmPos]->getVmName();
692         // Create a new console instance and set the launch file
693         VmXConsoleParent* consoleParent = new VmXConsoleParent(name);
694         
695         // Add it to list of running VMs
696         mRunningVms.append(consoleParent);
697         pos = mRunningVms.indexOf(consoleParent);
698         
699         // Launch in new tab
700         // Disable updates in widgets to reduce screen flicker
701         // due to layouting in widgets
702         consoleParent->setUpdatesEnabled(false);
703         mVmControlPanel->setUpdatesEnabled(false);
704         if (mVmMode != VmConsoleWidget::STREAM) {
705             // If not in stream mode, header will be VM name
706             mVmControlPanel->insertTab(mVmControlPanel->count(), consoleParent, name);
707         } else {
708             // If stream mode, header will be stream name
709             mVmControlPanel->insertTab(mVmControlPanel->count(), consoleParent, mStreamName);
710         }
711         mVmControlPanel->setCurrentWidget(consoleParent);
712         
713         // Start VM
714         consoleParent->showWidget(mVmMode, v3_devfile, mStreamName);
715         // Re-enable updates to widgets
716         mVmControlPanel->setUpdatesEnabled(true);
717         consoleParent->setUpdatesEnabled(true);
718
719         // Signal to tell the background xterm process to quit when console widget is closed
720         connect(mRunningVms[pos], SIGNAL(windowClosingWithId(QString)), this,
721                         SLOT(consoleWindowClosed(QString)));
722         // Update VM state
723         updateVmState(VmInfo::RUNNING);
724         
725         for (int i=0; i<mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->childCount(); i++) {
726                 QTreeWidgetItem* child = mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->child(i);
727                 if (mVmName.compare(child->text(0)) == 0) {
728                         child->setIcon(0, QIcon(":/images/images/start_vm.png"));
729                         break;
730                 }
731         }
732 }
733
734 void NewPalacios::updateVmState(int mode) {
735         // TODO: Move this to a background thread
736         QString vm_name = mVmList[mVmPos]->getVmName();
737         
738         QFile file("virtual_machines_list.txt");
739         if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
740                 showMessage(tr(ERROR_UPDATE_VM_STATE), true);
741                 stopVm();
742                 return;
743         }
744
745         QFile temp("temp.txt");
746         if (!temp.open(QIODevice::WriteOnly | QIODevice::Text)) {
747                 showMessage(tr(ERROR_UPDATE_VM_STATE), true);
748                 stopVm();
749                 return;
750         }
751
752         QTextStream in(&file);
753         QTextStream out(&temp);
754
755         while (!in.atEnd()) {
756                 QString line = in.readLine();
757                 if (line.compare("\n") == 0) {
758                         continue;
759                 }
760                 
761                 QStringList vmDet = line.split(",");
762                 QString nameStr = vmDet.at(0);
763
764                 if (nameStr.compare(vm_name) == 0) {
765                         QString configStr = vmDet.at(1);
766                         QString devfileStr = vmDet.at(2);
767                         QString stateStr = vmDet.at(3);
768                         QString imageStr = vmDet.at(4);
769
770                         out << nameStr << "," << configStr << "," << devfileStr << "," << QString::number(mode) <<"," << imageStr << endl;
771                 } else {
772                         out << line << endl;
773                 }
774         }
775
776         out.flush();
777         file.remove("virtual_machines_list.txt");
778         temp.rename("virtual_machines_list.txt");
779
780         file.close();
781         temp.close();
782
783         // Update VM object
784         mVmList[mVmPos]->setState(mode);
785 }
786
787 void NewPalacios::stopVm() {
788         if (mVmList.isEmpty() 
789                 || mVmList[mVmPos]->getState() == VmInfo::STOPPED) {
790                 // If the VM list is empty or the VM is already stopped
791                 // or if the VM is passive
792                 // return
793                 showMessage(tr(ERROR_STOP_VM), false, true);
794                 return;
795         }
796
797         if (mVmList[mVmPos]->getCategory() == VmInfo::INACTIVE_INVENTORY
798                 || mVmList[mVmPos]->getCategory() == VmInfo::ACTIVE_NOT_INVENTORY) {
799                 // If the VM is inactive or active not inventory
800                 showMessage(tr(ERROR_VM_NOT_INVENTORY), true);
801                 return;
802         }
803
804         QString name = NULL;
805         QMessageBox vmStopWarningBox;
806         vmStopWarningBox.setText(VM_STOP_WARNING_MESSAGE);
807         vmStopWarningBox.setIcon(QMessageBox::Warning);
808         vmStopWarningBox.setStandardButtons(
809                         QMessageBox::Cancel | QMessageBox::Ok);
810         vmStopWarningBox.setDefaultButton(QMessageBox::Cancel);
811         int ret = vmStopWarningBox.exec();
812         int posInTabWidget = -1;
813         QStringList args;
814         QProcess* v3StopProc = NULL;
815
816         switch (ret) {
817         case QMessageBox::Ok:
818                 
819                 v3StopProc = new QProcess();
820                 v3StopProc->setProcessChannelMode(QProcess::MergedChannels);
821                 args << mVmList[mVmPos]->getVmDevFile();
822                 v3StopProc->start("v3_stop", args);
823                 if (!v3StopProc->waitForFinished()) {
824                     showMessage(tr(ERROR_STOP_VM_PATH), true);
825                     delete v3StopProc;
826                     return;
827
828                 } else if (v3StopProc->readAllStandardOutput().contains("Error opening V3Vee VM device")) {
829                     showMessage(tr(ERROR_STOP_VM_DEVICE_NOT_FOUND), true);
830                     delete v3StopProc;
831                     return;
832                 }
833
834                 name = mVmList[mVmPos]->getVmName();
835                 for (int i=0; i<mRunningVms.length(); i++) {
836                         if (name.compare(mRunningVms[i]->getVmName()) == 0) {
837                                 // Remove widget from tab if placed there
838                                 posInTabWidget = mVmControlPanel->indexOf(mRunningVms[i]);
839                                 if (posInTabWidget != -1) {
840                                         // Console is present in tab
841                                         mVmControlPanel->removeTab(posInTabWidget);
842                                 }
843                                 // Close the console
844                                 mRunningVms[i]->close();
845                                 // Remove it from list of running console windows
846                                 mRunningVms.removeAt(i);
847                                 break;
848                         }
849                 }
850
851                 // Update VM state
852                 updateVmState(VmInfo::STOPPED);
853                 
854                 // Update icon
855                 for (int i=0; i<mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->childCount(); i++) {
856                         QTreeWidgetItem* child = mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->child(i);
857                         if (mVmName.compare(child->text(0)) == 0) {
858                                 child->setIcon(0, QIcon(":/images/images/stop_vm.png"));
859                                 break;
860                         }
861                 }
862                 
863                 break;
864         case QMessageBox::Cancel:
865                 break;
866         }
867 }
868
869 void NewPalacios::pauseVm() {
870     if (mVmList.isEmpty()) {
871        return;
872     }
873         
874     if (mVmList[mVmPos]->getCategory() == VmInfo::INACTIVE_INVENTORY
875         || mVmList[mVmPos]->getCategory() == VmInfo::ACTIVE_NOT_INVENTORY) {
876         showMessage(tr(ERROR_VM_NOT_INVENTORY), false, true);
877         return;
878     }
879         
880     QString v3_devfile = mVmList[mVmPos]->getVmDevFile();
881     if (v3_devfile == NULL) {
882             showMessage(tr("Device file not found"), true);
883             return;
884     }
885
886     QProcess* v3Pauseproc = new QProcess();
887     v3Pauseproc->setProcessChannelMode(QProcess::MergedChannels);
888     QStringList args;
889     args << v3_devfile;
890     v3Pauseproc->start("v3_pause", args);
891     if (!v3Pauseproc->waitForFinished()) {
892         showMessage(v3Pauseproc->errorString(), true);
893     } else if (v3Pauseproc->readAllStandardOutput().contains("Error opening V3Vee VM device")) {
894         showMessage(tr(ERROR_PAUSE_VM_DEVICE_NOT_FOUND), true);
895     }
896         
897     // Update VM state
898     updateVmState(VmInfo::PAUSED);
899     
900     // Update icon
901     for (int i=0; i<mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->childCount(); i++) {
902         QTreeWidgetItem* child = mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->child(i);
903         if (mVmName.compare(child->text(0)) == 0) {
904                 child->setIcon(0, QIcon(":/images/images/pause_vm.png"));
905                 break;
906         }
907     }
908     
909     delete v3Pauseproc;
910 }
911
912 void NewPalacios::restartVm() {
913     if (mVmList.isEmpty()) {
914        return;
915     }
916
917     if (mVmList[mVmPos]->getCategory() == VmInfo::INACTIVE_INVENTORY
918         || mVmList[mVmPos]->getCategory() == VmInfo::ACTIVE_NOT_INVENTORY) {
919         showMessage(tr(ERROR_VM_NOT_INVENTORY), false, true);
920         return;
921     }
922
923     QString v3_devfile = mVmList[mVmPos]->getVmDevFile();
924     if (v3_devfile == NULL) {
925             showMessage(tr("Device file not found"), true);
926             return;
927     }
928
929     QProcess* v3Continueproc = new QProcess();
930     v3Continueproc->setProcessChannelMode(QProcess::MergedChannels);
931     QStringList args;
932     args << v3_devfile;
933     v3Continueproc->start("v3_continue", args);
934     
935     if (!v3Continueproc->waitForFinished()) {
936         showMessage(v3Continueproc->errorString(), true);
937     } else if (v3Continueproc->readAllStandardOutput().contains("Error opening V3Vee VM device")) {
938         showMessage(tr(ERROR_RESTART_VM_IOCTL), true);
939     }
940
941     // Update icon
942     for (int i=0; i<mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->childCount(); i++) {
943         QTreeWidgetItem* child = mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->child(i);
944         if (mVmName.compare(child->text(0)) == 0) {
945                 child->setIcon(0, QIcon(":/images/images/start_vm.png"));
946                 break;
947         }
948     }
949
950     delete v3Continueproc;
951 }
952
953 // Method to create a VM from inactive list
954 int NewPalacios::createInactiveVm() {
955         QString vmImageFile = mVmList[mVmPos]->getImageFile();
956         QString vmName = mVmList[mVmPos]->getVmName();
957         
958         // Create the VM instance
959         QProcess* v3CreateProc = new QProcess();
960         QStringList args;
961         args.clear();
962         args << vmImageFile << vmName;
963         v3CreateProc->start("v3_create", args);
964                 
965         if (v3CreateProc->waitForFinished()) {
966                 if (v3CreateProc->readAllStandardOutput().contains("Error (-1)")) {
967                         // v3_create has failed with IOCTL error
968                         showMessage(tr(ERROR_VM_CREATE_IOCTL), true);
969                         delete v3CreateProc;
970                         return -1;
971                 }
972         } else {
973                 showMessage(tr(ERROR_VM_CREATE_PATH), true);
974                 delete v3CreateProc;
975                 return -1;
976         }
977         
978         // Cleanup
979         delete v3CreateProc;
980         
981         // Check the last line of /proc/v3vee/v3-guests 
982         // to see the /dev/v3-vm# of the new VM
983         bool isCreated = false;
984         QProcess* proc = new QProcess();
985         proc->setProcessChannelMode(QProcess::MergedChannels);
986         proc->start("cat /proc/v3vee/v3-guests");
987                 
988         if (!proc->waitForFinished()) {
989                 showMessage(tr(ERROR_VM_CREATE_PROC), true);
990                 delete proc;
991                 return -1;
992         }
993         
994         //QByteArray temp = vmName.toAscii();
995         //const char* vmEntry = temp.data();
996         
997         // Read standard output of process
998         QByteArray val = proc->readAllStandardOutput();
999         if (!val.isNull()) {
1000                 // The created VM can be defined anywhere in the /proc file
1001                 // we need to go over all entries till we find it
1002                 QList<QByteArray> procs = val.split('\n');
1003                 for (int i=0; i<procs.size(); i++) {
1004                         QList<QByteArray> temp = procs[i].split('\t');
1005                         QByteArray a = temp.at(0);
1006                         QString vmProcName(a);
1007                         if (vmName.compare(vmProcName) == 0) {
1008                                 // We have found the VM, get dev file name
1009                                 QByteArray b = temp.at(1);
1010                                 QString vmDevFile(b);
1011                                 vmDevFile.remove(QChar('\n'), Qt::CaseInsensitive);
1012                                 mVmList[mVmPos]->setVmDevFile(vmDevFile);
1013                                 // Make VM instance active
1014                                 mVmList[mVmPos]->setCategory(VmInfo::ACTIVE_INVENTORY);
1015                                 isCreated = true;
1016                                 break;
1017                        }
1018                 }
1019         }
1020                 
1021         if (!isCreated) {
1022                 // We did not find an entry in
1023                 // /proc file so there must have
1024                 // been an error in creation
1025                 showMessage(tr(ERROR_VM_CREATE_FAILED), true);
1026                 delete proc;
1027                 return -1;
1028         }
1029         
1030         if (proc != NULL) 
1031             delete proc;
1032
1033         return 0;
1034 }
1035
1036 int NewPalacios::updateDb(int cat) {
1037         QString vm_name = mVmList[mVmPos]->getVmName();
1038         
1039         QFile file("virtual_machines_list.txt");
1040         if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
1041                 showMessage("Error opening DB! Please restart application", true);
1042                 return -1;
1043         }
1044
1045         QFile temp("temp.txt");
1046         if (!temp.open(QIODevice::WriteOnly | QIODevice::Text)) {
1047                 showMessage("Error opening DB! Please restart application", true);
1048                 return -1;
1049         }
1050         
1051         QTextStream in(&file);
1052         QTextStream out(&temp);
1053         
1054
1055         if (cat == VmInfo::INACTIVE_INVENTORY) {
1056                 // If we are updating an inactive entry
1057                 // search the file and update
1058                 while (!in.atEnd()) {
1059                         QString line = in.readLine();
1060                         if (line.compare("\n") == 0) {
1061                                 continue;
1062                         }
1063                         QStringList vmDet = line.split(",");
1064                         QString nameStr = vmDet.at(0);
1065                         
1066                         if (vm_name.compare(nameStr) != 0) {
1067                                 // If the name does not match, then copy to new place
1068                                 out << line << endl;
1069                         } else {
1070                                 // Update DB state
1071                                 VmInfo* v = mVmList[mVmPos];
1072                                 QString updateLine = v->getVmName()
1073                                         + "," + v->getVmConfigFile()
1074                                         + "," + v->getVmDevFile()
1075                                         + "," + QString::number(VmInfo::STOPPED)
1076                                         + "," + v->getImageFile();
1077                                 out << updateLine << endl;
1078                         }
1079                 }
1080         } else if (cat == VmInfo::ACTIVE_NOT_INVENTORY) {
1081                 
1082                 while (!in.atEnd()) {
1083                         QString line = in.readLine();
1084                         if (line.compare("\n") == 0) {
1085                                 continue;
1086                         }
1087                         
1088                         // Copy all the contents into new file
1089                         out << line << endl;
1090                 }
1091                 
1092                 // Copy the new VM info
1093                 VmInfo* vv = mVmList[mVmPos];
1094                 QString updateLine = vv->getVmName()
1095                         + "," + vv->getVmConfigFile()
1096                         + "," + vv->getVmDevFile()
1097                         + "," + QString::number(VmInfo::STOPPED)
1098                         + "," + vv->getImageFile();
1099                         out << updateLine << endl;
1100         }
1101
1102         out.flush();
1103         file.remove("virtual_machines_list.txt");
1104         temp.rename("virtual_machines_list.txt");
1105
1106         file.close();
1107         temp.close();
1108         
1109         return 0;
1110 }
1111
1112 void NewPalacios::activateVm() {
1113         // 1. Check VM category
1114         //      1a. If VM is active but not in inventory, upgrade category
1115         //      1b. If VM is inactive, create VM and upgrade category
1116         QTreeWidgetItem* item = NULL;
1117         
1118         // Remove VM from inactive list
1119         // The list could be from either the inactive inventory or
1120         // active not inventory
1121         int category = mVmList[mVmPos]->getCategory();
1122         
1123         if (category == VmInfo::ACTIVE_NOT_INVENTORY) {
1124                 // The VM exists in the /proc file and 
1125                 // is already created. We will only update
1126                 // VM category.
1127                 
1128                 // Ask user for Config file and Image file
1129                 QString configFile = QFileDialog::getOpenFileName(this, tr("Select config file"), ".",
1130                         "XML file (*.xml)");
1131                 if (configFile == NULL) {
1132                         // User pressed cancel
1133                         return;
1134                 }
1135                 QString imageFile = QFileDialog::getOpenFileName(this, tr("Select image file"), ".",
1136                         "Image file (*.img *.bZ)");
1137                 if (imageFile == NULL) {
1138                         // User pressed cancel
1139                         return;
1140                 }
1141                 
1142                 mVmList[mVmPos]->setVmConfigFile(configFile);
1143                 mVmList[mVmPos]->setImageFile(imageFile);
1144                 
1145                 // Remove from active not inventory list
1146                 for (int i=0; i<mVmTreeView->topLevelItem(VmInfo::ACTIVE_NOT_INVENTORY)->childCount(); i++) {
1147                         item = mVmTreeView->topLevelItem(VmInfo::ACTIVE_NOT_INVENTORY)->child(i);
1148                         if (item->text(0).compare(mVmList[mVmPos]->getVmName()) == 0) {
1149                                 item = mVmTreeView->topLevelItem(VmInfo::ACTIVE_NOT_INVENTORY)->takeChild(i);
1150                                 break;
1151                         }
1152                 }
1153                 
1154                 // Add it to active list
1155                 QTreeWidgetItem* subParent = mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY);
1156                 subParent->addChild(item);
1157                 
1158                 // Update Category
1159                 mVmList[mVmPos]->setCategory(VmInfo::ACTIVE_INVENTORY);
1160                 
1161                 // Update DB with newly created entry
1162                 updateDb(VmInfo::ACTIVE_NOT_INVENTORY);
1163                 return;
1164                 
1165         } else if (category == VmInfo::INACTIVE_INVENTORY) {
1166                 // The VM is in the inventory but inactive.
1167                 // This means that we need to create it.
1168                 int ret = createInactiveVm();
1169                 
1170                 if (ret != 0) {
1171                         // VM was not created due to some problem
1172                         // TODO: Decide if you want to delete the reference
1173                         // from the text file or keep it there for a while and
1174                         // try again
1175                         return;
1176                 }
1177                 
1178                 // Once VM is created, we need to first remove it from the 
1179                 // inactive list and add it to active list
1180                 for (int i=0; i<mVmTreeView->topLevelItem(VmInfo::INACTIVE_INVENTORY)->childCount(); i++) {
1181                         item = mVmTreeView->topLevelItem(VmInfo::INACTIVE_INVENTORY)->child(i);
1182                         if (item->text(0).compare(mVmList[mVmPos]->getVmName()) == 0) {
1183                                 item = mVmTreeView->topLevelItem(VmInfo::INACTIVE_INVENTORY)->takeChild(i);
1184                                 break;
1185                         }
1186                 }
1187                 
1188                 // Add it to active list
1189                 QTreeWidgetItem* subParent = mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY);
1190                 subParent->addChild(item);
1191                 
1192                 // Update DB with newly created entry
1193                 updateDb(VmInfo::INACTIVE_INVENTORY);
1194         }
1195 }
1196
1197 void NewPalacios::reloadVms() {
1198         // Clear all previous entries
1199         for (int i=0; i<mVmTreeView->topLevelItemCount(); i++) {
1200                 qDeleteAll(mVmTreeView->topLevelItem(i)->takeChildren());
1201         }
1202         
1203         // Call load VM thread
1204         readExistingVmsFile();
1205 }
1206
1207 // This handler is used in serial mode when user clicks
1208 // the close button of the floating window
1209 void NewPalacios::consoleWindowClosed(QString name) {
1210         // Remove the console from the list of
1211         // running consoles
1212         for (int i=0; i < mRunningVms.length(); i++) {
1213                 if (name.compare(mRunningVms[i]->getVmName()) == 0) {
1214                         mRunningVms.removeAt(i);
1215                         break;
1216                 }
1217         }
1218 }
1219
1220 // This handler is used in v3_cons_sc mode when the user clicks
1221 // the close button on the tab widget
1222 void NewPalacios::vmTabClosed(int index) {
1223         if (index == 0) {
1224                 // As of now do not remove the info tab
1225                 return;
1226         }
1227
1228         // Get the name of the VM tab which we need to close
1229         // Need to cast the return value of TabWidget->widget as it returns an object
1230         // of the base class. static_cast is used because the conversion is from base
1231         // class object to derived class object
1232         VmXConsoleParent* widget = static_cast<VmXConsoleParent*>(mVmControlPanel->widget(index));
1233         QString name = widget->getVmName();
1234         for (int i=0; i<mRunningVms.length(); i++) {
1235                 if (name.compare(mRunningVms[i]->getVmName()) == 0) {
1236                         // Remove the tab
1237                         mVmControlPanel->removeTab(index);
1238                         // Remove the console from running vm instances
1239                         mRunningVms.removeAt(i);
1240                         // Send close event to widget
1241                         widget->close();
1242                         break;
1243                 }
1244         }
1245 }
1246
1247 /* This function reads from the vm list file */
1248 void NewPalacios::readExistingVmsFile() {
1249         mThread = new QThread();
1250         mLoadVmsThread = new LoadVmsThread();
1251         mLoadVmsThread->moveToThread(mThread);
1252         connect(mThread, SIGNAL(started()), mLoadVmsThread, SLOT(loadVms()));
1253         connect(mLoadVmsThread, SIGNAL(finished()), mThread, SLOT(quit()));
1254         // Action which listens to completion of initial VM loading
1255         connect(mLoadVmsThread, SIGNAL(finished()), this,
1256                         SLOT(finishLoadingVmsFromFile()));
1257         mThread->start();
1258 }
1259
1260 // Update UI with VMs loaded from file
1261 void NewPalacios::finishLoadingVmsFromFile() {
1262         if (mLoadVmsThread->getStatus() == LoadVmsThread::STATUS_OK) {
1263                 mVmList.clear();
1264                 mVmPos = 0;
1265                 
1266                 int category = -1;
1267                 
1268                 // Load VMs into memory
1269                 mVmList.append(mLoadVmsThread->getVmList());
1270                 
1271                 QTreeWidgetItem* item = NULL;
1272                 for (int i = 0; i < mVmList.size(); i++) {
1273                         if (mVmList[i]->getCategory() == VmInfo::ACTIVE_INVENTORY) {
1274                                item = new QTreeWidgetItem();
1275                                item->setText(0, mVmList[i]->getVmName());
1276                                
1277                                category = mVmList[i]->getState();
1278                                switch (category) {
1279                                case VmInfo::STOPPED:
1280                                         item->setIcon(0, QIcon(":/images/images/stop_vm.png"));
1281                                         break;
1282                                case VmInfo::PAUSED:
1283                                         item->setIcon(0, QIcon(":/images/images/pause_vm.png"));
1284                                         break;
1285                                case VmInfo::RUNNING:
1286                                         item->setIcon(0, QIcon(":/images/images/start_vm.png"));
1287                                         break;
1288                                }
1289                                
1290                                mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY)->addChild(item);
1291                                
1292                         } else if (mVmList[i]->getCategory() == VmInfo::INACTIVE_INVENTORY) {
1293                                item = new QTreeWidgetItem();
1294                                item->setText(0, mVmList[i]->getVmName()); 
1295                                mVmTreeView->topLevelItem(VmInfo::INACTIVE_INVENTORY)->addChild(item);
1296                                
1297                         } else if (mVmList[i]->getCategory() == VmInfo::ACTIVE_NOT_INVENTORY) {
1298                                item = new QTreeWidgetItem();
1299                                item->setText(0, mVmList[i]->getVmName()); 
1300                                mVmTreeView->topLevelItem(VmInfo::ACTIVE_NOT_INVENTORY)->addChild(item);
1301                         }
1302                 }
1303                 
1304                 mVmControlPanel->insertTab(0, mVmInfoWidget, tr(VM_TAB_TITLE));
1305
1306                 if (mThread != NULL)
1307                     delete mThread;
1308
1309         }
1310 }
1311
1312 /* This method is called after completion of the VM wizard
1313  * It updates the backend vm file with new vm */
1314 void NewPalacios::addNewVm() {
1315         QString name = mVmWizard->field("guestName").toString();
1316         QString file = mVmWizard->field("configLoc").toString();
1317         QFileInfo f(mVmWizard->field("imageLoc").toString());
1318         QString img = f.fileName();
1319         
1320         mThread = new QThread();
1321         mAddVmThread = new AddVmThread(name, file, img);
1322         mAddVmThread->moveToThread(mThread);
1323         connect(mThread, SIGNAL(started()), mAddVmThread, SLOT(addVm()));
1324         connect(mAddVmThread, SIGNAL(finished()), mThread, SLOT(quit()));
1325         // Call method on window to update the vm list
1326         connect(mAddVmThread, SIGNAL(finished()), this, SLOT(updateVmList()));
1327         mThread->start();
1328 }
1329
1330 /* Update UI with new VM added to list */
1331 void NewPalacios::updateVmList() {
1332         if(mAddVmThread != NULL && mAddVmThread->getStatus()
1333                         == AddVmThread::ERROR_V3CREATE_DB) {
1334                 showMessage(tr(ERROR_VM_CREATE_DB), true);
1335
1336         } else if (mAddVmThread != NULL &&
1337                         mAddVmThread->getStatus() == AddVmThread::STATUS_OK) {
1338                 // Newly created VM is inactive but in inventory
1339                 showMessage(tr(SUCCESS_VM_ADDED), false);
1340                 mVmList.append(mAddVmThread->getNewVm());
1341                 QTreeWidgetItem* item = new QTreeWidgetItem();
1342                 item->setText(0, mAddVmThread->getName());
1343
1344                 QTreeWidgetItem* subParent = mVmTreeView->topLevelItem(VmInfo::INACTIVE_INVENTORY);
1345                 subParent->addChild(item);
1346         }
1347
1348         if (mThread != NULL)
1349             delete mThread;
1350 }
1351
1352 /* Handler to delete VM instance from list and backend file */
1353 void NewPalacios::deleteVm(QString item) {
1354         int category = -1;
1355         QString devfile;
1356
1357         for (int i = 0; i < mVmList.size(); i++) {
1358                 if (item.compare(mVmList[i]->getVmName()) == 0) {
1359                         category = mVmList[i]->getCategory();
1360                         devfile = mVmList[i]->getVmDevFile();
1361                         break;
1362                 }
1363         }
1364
1365         mThread = new QThread();
1366         mDeleteVmThread = new DeleteVmThread(category, item, devfile);
1367         mDeleteVmThread->moveToThread(mThread);
1368         connect(mThread, SIGNAL(started()), mDeleteVmThread, SLOT(deleteVm()));
1369         connect(mDeleteVmThread, SIGNAL(finished()), mThread, SLOT(quit()));
1370         connect(mDeleteVmThread, SIGNAL(finished()), this, SLOT(handleVmDeletion()));
1371         mThread->start();
1372 }
1373
1374 void NewPalacios::handleVmDeletion() {
1375         if (mDeleteVmThread->getStatus()
1376                         == DeleteVmThread::ERROR_V3FREE_PATH) {
1377                 showMessage(tr(ERROR_VM_DELETE_PATH), true);
1378
1379         } else if (mDeleteVmThread->getStatus()
1380                         == DeleteVmThread::ERROR_V3FREE_IOCTL) {
1381                 showMessage(tr(ERROR_VM_DELETE_IOCTL), true);
1382
1383         } else if (mDeleteVmThread->getStatus()
1384                         == DeleteVmThread::ERROR_V3FREE_DB) {
1385                 showMessage(tr(ERROR_VM_DELETE_DB), true);
1386
1387         } else if (mDeleteVmThread->getStatus()
1388                         == DeleteVmThread::ERROR_V3FREE_INVALID_ARGUMENT) {
1389                 showMessage(tr(ERROR_VM_DELETE_INVALID_ARGUMENT), true);    
1390
1391         } else if (mDeleteVmThread->getStatus()
1392                         == DeleteVmThread::STATUS_OK) {
1393                 // Delete VM from list
1394                 for (int i = 0; i < mVmList.size(); i++) {
1395                         if (mVmName.compare(mVmList[i]->getVmName()) == 0) {
1396                                 // Deletion is a little tricky
1397                                 // 1. Find the VM to be deleted and get its name
1398                                 // 2. Remove VM from list
1399                                 // 3. Determine the category
1400                                 // 4. Search the appropriate category for the VM
1401                                 // 5. Remove from UI widget and delete
1402                                 int cat = mVmList[i]->getCategory();
1403                                 mVmList.removeAt(i);
1404                                 
1405                                 if (cat == VmInfo::ACTIVE_INVENTORY) {
1406                                     QTreeWidgetItem* activeItems = mVmTreeView->topLevelItem(VmInfo::ACTIVE_INVENTORY);
1407                                     for (int j=0; j<activeItems->childCount(); j++) {
1408                                         QString n = activeItems->child(j)->text(0);
1409                                         if (mVmName.compare(n) == 0) {
1410                                                 QTreeWidgetItem* achild = activeItems->takeChild(j);
1411                                                 delete achild;
1412                                                 break;
1413                                         }
1414                                                 
1415                                     }
1416                                 } else if (cat == VmInfo::INACTIVE_INVENTORY) {
1417                                    QTreeWidgetItem* inactiveItems = mVmTreeView->topLevelItem(VmInfo::INACTIVE_INVENTORY);
1418                                    for (int j=0; j<inactiveItems->childCount(); j++) {
1419                                         QString in = inactiveItems->child(j)->text(0);
1420                                         if (mVmName.compare(in) == 0) {
1421                                                 QTreeWidgetItem* ichild = inactiveItems->takeChild(j);
1422                                                 delete ichild;
1423                                                 break;
1424                                         }
1425                                    }
1426                                 } else if (cat == VmInfo::ACTIVE_NOT_INVENTORY) {
1427                                         QTreeWidgetItem* activeNotInvItems = mVmTreeView->topLevelItem(VmInfo::ACTIVE_NOT_INVENTORY);
1428                                         for (int j=0; j<activeNotInvItems->childCount(); j++) {
1429                                              QString an = activeNotInvItems->child(j)->text(0);
1430                                              if (mVmName.compare(an) == 0) {
1431                                                      QTreeWidgetItem* aichild = activeNotInvItems->takeChild(j);
1432                                                      delete aichild;
1433                                                      break;
1434                                                 }
1435                                         }
1436                                 
1437                                 }
1438                                 
1439                                 // Clear VM from Info widget view
1440                                 mVmInfoWidget->deleteVm();
1441                                 break;
1442                         }
1443                 }
1444
1445                 showMessage(tr(SUCCESS_VM_DELETE), false);
1446         }
1447
1448         if (mThread != NULL)
1449             delete mThread;
1450 }