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

9.1-release9.2-releasereleng/10.0releng/10.0.1releng/10.0.2
Last change on this file since 42584ef was 42584ef, checked in by Kris Moore <kris@…>, 15 months ago

Welcome pc-pkgmanager to warden jails!

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