source: src-qt4/warden-gui/dialogwarden.cpp @ d71f644

releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since d71f644 was d71f644, checked in by Kris Moore <kris@…>, 7 months ago

Fix a bug in warden GUI, validate the hostname / IPs aren't in use before letting
the user continue to make a new jail

  • Property mode set to 100644
File size: 50.4 KB
Line 
1/****************************************************************************
2** ui.h extension file, included from the uic-generated form implementation.
3**
4** If you want to add, delete, or rename functions or slots, use
5** Qt Designer to update this file, preserving your code.
6**
7** You should not define a constructor or destructor in this file.
8** Instead, write your code in functions called init() and destroy().
9** These will automatically be called by the form's constructor and
10** destructor.
11****************************************************************************/
12#include "dialogwarden.h"
13#include <QDate>
14#include <QDebug>
15#include <QFileDialog>
16#include <QMessageBox>
17#include <QSettings>
18#include <QTextStream>
19#include <QTime>
20
21
22
23#include "dialogworking.h"
24#include "dialogconfig.h"
25#include "dialogdisplayoutput.h"
26#include "dialogimport.h"
27#include "dialogTemplates.h"
28#include "wizardNewJail.h"
29#include "pcbsd-utils.h"
30
31/* Update interval in ms  - Every 5 seconds */
32#define  UPDATE_MSEC 1000 * 5
33
34void dialogWarden::helpAbout()
35{
36
37}
38
39
40void dialogWarden::programInit()
41{ 
42   // Disable these until we check if the jail is running
43   pushTerminal->setEnabled(false);
44   pushPackageManager->setEnabled(false);
45
46   // Setup our listview options
47   listJails->setSelectionMode(QAbstractItemView::SingleSelection);
48   listJails->setAllColumnsShowFocus(TRUE);
49
50   // Run this a single time, just to be sure we did any jail import / migration
51   // from legacy jails
52   system("warden list");
53
54   // Hide the identifier column / host column
55   listJails->setColumnHidden(0, true);
56   listJails->setColumnWidth(1, 200);
57   listJails->setColumnWidth(2, 200);
58   listJails->setColumnWidth(3, 150);
59   listJails->setColumnWidth(4, 40);
60
61   groupJailTab->setTitle(tr("<- Please select a jail"));
62   groupJailTab->setEnabled(false);
63   
64   // Read in our configuration data
65   readConfig();
66
67   // Start our monitor service to check if jails are running
68   checkingStatus = false;
69   checkingUpdates = false;
70   currentStatusWorkingJail = "";
71   currentUpdateWorkingJail = "";
72   statusTimer = new QTimer(this);
73   connect( statusTimer, SIGNAL(timeout()), this, SLOT( slotMonitorJailStatus() ) );
74   slotMonitorJailStatus();
75   
76   // Start our monitor service for jail details
77   checkingDetails = false;
78   currentDetailsWorkingJail = "";
79   detailsTimer = new QTimer(this);
80   connect( detailsTimer, SIGNAL(timeout()), this, SLOT( slotMonitorJailDetails() ) );
81   slotMonitorJailDetails();
82   
83   // Start by refreshing our jail list
84   refreshJails();
85   
86   // Connect the rightclick slot
87   listJails->setContextMenuPolicy( Qt::CustomContextMenu);
88   connect( listJails, SIGNAL(customContextMenuRequested (const QPoint & ) ), this, SLOT(slotJailRightClicked() ) );
89   connect( listJails, SIGNAL(itemSelectionChanged() ), this, SLOT(slotCurrentJailChanged() ) );
90   connect( pushAdd, SIGNAL(clicked()), this, SLOT(slotClickedNewJail() ) );
91   connect( pushRemove, SIGNAL(clicked()), this, SLOT(slotDeleteJail() ) );
92   connect( pushExportJail, SIGNAL(clicked()), this, SLOT(slotExportJail() ) );
93   connect( pushServiceGUI, SIGNAL(clicked()), this, SLOT(slotServiceGUI() ) );
94   connect( pushTerminal, SIGNAL(clicked()), this, SLOT(slotTerminal() ) );
95   connect( pushUserAdmin, SIGNAL(clicked()), this, SLOT(slotUserAdmin() ) );
96   connect( pushConfigure, SIGNAL(clicked()), this, SLOT(slotPushEditIP() ) );
97   connect( pushPackageManager, SIGNAL(clicked()), this, SLOT(slotPushPackage() ) );
98   connect( pushUpdate, SIGNAL(clicked()), this, SLOT(slotUpdate() ) );
99   connect( pushStart, SIGNAL(clicked()), this, SLOT(slotStartJail() ) );
100
101   // Snapshot / Clone support
102   connect( pushAddClone, SIGNAL(clicked()), this, SLOT(slotAddClone() ) );
103   connect( pushRemoveClone, SIGNAL(clicked()), this, SLOT(slotRemoveClone() ) );
104   connect( pushCreateSnap, SIGNAL(clicked()), this, SLOT(slotCreateSnap() ) );
105   connect( pushRestoreSnap, SIGNAL(clicked()), this, SLOT(slotRestoreSnap() ) );
106   connect( pushRemoveSnap, SIGNAL(clicked()), this, SLOT(slotRemoveSnap() ) );
107   //connect( sliderSnaps, SIGNAL(sliderMoved(int)), this, SLOT(slotSnapSliderChanged(int) ) );
108   connect( sliderSnaps, SIGNAL(valueChanged(int)), this, SLOT(slotSnapSliderChanged(int) ) );
109
110   // Snapshot cron support
111   connect( comboSnapFrequency, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCronSnapshotChanged() ) );
112   connect( spinSnapDays, SIGNAL(valueChanged(int)), this, SLOT(slotCronSnapshotChanged() ) );
113   connect( groupSnapSchedule, SIGNAL(clicked(bool)), this, SLOT(slotCronSnapshotChanged() ) );
114
115   QTimer::singleShot(100, this, SLOT(slotCheckNic()) );
116
117   // Disable the start button until status's come back
118   pushStart->setEnabled(false);
119}
120
121
122void dialogWarden::slotCheckNic() 
123{
124   QString NIC = pcbsd::Utils::getValFromPCConf("/usr/local/etc/warden.conf", "NIC");
125   if ( system("ifconfig " + NIC.toLatin1() + " >/dev/null 2>/dev/null") != 0 )
126   {
127      // Confirm with user
128      int ret = QMessageBox::warning(this, tr("Warden"),
129                                tr("No valid network interface specified! Select one now?"),
130                                QMessageBox::Yes | QMessageBox::No,
131                                QMessageBox::No);
132      if ( ret == QMessageBox::No)
133         return;
134
135      slotOpenConfig();
136   }
137}
138
139void dialogWarden::refreshJails()
140{
141   QString jType, jName, jZFS;
142   QStringList jD;
143   QStringList mountOut;
144 
145   update();
146   
147   listJails->clear();
148   jailDetails.clear();
149   
150   // Check our JailDir and see what we have
151   QDir d(JailDir);
152   d.setFilter(QDir::Dirs | QDir::Hidden);
153   d.setNameFilters(QStringList() << ".*.meta");
154
155   // Start mount cmd
156   QProcess m;
157   m.start(QString("mount"), QStringList());
158   while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
159      m.waitForFinished(200);
160      QCoreApplication::processEvents();
161   }
162   // Get output of mount now
163   while (m.canReadLine())
164     mountOut << m.readLine().simplified();
165
166   for ( unsigned int i = 0; i < d.count(); i++ ) {
167       
168       // Traverse our directories, looking for jails
169       if ( d[i] == "." || d[i] == ".." )
170          continue;
171
172       jD.clear();
173
174       qDebug() << "Checking:" << d[i];
175
176       jName = d[i].replace(".meta", "").remove(0, 1);
177           
178       // Check if this jail is created on ZFS
179       jZFS="NO";
180       for (int z = 0; z < mountOut.size(); ++z)
181          if ( mountOut.at(z).indexOf("on " + JailDir + "/" + jName) != -1 && mountOut.at(z).indexOf("(zfs,") != -1 )
182             jZFS="YES";
183
184       // Check for the hostname of this jail
185       QFile file( JailDir + "/" + d[i] + "/host" );
186       if ( ! file.exists() )
187          continue;
188       if ( ! file.open( QIODevice::ReadOnly ) )
189          continue;
190       QTextStream stream( &file );
191       QString host;
192       while ( !stream.atEnd() )
193          host = stream.readLine(); // line of text excluding '\n'
194       file.close();
195           
196       // Build list of IPs for this jail
197       QString jIPs = "";
198       QStringList ipFiles;
199       ipFiles << "ipv4" << "ipv6";
200       for (int f = 0; f < ipFiles.size(); ++f) {
201         QFile fileip(JailDir + "/" + d[i] + "/" + ipFiles.at(f) );
202         if ( fileip.exists() ) {
203           if (fileip.open( QIODevice::ReadOnly ) ) {
204              QTextStream stream2( &fileip );
205              while ( !stream2.atEnd() )
206                jIPs = jIPs + stream2.readLine().simplified() + " "; // line of text excluding '\n'
207           }
208           fileip.close();
209         }
210       }
211       qDebug() << jIPs;
212
213       // Check the type of jail
214       jType = "Traditional";
215       QFile file3(JailDir + "/" + d[i] + "/jail-portjail" );
216       if ( file3.exists() )
217         jType = "Ports Jail";
218       QFile filelin(JailDir + "/" + d[i] + "/jail-linux" );
219       if ( filelin.exists() )
220         jType = "Linux Jail";
221
222       // Display the jail in the tree widget now
223       QStringList cols;
224       cols << jName << host;
225
226       QTreeWidgetItem *curItem = new QTreeWidgetItem( listJails, cols );
227       if ( ! listJails->currentItem() )
228         listJails->setCurrentItem(curItem);
229
230       // Save additional jail details into list
231       jD << jName << "Pending" << jType << jIPs << "" << "" << "" << jZFS;
232       jailDetails << jD;
233   
234   } // end of loop
235   
236   listJails->sortByColumn(1, Qt::AscendingOrder);
237   update();
238
239   slotCurrentJailChanged();
240
241   // Now refresh jail details
242   slotMonitorJailDetails();
243   
244}
245
246
247void dialogWarden::readConfig()
248{ 
249   
250    ProgDir = "/usr/local/share/warden";
251    TMPDIR = pcbsd::Utils::getValFromPCConf("/usr/local/etc/warden.conf", "WTMP");
252    JailDir = pcbsd::Utils::getValFromPCConf("/usr/local/etc/warden.conf", "JDIR");
253   
254}
255
256
257void dialogWarden::slotOpenConfig()
258{
259        // Launch our AddPartitionDialog to add a new device
260        configDialog = new dialogConfig();
261        connect(configDialog, SIGNAL(saved()),this, SLOT(readConfig()) );
262        configDialog->programInit();
263        configDialog->exec();
264
265}
266
267
268void dialogWarden::slotExit()
269{
270    exit(0);
271}
272
273void dialogWarden::slotCheckJailDetails()
274{
275    QString oldWorking = currentDetailsWorkingJail;
276    int found = 0;
277    // Mark that we are in the middle of checking the details
278    checkingDetails = true;
279   
280    // Read in our iterator and start checking jail status
281    QTreeWidgetItemIterator it( listJails );
282    while (*it) {
283       
284        if ( currentDetailsWorkingJail.isEmpty() ) {
285            currentDetailsWorkingJail = (*it)->text(0);
286            break;
287        }
288       
289        if ( found == 1) {
290          currentDetailsWorkingJail = (*it)->text(0);
291          break;
292        }
293       
294        if ( currentDetailsWorkingJail == (*it)->text(0) )
295            found = 1;
296       
297        ++it;
298    }
299   
300   
301    // Are we ready to take a break?
302    if ( currentDetailsWorkingJail == oldWorking ) {
303        checkingDetails = false;
304        currentDetailsWorkingJail="";
305        return;
306    }
307
308    // Build list of IPs for this jail
309    QString jIPs = "";
310    QStringList ipFiles;
311    ipFiles << "ipv4" << "ipv6";
312    for (int f = 0; f < ipFiles.size(); ++f) {
313       QFile fileip(JailDir + "/." + currentDetailsWorkingJail + ".meta/" + ipFiles.at(f) );
314       if ( fileip.exists() ) {
315         if (fileip.open( QIODevice::ReadOnly ) ) {
316            QTextStream stream2( &fileip );
317            while ( !stream2.atEnd() )
318             jIPs = jIPs + stream2.readLine().simplified() + " "; // line of text excluding '\n'
319         }
320         fileip.close();
321       }
322    }
323    qDebug() << "Found IPS:" << jIPs;
324
325    // Save the new jail IPs
326    for (int i=0; i < jailDetails.count(); ++i) {
327      if ( jailDetails.at(i).at(0) != currentDetailsWorkingJail )
328         continue;     
329      QStringList tmpList = jailDetails.at(i);
330      tmpList.replace(3, jIPs);
331      jailDetails.replace(i, tmpList);
332    }
333
334
335    // Run the getUpdatesDir.sh script to rsync with master server
336    detailsProc = new QProcess( this );
337    QString program = ProgDir + "/scripts/backend/details.sh";
338    QStringList args;
339    args << currentDetailsWorkingJail;
340
341    qDebug() << "Checking for details to: " << currentDetailsWorkingJail;
342   
343    // Connect the exited signal and start the process
344    connect( detailsProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotCheckDetailsReturn() ) );
345    detailsProc->start(program, args);
346}
347
348
349void dialogWarden::slotMonitorJailDetails()
350{
351  if ( checkingDetails == true) {
352       // Set our timer to check again
353       detailsTimer->start( 1000 * 60 * 10 );
354  } else {
355      currentDetailsWorkingJail = "";
356      slotCheckJailDetails();
357      // Set our timer to check again
358      detailsTimer->start( 1000 * 60 * 10 );
359  }
360
361  if ( checkingUpdates == true) {
362       // Set our timer to check again
363       detailsTimer->start( 1000 * 60 * 10 );
364  } else {
365      currentUpdateWorkingJail = "";
366      slotCheckForUpdates();
367      // Set our timer to check again
368      detailsTimer->start( 1000 * 60 * 10 );
369  }
370
371}
372
373void dialogWarden::slotCheckForUpdates()
374{
375    qDebug() << "Starting Update Check...";
376
377    QString oldWorking = currentUpdateWorkingJail;
378    checkingUpdates = true;
379
380    int found = 0;
381
382    // Read in our iterator and start checking jail status
383    QTreeWidgetItemIterator it( listJails );
384    while (*it) {
385        if ( currentUpdateWorkingJail.isEmpty() ) {
386            currentUpdateWorkingJail = (*it)->text(0);
387            break;
388        }
389        if ( found == 1)
390        {
391          currentUpdateWorkingJail = (*it)->text(0);
392          break;
393        }
394        if ( currentUpdateWorkingJail == (*it)->text(0) )
395            found = 1;
396        ++it;
397    }
398   
399   
400    // Are we ready to take a break?
401    if ( currentUpdateWorkingJail == oldWorking ) {
402        checkingUpdates = false;
403        currentUpdateWorkingJail="";
404        qDebug() << "Finished Update Check...";
405        return;
406    }
407
408    updateProc = new QProcess( this );
409    QString program = "warden";
410    QStringList args;
411    args << "checkup" << currentUpdateWorkingJail;
412   
413    // Connect the exited signal and start the process
414    connect( updateProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotCheckUpdateReturn() ) );
415    updateProc->start(program, args);
416
417}
418
419void dialogWarden::slotCheckUpdateReturn()
420{
421    bool haveUp = false;
422    QString line;
423
424    while (updateProc->canReadLine()) {
425        line = updateProc->readLine().simplified();
426        qDebug() << "Update output..." << line;
427        if ( line.indexOf("The following package updates") == 0 ) {
428         haveUp = true;
429         break;
430        }
431        if ( line.indexOf("The following files will be updated") == 0 ) {
432         haveUp = true;
433         break;
434        }
435    }
436
437    // Read in our iterator and update jail update status
438    QTreeWidgetItemIterator it( listJails );
439    while (*it) {
440      if ( currentUpdateWorkingJail == (*it)->text(0) )
441        break;
442      ++it;
443    }
444
445    if ( ! (*it) )
446       return;
447
448
449    qDebug() << (*it)->text(0) << haveUp;
450
451    if ( haveUp ) {
452      (*it)->setText(4, tr("Updates available!"));
453      (*it)->setIcon(4, QIcon(":updateavail.png"));
454    } else {
455      (*it)->setText(4, "");
456      (*it)->setIcon(4, QIcon());
457    }
458
459    slotCheckForUpdates();
460}
461
462void dialogWarden::slotCheckDetailsReturn()
463{
464    QString line, size, ports, connections;
465
466    // Read the output and parse
467    while ( detailsProc->canReadLine() )
468    {
469        line = detailsProc->readLine().simplified();
470        if ( line.indexOf("Disk Usage: ") == 0 ) {
471          line.replace("Disk Usage: ", "");
472          size = line;
473          continue;
474        }
475        if ( line.indexOf("Active Ports: ") == 0 ) {
476          line.replace("Active Ports: ", "");
477          ports = line;
478          continue;
479        }
480        if ( line.indexOf("Current Connections: ") == 0 ) {
481          line.replace("Current Connections: ", "");
482          connections = line;
483          continue;
484        }
485    }
486
487    // Now save details into our array
488    for (int i=0; i < jailDetails.count(); ++i) {
489      if ( jailDetails.at(i).at(0) != currentDetailsWorkingJail )
490         continue;     
491      QStringList tmpList = jailDetails.at(i);
492
493      if ( jailDetails.at(i).at(1) == "Pending" )
494         tmpList.replace(1, "Complete");
495
496      tmpList.replace(4, size);
497      tmpList.replace(5, ports);
498      tmpList.replace(6, connections);
499      jailDetails.replace(i, tmpList);
500    }
501   
502    // See if we can update the GUI details
503    refreshJailDetailsView();
504
505    // Check the next jail, if there are any more left.
506    slotCheckJailDetails();
507}
508
509void dialogWarden::slotCheckJailStatus()
510{
511    QString oldWorking = currentStatusWorkingJail;
512    int found = 0;
513    // Mark that we are in the middle of checking the status
514    checkingStatus = true;
515   
516    // Read in our iterator and start checking jail status
517    QTreeWidgetItemIterator it( listJails );
518    while (*it) {
519       
520        if ( currentStatusWorkingJail.isEmpty() ) {
521            currentStatusWorkingJail = (*it)->text(0);
522            break;
523        }
524       
525        if ( found == 1)
526        {
527          currentStatusWorkingJail = (*it)->text(0);
528          break;
529        }
530       
531        if ( currentStatusWorkingJail == (*it)->text(0) )
532        {
533            found = 1;
534        }
535       
536       
537        ++it;
538    }
539   
540   
541    // Are we ready to take a break?
542    if ( currentStatusWorkingJail == oldWorking ) {
543        checkingStatus = false;
544        currentStatusWorkingJail="";
545        return;
546    }
547
548    // Run the getUpdatesDir.sh script to rsync with master server
549    statusProc = new QProcess( this );
550    QString program = ProgDir + "/scripts/backend/checkstatus.sh";
551    QStringList args;
552    args << currentStatusWorkingJail;
553   
554    // Connect the exited signal and start the process
555    connect( statusProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotCheckStatusReturn() ) );
556    statusProc->start(program, args);
557}
558
559
560void dialogWarden::slotMonitorJailStatus()
561{
562    if ( checkingStatus == true) {
563       // Set our timer to check again
564       statusTimer->start( UPDATE_MSEC );
565  } else {
566      currentStatusWorkingJail = "";
567      slotCheckJailStatus();
568      // Set our timer to check again
569      statusTimer->start( UPDATE_MSEC );
570  }
571
572}
573
574
575void dialogWarden::slotCheckStatusReturn()
576{
577
578    // Check the exit status
579    int exitStatus = statusProc->exitCode();
580    bool running;
581   
582        // Read in our iterator and locate the jail, changing its status
583    QTreeWidgetItemIterator it( listJails );
584    while (*it) {
585        if ( currentStatusWorkingJail == (*it)->text(0) )
586        {
587            if ( exitStatus == 0) {
588                running = true;
589                (*it)->setIcon(1, QIcon(":running.png"));
590                (*it)->setText(2, "Running");
591            } else {
592                running = false;
593                (*it)->setIcon(1, QIcon(":stopped.png"));
594                (*it)->setText(2, "Not Running");
595            }
596
597            // See if we can update push buttons
598            if ( listJails->currentItem()) {
599              if ( listJails->currentItem()->text(0) == currentStatusWorkingJail ) {
600                if ( running ) {
601                  pushPackageManager->setEnabled(true);
602                  pushTerminal->setEnabled(true);
603                  pushStart->setEnabled(true);
604                  pushStart->setIcon(QIcon(":stopjail.png"));
605                  pushStart->setIconSize(QSize(16,16));
606                  pushStart->setToolTip(tr("Stop the selected jail"));
607                } else {
608                  pushPackageManager->setEnabled(false);
609                  pushTerminal->setEnabled(false);
610                  pushStart->setEnabled(true);
611                  pushStart->setIcon(QIcon(":running.png"));
612                  pushStart->setIconSize(QSize(16,16));
613                  pushStart->setToolTip(tr("Start the selected jail"));
614                }
615              }
616            }
617            break;
618        }
619        ++it;
620    }
621   
622    // Check the next jail, if there are any more left.
623    slotCheckJailStatus();
624}
625
626
627
628
629void dialogWarden::slotJailRightClicked()
630{
631    QString Status, Updates;
632
633    if ( listJails->currentItem()) {
634          popupip = listJails->currentItem()->text(0);
635          Status = listJails->currentItem()->text(2);
636          Updates = listJails->currentItem()->text(3);
637          popup = new QMenu();
638          if ( Status == "Running" )
639              popup->addAction( tr("Stop this Jail") , this, SLOT(slotStopJail() )  );
640          else
641              popup->addAction( tr("Start this Jail") , this, SLOT(slotStartJail() )  );
642          popup->addSeparator();
643          if ( ! Updates.isEmpty() )
644              popup->addAction( tr("Start update manager") , this, SLOT(slotUpdate() )  );
645          popup->addAction( tr("Toggle Autostart") , this, SLOT(slotToggleAutostartClicked() )  );
646          popup->addAction( tr("Export jail to .wdn file") , this, SLOT(slotExportJail() )  );
647          popup->addSeparator();
648          popup->addAction( tr("Delete Jail") , this, SLOT(slotDeleteJail() )  );
649          popup->exec( QCursor::pos() );
650
651
652    }
653
654   
655}
656
657
658void dialogWarden::slotStopJail()
659{
660        if ( !listJails->currentItem())
661          return;
662
663        QString tmp;
664        popupip = listJails->currentItem()->text(0);
665       
666        // Launch our working dialog to prevent further action until we are finished
667        workingDialog = new dialogWorking();
668        workingDialog->setModal(true);
669        workingDialog->programInit();
670        tmp = tr("Stopping Jail");
671        workingDialog->setDialogTitle(tmp);
672        tmp = tr("Stopping Jail:") + " " + popupip;
673        workingDialog->setDialogText(tmp);
674        workingDialog->show();
675       
676       
677      // Now start the script to stop this jail
678      stopJailProc = new QProcess( this );
679      QString program = "warden";
680      QStringList args;
681      args << "stop" <<popupip;
682     
683      // Connect the exited signal and start the process
684      connect( stopJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishedWorking() ) );
685      stopJailProc->start(program, args);
686      pushStart->setEnabled(false);
687       
688}
689
690
691void dialogWarden::slotStartJail()
692{
693        if ( !listJails->currentItem())
694          return;
695
696        // If jail is running, lets stop it
697        if ( listJails->currentItem()->text(2) == "Running" ) {
698           slotStopJail();
699           return;
700        }
701
702        QString tmp;
703        popupip = listJails->currentItem()->text(0);
704       
705        // Launch our working dialog to prevent further action until we are finished
706        workingDialog = new dialogWorking();
707        workingDialog->setModal(true);
708        workingDialog->programInit();
709        tmp = tr("Starting Jail");
710        workingDialog->setDialogTitle(tmp);
711        tmp = tr("Starting Jail:") + " " + popupip;
712        workingDialog->setDialogText(tmp);
713        workingDialog->show();
714       
715       
716      // Now start the script to stop this jail
717      startJailProc = new QProcess( this );
718      QString program =  "warden";
719      QStringList args;
720      args << "start" << popupip;
721     
722      // Connect the exited signal and start the process
723      connect( startJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishedWorking() ) );
724      startJailProc->start(program, args);
725      pushStart->setEnabled(false);
726}
727
728
729
730void dialogWarden::slotExportJail()
731{
732    QString exportFile, tmp;
733   
734    exportFile = QFileDialog::getExistingDirectory(
735                    this,
736                    tr("Choose a directory to save the finished .wdn file:"),
737                    "/root",
738                    QFileDialog::ShowDirsOnly );
739   
740    if ( exportFile.isEmpty() )
741    {
742        return;
743    }
744   
745      // Lauch the command output dialog
746      dialogOutput = new dialogDisplayOutput();
747      dialogOutput->setModal(true);
748      dialogOutput->programInit(FALSE);
749      dialogOutput->setDialogCaption(tr("Exporting Jail:") + " " + popupip);
750      dialogOutput->setDialogText("");
751      tmp = tr("Exporting Jail:") + " " + popupip + "\n";
752      dialogOutput->appendDialogText(tmp);
753      dialogOutput->show();
754   
755      // Now start the script to stop this jail
756      exportJailProc = new QProcess( this );
757      QString program = "warden";
758      QStringList args;
759      args << "export" << popupip << "--dir=" + exportFile;
760     
761      // Connect the exited signal and start the process
762      connect( exportJailProc, SIGNAL(readyReadStandardOutput()), this, SLOT(slotReadExportOutput() ) );
763      connect( exportJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishedExport() ) );
764      exportJailProc->start(program, args);
765   
766}
767
768void dialogWarden::slotFinishedExport()
769{
770  dialogOutput->setCloseHide( false );
771}
772
773void dialogWarden::slotListJailPkgs()
774{
775
776   
777      dialogOutput = new dialogDisplayOutput();
778      dialogOutput->setModal(true);
779      dialogOutput->programInit(TRUE);
780      dialogOutput->setDialogCaption("Jail Packages: " + popupip);
781      dialogOutput->setDialogText("");
782      dialogOutput->show();
783   
784          // Now start the script to stop this jail
785      listPackagesProc = new QProcess( this );
786      QString program = ProgDir + "/scripts/backend/listpkgs.sh";
787      QStringList args;
788      args << popupip;
789
790      listPackagesProc->setProcessChannelMode(QProcess::MergedChannels);
791      listPackagesProc->setReadChannel(QProcess::StandardOutput);
792
793      // Connect the exited signal and start the process
794      connect( listPackagesProc, SIGNAL(readyReadStandardOutput ()), this, SLOT(slotReadPkgsOutput() ) );
795
796      listPackagesProc->start(program, args);
797}
798
799
800void dialogWarden::slotDeleteJail()
801{
802    QString tmp;
803
804    if ( ! listJails->currentItem() )
805      return;
806
807    popupip = listJails->currentItem()->text(0);
808
809    // Confirm with user
810    int ret = QMessageBox::warning(this, tr("Warden"),
811                                tr("Are you sure you want to delete the jail") + ": " + popupip,
812                                QMessageBox::Yes | QMessageBox::No,
813                                QMessageBox::No);
814    if ( ret == QMessageBox::No)
815      return;
816   
817    // Launch our working dialog to prevent further action until we are finished
818    workingDialog = new dialogWorking();
819    workingDialog->setModal(true);
820    workingDialog->programInit();
821    tmp = tr("Deleting Jail");
822    workingDialog->setDialogTitle(tmp);
823    tmp = tr("Deleting Jail:") + " " + popupip;
824    workingDialog->setDialogText(tmp);
825    workingDialog->show();
826 
827    // Now start the script to stop this jail
828    deleteJailProc = new QProcess( this );
829    QString program = ProgDir + "/scripts/backend/deletejail.sh";
830    QStringList args;
831    args << popupip;
832   
833    // Connect the exited signal and start the process
834    connect( deleteJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(refreshJails() ) );
835    connect( deleteJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishedWorking() ) );
836    deleteJailProc->start(program, args);
837}
838
839
840
841
842void dialogWarden::slotFinishedWorking()
843{
844        // Finished whatever we were working on, hide the dialog now.
845        workingDialog->hide();
846        slotCurrentJailChanged();
847}
848
849
850void dialogWarden::runCommand( QString command )
851{
852        FILE *file = popen(command.toLatin1(),"r");
853        fclose(file);
854}
855
856
857void dialogWarden::slotReadExportOutput()
858{
859    while ( exportJailProc->canReadLine() )
860        dialogOutput->appendDialogText(exportJailProc->readLine());
861}
862
863
864void dialogWarden::slotFinishedOutput()
865{
866    // Hide the output dialog, not needed anymore
867    dialogOutput->hide();
868}
869
870
871void dialogWarden::slotReadPkgsOutput()
872{
873   
874    while ( listPackagesProc->canReadLine() )
875    {
876        dialogOutput->appendDialogText(listPackagesProc->readLine());
877    }
878}
879
880
881void dialogWarden::slotClickedNewJail()
882{
883      QStringList uH, uI;
884
885       // Launch our working dialog to prevent further action until we are finished
886      newJailWizard = new wizardNewJail();
887      newJailWizard->setModal(true);
888      newJailWizard->programInit();
889
890      // Build list of used jail IP / Hosts
891      QTreeWidgetItemIterator it( listJails );
892      int i = 0;
893      while (*it) {
894         uH << (*it)->text(0);
895         uI << jailDetails.at(i).at(3);
896         ++it;
897         i++;
898      }
899      newJailWizard->setHostIPUsed(uH, uI);
900     
901      connect( newJailWizard, SIGNAL(create(const QString &, const QString &, const QString &, bool, bool, const QString &, bool, bool, bool, bool, const QString &, const QString &)), this, SLOT(slotCreateNewJail(const QString &, const QString &, const QString &, bool, bool, const QString &, bool, bool, bool, bool, const QString &, const QString &) ) );
902      newJailWizard->show();
903}
904
905
906void dialogWarden::slotCreateNewJail( const QString &IP, const QString &IP6, const QString &host, bool tradjail, bool PCUtils, const QString &rootpw, bool src, bool ports, bool autostart, bool linuxJail, const QString &linuxScript, const QString &tplate )
907{
908    if ( tradjail || linuxJail )
909      newRootPW=rootpw;
910    else
911      newRootPW="";
912   
913    newHost=host;
914
915    /***********************************************************************************************************************
916        Now create the jail here
917    *************************************************************************************************************************/
918      dialogOutput = new dialogDisplayOutput();
919      dialogOutput->setModal(false);
920      dialogOutput->programInit(FALSE);
921      dialogOutput->setDialogCaption("Creating Jail: " + IP);
922      dialogOutput->setDialogText("");
923      dialogOutput->show();
924   
925   
926      // Now start the script to stop this jail
927      createJailProc = new QProcess( this );
928      QString program = "warden";
929      QStringList args;
930      args << "create" << host;
931
932      // Set our optional flags
933      if ( ! IP.isEmpty() ) {
934        args << "--ipv4";
935        args << IP;
936      }
937
938      if ( ! IP6.isEmpty() ) {
939        args << "--ipv6";
940        args << IP6;
941      }
942
943      if ( ! linuxJail && ! tplate.isEmpty() )
944        args << "--template" << tplate.section(" ", 0, 0);
945
946      if ( tradjail && ! PCUtils )
947        args << "--vanilla";
948
949      if ( ! tradjail && ! linuxJail )
950        args << "--portjail";
951
952      if ( src && ! linuxJail)
953        args << "--src";
954
955      if ( ports && ! linuxJail )
956        args <<  "--ports";
957
958      if ( linuxJail )
959        args <<  "--linuxjail" << linuxScript ;
960
961      if ( autostart )
962        args << "--startauto";
963
964      // Connect the exited signal and start the process
965      createJailProc->setProcessChannelMode(QProcess::MergedChannels);
966      createJailProc->setReadChannel(QProcess::StandardOutput);
967      connect( createJailProc, SIGNAL(readyReadStandardOutput ()), this, SLOT(slotReadCreateOutput() ) );
968      connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishedJailCreate() ) );
969      createJailProc->start(program, args);
970   
971}
972
973
974void dialogWarden::slotReadCreateOutput()
975{
976    while ( createJailProc->canReadLine() )
977    {
978        dialogOutput->appendDialogText(createJailProc->readLine());
979    }
980}
981
982
983void dialogWarden::slotFinishedJailCreate()
984{
985    // If this doesn't need a root pw, or doesn't have one
986    if ( newRootPW.isEmpty() ) {
987      slotFinishedUserAdd();
988      return;
989    }
990
991    // Jail is done creating, now set rootpw
992    userAddProc = new QProcess( this );
993    QString program = ProgDir + "/scripts/backend/setupusers.sh";
994    QStringList args;
995    args << newHost << newRootPW;
996     
997    // Connect the exited signal and start the process
998    userAddProc->setProcessChannelMode(QProcess::MergedChannels);
999    userAddProc->setReadChannel(QProcess::StandardOutput);
1000    connect( userAddProc, SIGNAL(readyReadStandardOutput()), this, SLOT(slotReadUserAddOutput() ) );
1001    connect( userAddProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishedUserAdd() ) );
1002    userAddProc->start(program, args);
1003
1004}
1005
1006
1007void dialogWarden::slotReadUserAddOutput()
1008{
1009    while ( userAddProc->canReadLine() )
1010    {
1011        dialogOutput->appendDialogText(userAddProc->readLine());
1012    }
1013}
1014
1015
1016void dialogWarden::slotFinishedUserAdd()
1017{
1018    // All finished with creating a jail and adding a username to it
1019   
1020    // Unhide the close button
1021    dialogOutput->setCloseHide(FALSE);
1022
1023    // Refresh our jail list
1024    refreshJails();
1025}
1026
1027
1028void dialogWarden::slotImportJailClicked()
1029{
1030      // The user wants to import a jail, lets prompt for the .wdn file to use
1031      importFile="";
1032   
1033      importFile = QFileDialog::getOpenFileName(
1034                    this,
1035                    tr("Select warden jail package"),
1036                    "/home",
1037                    "Warden Jail Packs (*.wdn)");
1038     
1039      if ( importFile.isEmpty() )
1040          return;
1041
1042      // Bring up dialog to ask about import settings
1043      importDialog = new dialogImport();
1044      importDialog->programInit();
1045      connect( importDialog, SIGNAL(import(const QString &, const QString &)), this, SLOT(slotImportConfigDone(const QString &, const QString &) ) );
1046      importDialog->show();
1047
1048}
1049
1050void dialogWarden::slotImportConfigDone(const QString &IP, const QString &Host)
1051{
1052
1053      // Display the import dialog output
1054      dialogOutput = new dialogDisplayOutput();
1055      dialogOutput->setModal(false);
1056      dialogOutput->programInit(FALSE);
1057      dialogOutput->setDialogCaption("Importing Jail");
1058      dialogOutput->setDialogText("");
1059      dialogOutput->show();
1060
1061      importJailProc = new QProcess( this );
1062      QString program = "warden";
1063      QStringList args;
1064      args << "import" << importFile;
1065      if ( ! IP.isEmpty() )
1066        args << "--ipv4=" + IP + "/24";
1067      if ( ! Host.isEmpty() )
1068        args << "--host=" + Host;
1069
1070      qDebug() << args;
1071     
1072      // Connect the exited signal and start the process
1073      importJailProc->setProcessChannelMode(QProcess::MergedChannels);
1074      importJailProc->setReadChannel(QProcess::StandardOutput);
1075      connect( importJailProc, SIGNAL(readyReadStandardOutput ()), this, SLOT(slotReadImportOutput() ) );
1076      connect( importJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishedJailImport()));
1077      importJailProc->start(program, args);
1078
1079}
1080
1081
1082void dialogWarden::slotReadImportOutput()
1083{
1084    while ( importJailProc->canReadLine() )
1085    {
1086        dialogOutput->appendDialogText(importJailProc->readLine());
1087    }
1088}
1089
1090
1091void dialogWarden::slotFinishedJailImport()
1092{
1093    // All finished with importing a jail
1094   
1095    // Unhide the close button
1096    dialogOutput->setCloseHide(FALSE);
1097   
1098       // Refresh our jail list
1099    refreshJails();
1100}
1101
1102void dialogWarden::slotToggleAutostartClicked()
1103{
1104    // Change auto-start status of the jail
1105    //runCommand("warden auto " + popupip);
1106   
1107    toggleAutoProc = new QProcess( this );
1108    QString program = "warden";
1109    QStringList args;
1110    args << "auto" << popupip;
1111
1112     
1113    // Connect the exited signal and start the process
1114    connect( toggleAutoProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(refreshJails() ) );
1115    toggleAutoProc->start(program, args);
1116   
1117}
1118
1119void dialogWarden::refreshJailDetailsView()
1120{
1121   if ( ! listJails->currentItem() )
1122     return;
1123
1124   QString tmp;
1125
1126   // Load the details for this jail
1127   for (int i=0; i < jailDetails.count(); ++i) {
1128     if ( jailDetails.at(i).at(0) != listJails->currentItem()->text(0) )
1129        continue;
1130
1131     // Depending upon the type of jail, we may need to hide stuff
1132     if ( jailDetails.at(i).at(2) == "Linux Jail" ) {
1133        pushServiceGUI->setHidden(true);
1134        pushPackageManager->setHidden(true);
1135        pushUserAdmin->setHidden(true);
1136        pushUpdate->setHidden(true);
1137        tabJail->setTabEnabled(3, false);
1138     } else {
1139        pushServiceGUI->setHidden(false);
1140        pushPackageManager->setHidden(false);
1141        pushUserAdmin->setHidden(false);
1142        pushUpdate->setHidden(false);
1143        tabJail->setTabEnabled(3, true);
1144     }
1145
1146     // Load the details now
1147     labelType->setText(jailDetails.at(i).at(2));
1148     labelIPs->setText(jailDetails.at(i).at(3));
1149
1150     // Not all details available, stop here
1151     if ( jailDetails.at(i).at(1) == "Pending" ) {
1152        labelSize->setText(tr("Loading..."));
1153        labelPorts->setText(tr("Loading..."));
1154        labelConnections->setText(tr("Loading..."));
1155        break;
1156     }
1157
1158     labelSize->setText(jailDetails.at(i).at(4));
1159     tmp =jailDetails.at(i).at(5);
1160     tmp.replace(",", " " );
1161     labelPorts->setText(tmp);
1162     labelConnections->setText(jailDetails.at(i).at(6));
1163
1164     // Is this jail ZFS?
1165     if ( jailDetails.at(i).at(7) == "YES" ) {
1166        groupSnaps->setEnabled(false); 
1167        labelSnap->setText(tr("Loading snapshots..."));
1168        QTimer::singleShot(50, this, SLOT(slotLoadSnapshots()) );
1169     } else {
1170        groupSnaps->setEnabled(false); 
1171        groupSnapSchedule->setEnabled(false); 
1172        labelSnap->setText(tr("For snapshot support you must be using ZFS"));
1173     }
1174
1175     // Done loading all details
1176     break;
1177   }
1178
1179}
1180
1181void dialogWarden::slotLoadSnapshots()
1182{
1183   if ( ! listJails->currentItem() )
1184      return;
1185
1186   bool ok, ok2;
1187
1188   groupSnaps->setEnabled(false); 
1189   groupSnapSchedule->setEnabled(false); 
1190   labelSnap->setText(tr("Loading snapshots..."));
1191   disconnect(spinSnapDays, SIGNAL(valueChanged(int)), 0, 0);
1192   disconnect(comboSnapFrequency, SIGNAL(currentIndexChanged(int)), 0, 0);
1193   // Load the snapshot schedule
1194   QFile file(JailDir + "/." + listJails->currentItem()->text(0) + ".meta/cron" );
1195   if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
1196      QTextStream streamfreq( &file );
1197      if ( streamfreq.readLine().simplified() == "hourly" )
1198         comboSnapFrequency->setCurrentIndex(1);
1199      else
1200         comboSnapFrequency->setCurrentIndex(0);
1201      file.close();
1202
1203     // Now see how many are set to keep
1204     QFile file2(JailDir + "/." + listJails->currentItem()->text(0) + ".meta/cron-keep" );
1205     if ( file2.exists() && file2.open( QIODevice::ReadOnly ) ) {
1206        QTextStream streamkeep( &file2 );
1207        int keep = streamkeep.readLine().toInt(&ok);
1208        if ( ok )
1209            spinSnapDays->setValue(keep);
1210     }
1211     groupSnapSchedule->setChecked(true); 
1212   } else {
1213     comboSnapFrequency->setCurrentIndex(0);
1214     spinSnapDays->setValue(10);
1215     groupSnapSchedule->setChecked(false); 
1216   }
1217
1218   groupSnapSchedule->setEnabled(true); 
1219   connect( comboSnapFrequency, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCronSnapshotChanged() ) );
1220   connect( spinSnapDays, SIGNAL(valueChanged(int)), this, SLOT(slotCronSnapshotChanged() ) );
1221   // Done loading snapshot schedule
1222
1223   QString IP = listJails->currentItem()->text(0);
1224
1225   // Grab the ZFS snapshot list
1226   QProcess m;
1227   m.start(QString("warden"), QStringList() << "zfslistsnap" << IP );
1228   while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
1229      m.waitForFinished(200);
1230      QCoreApplication::processEvents();
1231   }
1232
1233   // Check if the user changed jails before we finished loading snaps
1234   if ( ! listJails->currentItem() )
1235      return;
1236   if ( IP != listJails->currentItem()->text(0))
1237     return;
1238
1239   snapshotList.clear();
1240   QString tmp;
1241
1242   qDebug() << "Getting ZFS snapshots for " + IP;
1243
1244   // Get output of ZFS snapshots
1245   while (m.canReadLine()) {
1246      tmp = m.readLine().simplified();
1247      tmp.section("-", 0, 0).toInt(&ok);
1248      tmp.section("-", 1, 1).toInt(&ok2);
1249      if (ok && ok2) {
1250         snapshotList << tmp;
1251      }
1252   }
1253
1254   qDebug() << "Available Snapshots:" << snapshotList;
1255
1256   // If this jail has no snapshots, show that
1257   if ( snapshotList.count() <= 0 ) {
1258     labelSnap->setText(tr("No snapshots available. You may create one below."));
1259     groupSnaps->setEnabled(true); 
1260     sliderSnaps->setEnabled(false);
1261     pushRestoreSnap->setEnabled(false);
1262     pushRemoveSnap->setEnabled(false);
1263     pushAddClone->setEnabled(false);
1264     pushRemoveClone->setEnabled(false);
1265     return;
1266   }
1267
1268   // List snapshots
1269   sliderSnaps->setRange(0, snapshotList.count() - 1 );
1270   sliderSnaps->setValue(snapshotList.count() -1 );
1271   tmp="";
1272   if ( hasClone(snapshotList.at(snapshotList.count()-1)) )
1273      tmp = tr("(Cloned)");
1274 
1275   labelSnap->setText(getSnapDateReadable(snapshotList.at(snapshotList.count()-1)) + " " + tmp);
1276   sliderSnaps->setEnabled(true);
1277   pushRestoreSnap->setEnabled(true);
1278   pushRemoveSnap->setEnabled(true);
1279
1280   slotLoadClones();
1281}
1282
1283bool dialogWarden::hasClone(QString snap)
1284{
1285   for (int i = 0; i < cloneList.size(); ++i)
1286     if ( cloneList.at(i) == snap )
1287        return true;
1288
1289   return false;
1290}
1291
1292void dialogWarden::slotLoadClones()
1293{
1294   if ( ! listJails->currentItem() )
1295      return;
1296
1297   labelClone->setText(tr("Loading clones..."));
1298
1299   QString IP = listJails->currentItem()->text(0);
1300
1301   // Grab the ZFS clone list
1302   QProcess m;
1303   m.start(QString("warden"), QStringList() << "zfslistclone" << IP );
1304   while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
1305      m.waitForFinished(200);
1306      QCoreApplication::processEvents();
1307   }
1308
1309   // Check if the user changed jails before we finished loading snaps
1310   if ( ! listJails->currentItem() )
1311      return;
1312   if ( IP != listJails->currentItem()->text(0))
1313     return;
1314
1315   cloneList.clear();
1316   QString tmp;
1317   bool ok, ok2;
1318
1319   qDebug() << "Getting ZFS clones for " + IP;
1320
1321   // Get output of ZFS Clones
1322   while (m.canReadLine()) {
1323      tmp = m.readLine().simplified();
1324      tmp.section("-", 0, 0).toInt(&ok);
1325      tmp.section("-", 1, 1).toInt(&ok2);
1326      if (ok && ok2) {
1327         cloneList << tmp;
1328      }
1329   }
1330
1331   qDebug() << "Available Clones:" << cloneList;
1332
1333   if ( snapshotList.count() <= 0 ) {
1334     pushRemoveClone->setEnabled(false);
1335     pushAddClone->setEnabled(false);
1336   } else
1337     slotSnapSliderChanged(snapshotList.count()-1);
1338
1339   // If we did something and want to show the same snapshot
1340   if ( currentSnapshot != -1 ) {
1341     sliderSnaps->setValue(currentSnapshot );
1342     slotSnapSliderChanged(currentSnapshot);
1343   }
1344     
1345
1346   groupSnaps->setEnabled(true); 
1347}
1348
1349QString dialogWarden::getSnapDateReadable(QString time)
1350{
1351   QDate date;
1352   QTime timestr;
1353   if ( time.count('-') == 1 ) {
1354     // Old Style
1355     date = QDate::fromString(time.section("-", 0, 0), "yyyyMMdd");
1356     timestr = QTime::fromString(time.section("-", 1, 1), "hhmmss");
1357   } else {
1358     // New Style
1359     date = QDate::fromString(time.section("-", 0, 2), "yyyy-MM-dd");
1360     timestr = QTime::fromString(time.section("-", 3, 5), "hh-mm-ss");
1361   }
1362   
1363   return QString(date.toString("ddd MMMM d',' yyyy") + " @ " + timestr.toString("h:mm:ss ap"));
1364}
1365
1366void dialogWarden::slotCurrentJailChanged()
1367{
1368   if ( ! listJails->currentItem() ) {
1369
1370     groupJailTab->setEnabled(false);
1371     groupJailTab->setTitle(tr("No jail selected!"));
1372     labelSize->setText("");
1373     labelPorts->setText("");
1374     labelConnections->setText("");
1375     labelType->setText("");
1376     labelIPs->setText("");
1377     labelStartAtBoot->setText("");
1378     pushStart->setEnabled(false);
1379     return;
1380   }
1381
1382   currentSnapshot = -1;
1383   //pushStart->setEnabled(false);
1384
1385   if ( listJails->currentItem()->text(2) == "Running" ) {
1386     //pushStart->setEnabled(true);
1387     pushTerminal->setEnabled(true);
1388     pushPackageManager->setEnabled(true);
1389     pushStart->setIcon(QIcon(":stopjail.png"));
1390     pushStart->setIconSize(QSize(16,16));
1391     pushStart->setToolTip(tr("Stop the selected jail"));
1392   }
1393   if ( listJails->currentItem()->text(2) == "Not Running" ) {
1394     //pushStart->setEnabled(true);
1395     pushTerminal->setEnabled(false);
1396     pushPackageManager->setEnabled(false);
1397     pushStart->setIcon(QIcon(":running.png"));
1398     pushStart->setIconSize(QSize(16,16));
1399     pushStart->setToolTip(tr("Start the selected jail"));
1400   }
1401
1402   groupJailTab->setTitle(tr("Working on jail:") + " " + listJails->currentItem()->text(0));
1403   groupJailTab->setEnabled(true);
1404
1405   QString AutoStart = "Disabled";
1406   QFile file2(JailDir + "/." + listJails->currentItem()->text(0) + ".meta/autostart" );
1407   if ( file2.exists() )
1408      AutoStart = "Enabled";
1409   labelStartAtBoot->setText(AutoStart);
1410
1411   refreshJailDetailsView();
1412
1413}
1414
1415void dialogWarden::slotUserAdmin()
1416{
1417   if ( ! listJails->currentItem() )
1418     return;
1419   QString cmd = "pc-usermanager -warden /usr/jails/" + listJails->currentItem()->text(0) + " " + listJails->currentItem()->text(0) + " &"; 
1420   system(cmd.toLatin1());
1421   
1422}
1423
1424void dialogWarden::slotServiceGUI()
1425{
1426   if ( ! listJails->currentItem() )
1427     return;
1428   QString cmd = "pc-servicemanager -warden /usr/jails/" + listJails->currentItem()->text(0) + " " + listJails->currentItem()->text(0) + " &"; 
1429   system(cmd.toLatin1());
1430}
1431
1432void dialogWarden::slotTerminal()
1433{
1434   if ( ! listJails->currentItem() )
1435     return;
1436
1437   pcbsd::Utils::runInTerminal(QString("warden chroot ") + listJails->currentItem()->text(0),
1438                        QString("Jail: ") + listJails->currentItem()->text(0));
1439}
1440
1441void dialogWarden::slotPushEditIP()
1442{
1443
1444   if ( ! listJails->currentItem() )
1445     return;
1446
1447   dIP = new dialogEditIP();
1448   connect(dIP, SIGNAL(saved()),this, SLOT(slotMonitorJailDetails()) );
1449   dIP->programInit(listJails->currentItem()->text(0));
1450   dIP->exec();
1451
1452}
1453
1454void dialogWarden::slotPushPackage()
1455{
1456   
1457   if ( ! listJails->currentItem() )
1458     return;
1459   QString cmd = "pc-pkgmanager -chroot /usr/jails/" + listJails->currentItem()->text(0) + " &"; 
1460   system(cmd.toLatin1());
1461}
1462
1463
1464void dialogWarden::slotUpdate()
1465{
1466   
1467   if ( ! listJails->currentItem() )
1468     return;
1469   QString cmd = "pc-updategui -warden /usr/jails/" + listJails->currentItem()->text(0) + " " + listJails->currentItem()->text(0) + " &"; 
1470   system(cmd.toLatin1());
1471}
1472
1473void dialogWarden::slotAddClone()
1474{
1475   if ( ! listJails->currentItem() )
1476      return;
1477
1478   // Update status
1479   groupSnaps->setEnabled(false); 
1480   labelSnap->setText(tr("Cloning snapshot... Please wait..."));
1481
1482   QString IP = listJails->currentItem()->text(0);
1483
1484   // Now start the script to stop this jail
1485   createJailProc = new QProcess( this ); 
1486   QString program = "warden";
1487   QStringList args;
1488   args << "zfsclonesnap" << IP << snapshotList.at(sliderSnaps->value());
1489
1490   // Connect the exited signal and start the process
1491   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1492   createJailProc->setReadChannel(QProcess::StandardOutput);
1493   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1494   createJailProc->start(program, args);
1495
1496   currentSnapshot = sliderSnaps->value();
1497
1498}
1499
1500void dialogWarden::slotRemoveClone()
1501{
1502   if ( ! listJails->currentItem() )
1503      return;
1504
1505   // Update status
1506   groupSnaps->setEnabled(false); 
1507   labelSnap->setText(tr("Removing clone... Please wait..."));
1508
1509   QString IP = listJails->currentItem()->text(0);
1510
1511   // Now start the script to stop this jail
1512   createJailProc = new QProcess( this ); 
1513   QString program = "warden";
1514   QStringList args;
1515   args << "zfsrmclone" << IP << snapshotList.at(sliderSnaps->value());
1516
1517   // Connect the exited signal and start the process
1518   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1519   createJailProc->setReadChannel(QProcess::StandardOutput);
1520   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1521   createJailProc->start(program, args);
1522
1523   currentSnapshot = sliderSnaps->value();
1524}
1525
1526
1527void dialogWarden::slotCreateSnap()
1528{
1529   if ( ! listJails->currentItem() )
1530      return;
1531
1532   currentSnapshot = -1;
1533
1534   // Update status
1535   groupSnaps->setEnabled(false); 
1536   labelSnap->setText(tr("Creating new snapshot... Please wait..."));
1537
1538   QString IP = listJails->currentItem()->text(0);
1539
1540   // Now start the script to stop this jail
1541   createJailProc = new QProcess( this ); 
1542   QString program = "warden";
1543   QStringList args;
1544   args << "zfsmksnap" << IP;
1545
1546   // Connect the exited signal and start the process
1547   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1548   createJailProc->setReadChannel(QProcess::StandardOutput);
1549   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1550   createJailProc->start(program, args);
1551
1552}
1553
1554void dialogWarden::slotRestoreSnap()
1555{
1556   // Update status
1557   currentSnapshot = -1;
1558
1559   QString IP = listJails->currentItem()->text(0);
1560
1561   int ret = QMessageBox::question(this, tr("Warden"),
1562                                tr("Are you sure you want to revert to the snapshot:") + "\n" + getSnapDateReadable(snapshotList.at(sliderSnaps->value() ) ) + "?" + "\n" + tr("Any newer snapshots and mounted clones will be lost, and the jail will be restarted!"),
1563                                QMessageBox::Yes | QMessageBox::No,
1564                                QMessageBox::No);
1565   if ( ret != QMessageBox::Yes )
1566      return;
1567
1568   groupSnaps->setEnabled(false); 
1569   labelSnap->setText(tr("Reverting snapshot... Please wait..."));
1570
1571   dialogOutput = new dialogDisplayOutput();
1572   dialogOutput->setModal(true);
1573   dialogOutput->programInit(FALSE);
1574   dialogOutput->setDialogCaption(tr("Reverting snapshot"));
1575   dialogOutput->setDialogText(tr("Reverting to snapshot:") + " " + getSnapDateReadable(snapshotList.at(sliderSnaps->value() ) ));
1576   dialogOutput->show();
1577   
1578
1579   // Revert the snapshot
1580   createJailProc = new QProcess( this ); 
1581   QString program = "warden";
1582   QStringList args;
1583   args << "zfsrevertsnap" << IP << snapshotList.at(sliderSnaps->value());
1584
1585   // Connect the exited signal and start the process
1586   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1587   createJailProc->setReadChannel(QProcess::StandardOutput);
1588   connect( createJailProc, SIGNAL(readyReadStandardOutput ()), this, SLOT(slotReadCreateOutput() ) );
1589   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotShowDialogCloseButton() ) );
1590   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1591   createJailProc->start(program, args);
1592
1593
1594}
1595
1596void dialogWarden::slotRemoveSnap()
1597{
1598
1599   QString IP = listJails->currentItem()->text(0);
1600
1601   currentSnapshot = -1;
1602
1603   int ret = QMessageBox::question(this, tr("Warden"),
1604                                tr("Are you sure you want to remove the snapshot:") + "\n" + getSnapDateReadable(snapshotList.at(sliderSnaps->value() ) ) + "?",
1605                                QMessageBox::Yes | QMessageBox::No,
1606                                QMessageBox::No);
1607   if ( ret != QMessageBox::Yes )
1608      return;
1609
1610   // Update status
1611   groupSnaps->setEnabled(false); 
1612   labelSnap->setText(tr("Removing snapshot... Please wait..."));
1613
1614   // Remove the snapshot
1615   createJailProc = new QProcess( this ); 
1616   QString program = "warden";
1617   QStringList args;
1618   args << "zfsrmsnap" << IP << snapshotList.at(sliderSnaps->value());
1619
1620   // Connect the exited signal and start the process
1621   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1622   createJailProc->setReadChannel(QProcess::StandardOutput);
1623   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1624   createJailProc->start(program, args);
1625
1626}
1627
1628
1629void dialogWarden::slotSnapSliderChanged(int newVal)
1630{ 
1631   QString IP = listJails->currentItem()->text(0);
1632   QString tmp;
1633   int cloneId = -1;
1634   if ( hasClone(snapshotList.at(newVal)) ) {
1635      tmp = tr("(Cloned)");
1636      pushAddClone->setEnabled(false);
1637      pushRemoveClone->setEnabled(true);
1638      pushRemoveSnap->setEnabled(false);
1639
1640      for (int i = 0; i < cloneList.size(); ++i)
1641        if ( cloneList.at(i) == snapshotList.at(newVal) )
1642           cloneId = i;
1643
1644      if ( cloneId != -1 )
1645        // List the clone
1646        labelClone->setText(tr("Mounted on: ") + "/usr/jails/clones/" + IP + "-" + cloneList.at(cloneId) );
1647
1648   } else {
1649      labelClone->setText(tr("Snapshot not mounted"));
1650      pushAddClone->setEnabled(true);
1651      pushRemoveClone->setEnabled(false);
1652      pushRemoveSnap->setEnabled(true);
1653   }
1654   labelSnap->setText(getSnapDateReadable(snapshotList.at(newVal)) + " " + tmp);
1655}
1656
1657void dialogWarden::slotShowDialogCloseButton()
1658{
1659    // Unhide the close button
1660    dialogOutput->setCloseHide(FALSE);
1661}
1662
1663void dialogWarden::slotCronSnapshotChanged()
1664{
1665   QString IP = listJails->currentItem()->text(0);
1666
1667   if ( groupSnapSchedule->isChecked() ) {
1668     qDebug() << "Enabling cron snapshots";
1669     QProcess m;
1670     m.start(QString("warden"), QStringList() << "zfscronsnap" << IP << "start" << comboSnapFrequency->currentText() << QString::number(spinSnapDays->value()) );
1671     while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
1672        m.waitForFinished(200);
1673        QCoreApplication::processEvents();
1674     }
1675   } else {
1676     qDebug() << "Disabling cron snapshots";
1677     QProcess m;
1678     m.start(QString("warden"), QStringList() << "zfscronsnap" << IP << "stop" );
1679     while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
1680        m.waitForFinished(200);
1681        QCoreApplication::processEvents();
1682     }
1683   }
1684
1685}
1686
1687void dialogWarden::slotSingleInstance()
1688{
1689  this->hide();
1690  this->showNormal();
1691  this->activateWindow();
1692  this->raise();
1693}
1694
1695void dialogWarden::slotTemplateOpen()
1696{
1697   tempDialog = new dialogTemplates();
1698   tempDialog->programInit();
1699   tempDialog->exec();
1700}
Note: See TracBrowser for help on using the repository browser.