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

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1releng/10.1.1
Last change on this file since 5dbb9c2 was 5dbb9c2, checked in by Kris Moore <kris@…>, 20 months ago

Add new template combobox to warden GUI, which will allow users to pick from other FreeBSD version/arch templates

  • Property mode set to 100644
File size: 50.0 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 &, 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 << IP << Host;
1065
1066     
1067      // Connect the exited signal and start the process
1068      importJailProc->setProcessChannelMode(QProcess::MergedChannels);
1069      importJailProc->setReadChannel(QProcess::StandardOutput);
1070      connect( importJailProc, SIGNAL(readyReadStandardOutput ()), this, SLOT(slotReadImportOutput() ) );
1071      connect( importJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishedJailImport()));
1072      importJailProc->start(program, args);
1073
1074}
1075
1076
1077void dialogWarden::slotReadImportOutput()
1078{
1079    while ( importJailProc->canReadLine() )
1080    {
1081        dialogOutput->appendDialogText(importJailProc->readLine());
1082    }
1083}
1084
1085
1086void dialogWarden::slotFinishedJailImport()
1087{
1088    // All finished with importing a jail
1089   
1090    // Unhide the close button
1091    dialogOutput->setCloseHide(FALSE);
1092   
1093       // Refresh our jail list
1094    refreshJails();
1095}
1096
1097void dialogWarden::slotToggleAutostartClicked()
1098{
1099    // Change auto-start status of the jail
1100    //runCommand("warden auto " + popupip);
1101   
1102    toggleAutoProc = new QProcess( this );
1103    QString program = "warden";
1104    QStringList args;
1105    args << "auto" << popupip;
1106
1107     
1108    // Connect the exited signal and start the process
1109    connect( toggleAutoProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(refreshJails() ) );
1110    toggleAutoProc->start(program, args);
1111   
1112}
1113
1114void dialogWarden::refreshJailDetailsView()
1115{
1116   if ( ! listJails->currentItem() )
1117     return;
1118
1119   QString tmp;
1120
1121   // Load the details for this jail
1122   for (int i=0; i < jailDetails.count(); ++i) {
1123     if ( jailDetails.at(i).at(0) != listJails->currentItem()->text(0) )
1124        continue;
1125
1126     // Depending upon the type of jail, we may need to hide stuff
1127     if ( jailDetails.at(i).at(2) == "Linux Jail" ) {
1128        pushServiceGUI->setHidden(true);
1129        pushUserAdmin->setHidden(true);
1130        pushUpdate->setHidden(true);
1131        tabJail->setTabEnabled(3, false);
1132     } else {
1133        pushServiceGUI->setHidden(false);
1134        pushUserAdmin->setHidden(false);
1135        pushUpdate->setHidden(false);
1136        tabJail->setTabEnabled(3, true);
1137     }
1138
1139     // Load the details now
1140     labelType->setText(jailDetails.at(i).at(2));
1141     labelIPs->setText(jailDetails.at(i).at(3));
1142
1143     // Not all details available, stop here
1144     if ( jailDetails.at(i).at(1) == "Pending" ) {
1145        labelSize->setText(tr("Loading..."));
1146        labelPorts->setText(tr("Loading..."));
1147        labelConnections->setText(tr("Loading..."));
1148        break;
1149     }
1150
1151     labelSize->setText(jailDetails.at(i).at(4));
1152     tmp =jailDetails.at(i).at(5);
1153     tmp.replace(",", " " );
1154     labelPorts->setText(tmp);
1155     labelConnections->setText(jailDetails.at(i).at(6));
1156
1157     // Is this jail ZFS?
1158     if ( jailDetails.at(i).at(7) == "YES" ) {
1159        groupSnaps->setEnabled(false); 
1160        labelSnap->setText(tr("Loading snapshots..."));
1161        QTimer::singleShot(50, this, SLOT(slotLoadSnapshots()) );
1162     } else {
1163        groupSnaps->setEnabled(false); 
1164        groupSnapSchedule->setEnabled(false); 
1165        labelSnap->setText(tr("For snapshot support you must be using ZFS"));
1166     }
1167
1168     // Done loading all details
1169     break;
1170   }
1171
1172}
1173
1174void dialogWarden::slotLoadSnapshots()
1175{
1176   if ( ! listJails->currentItem() )
1177      return;
1178
1179   bool ok, ok2;
1180
1181   groupSnaps->setEnabled(false); 
1182   groupSnapSchedule->setEnabled(false); 
1183   labelSnap->setText(tr("Loading snapshots..."));
1184   disconnect(spinSnapDays, SIGNAL(valueChanged(int)), 0, 0);
1185   disconnect(comboSnapFrequency, SIGNAL(currentIndexChanged(int)), 0, 0);
1186   // Load the snapshot schedule
1187   QFile file(JailDir + "/." + listJails->currentItem()->text(0) + ".meta/cron" );
1188   if ( file.exists() && file.open( QIODevice::ReadOnly ) ) {
1189      QTextStream streamfreq( &file );
1190      if ( streamfreq.readLine().simplified() == "hourly" )
1191         comboSnapFrequency->setCurrentIndex(1);
1192      else
1193         comboSnapFrequency->setCurrentIndex(0);
1194      file.close();
1195
1196     // Now see how many are set to keep
1197     QFile file2(JailDir + "/." + listJails->currentItem()->text(0) + ".meta/cron-keep" );
1198     if ( file2.exists() && file2.open( QIODevice::ReadOnly ) ) {
1199        QTextStream streamkeep( &file2 );
1200        int keep = streamkeep.readLine().toInt(&ok);
1201        if ( ok )
1202            spinSnapDays->setValue(keep);
1203     }
1204     groupSnapSchedule->setChecked(true); 
1205   } else {
1206     comboSnapFrequency->setCurrentIndex(0);
1207     spinSnapDays->setValue(10);
1208     groupSnapSchedule->setChecked(false); 
1209   }
1210
1211   groupSnapSchedule->setEnabled(true); 
1212   connect( comboSnapFrequency, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCronSnapshotChanged() ) );
1213   connect( spinSnapDays, SIGNAL(valueChanged(int)), this, SLOT(slotCronSnapshotChanged() ) );
1214   // Done loading snapshot schedule
1215
1216   QString IP = listJails->currentItem()->text(0);
1217
1218   // Grab the ZFS snapshot list
1219   QProcess m;
1220   m.start(QString("warden"), QStringList() << "zfslistsnap" << IP );
1221   while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
1222      m.waitForFinished(200);
1223      QCoreApplication::processEvents();
1224   }
1225
1226   // Check if the user changed jails before we finished loading snaps
1227   if ( ! listJails->currentItem() )
1228      return;
1229   if ( IP != listJails->currentItem()->text(0))
1230     return;
1231
1232   snapshotList.clear();
1233   QString tmp;
1234
1235   qDebug() << "Getting ZFS snapshots for " + IP;
1236
1237   // Get output of ZFS snapshots
1238   while (m.canReadLine()) {
1239      tmp = m.readLine().simplified();
1240      tmp.section("-", 0, 0).toInt(&ok);
1241      tmp.section("-", 1, 1).toInt(&ok2);
1242      if (ok && ok2) {
1243         snapshotList << tmp;
1244      }
1245   }
1246
1247   qDebug() << "Available Snapshots:" << snapshotList;
1248
1249   // If this jail has no snapshots, show that
1250   if ( snapshotList.count() <= 0 ) {
1251     labelSnap->setText(tr("No snapshots available. You may create one below."));
1252     groupSnaps->setEnabled(true); 
1253     sliderSnaps->setEnabled(false);
1254     pushRestoreSnap->setEnabled(false);
1255     pushRemoveSnap->setEnabled(false);
1256     pushAddClone->setEnabled(false);
1257     pushRemoveClone->setEnabled(false);
1258     return;
1259   }
1260
1261   // List snapshots
1262   sliderSnaps->setRange(0, snapshotList.count() - 1 );
1263   sliderSnaps->setValue(snapshotList.count() -1 );
1264   tmp="";
1265   if ( hasClone(snapshotList.at(snapshotList.count()-1)) )
1266      tmp = tr("(Cloned)");
1267 
1268   labelSnap->setText(getSnapDateReadable(snapshotList.at(snapshotList.count()-1)) + " " + tmp);
1269   sliderSnaps->setEnabled(true);
1270   pushRestoreSnap->setEnabled(true);
1271   pushRemoveSnap->setEnabled(true);
1272
1273   slotLoadClones();
1274}
1275
1276bool dialogWarden::hasClone(QString snap)
1277{
1278   for (int i = 0; i < cloneList.size(); ++i)
1279     if ( cloneList.at(i) == snap )
1280        return true;
1281
1282   return false;
1283}
1284
1285void dialogWarden::slotLoadClones()
1286{
1287   if ( ! listJails->currentItem() )
1288      return;
1289
1290   labelClone->setText(tr("Loading clones..."));
1291
1292   QString IP = listJails->currentItem()->text(0);
1293
1294   // Grab the ZFS clone list
1295   QProcess m;
1296   m.start(QString("warden"), QStringList() << "zfslistclone" << IP );
1297   while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
1298      m.waitForFinished(200);
1299      QCoreApplication::processEvents();
1300   }
1301
1302   // Check if the user changed jails before we finished loading snaps
1303   if ( ! listJails->currentItem() )
1304      return;
1305   if ( IP != listJails->currentItem()->text(0))
1306     return;
1307
1308   cloneList.clear();
1309   QString tmp;
1310   bool ok, ok2;
1311
1312   qDebug() << "Getting ZFS clones for " + IP;
1313
1314   // Get output of ZFS Clones
1315   while (m.canReadLine()) {
1316      tmp = m.readLine().simplified();
1317      tmp.section("-", 0, 0).toInt(&ok);
1318      tmp.section("-", 1, 1).toInt(&ok2);
1319      if (ok && ok2) {
1320         cloneList << tmp;
1321      }
1322   }
1323
1324   qDebug() << "Available Clones:" << cloneList;
1325
1326   if ( snapshotList.count() <= 0 ) {
1327     pushRemoveClone->setEnabled(false);
1328     pushAddClone->setEnabled(false);
1329   } else
1330     slotSnapSliderChanged(snapshotList.count()-1);
1331
1332   // If we did something and want to show the same snapshot
1333   if ( currentSnapshot != -1 ) {
1334     sliderSnaps->setValue(currentSnapshot );
1335     slotSnapSliderChanged(currentSnapshot);
1336   }
1337     
1338
1339   groupSnaps->setEnabled(true); 
1340}
1341
1342QString dialogWarden::getSnapDateReadable(QString time)
1343{
1344   QDate date;
1345   QTime timestr;
1346   if ( time.count('-') == 1 ) {
1347     // Old Style
1348     date = QDate::fromString(time.section("-", 0, 0), "yyyyMMdd");
1349     timestr = QTime::fromString(time.section("-", 1, 1), "hhmmss");
1350   } else {
1351     // New Style
1352     date = QDate::fromString(time.section("-", 0, 2), "yyyy-MM-dd");
1353     timestr = QTime::fromString(time.section("-", 3, 5), "hh-mm-ss");
1354   }
1355   
1356   return QString(date.toString("ddd MMMM d',' yyyy") + " @ " + timestr.toString("h:mm:ss ap"));
1357}
1358
1359void dialogWarden::slotCurrentJailChanged()
1360{
1361   if ( ! listJails->currentItem() ) {
1362
1363     groupJailTab->setEnabled(false);
1364     groupJailTab->setTitle(tr("No jail selected!"));
1365     labelSize->setText("");
1366     labelPorts->setText("");
1367     labelConnections->setText("");
1368     labelType->setText("");
1369     labelIPs->setText("");
1370     labelStartAtBoot->setText("");
1371     pushStart->setEnabled(false);
1372     return;
1373   }
1374
1375   currentSnapshot = -1;
1376   //pushStart->setEnabled(false);
1377
1378   if ( listJails->currentItem()->text(2) == "Running" ) {
1379     //pushStart->setEnabled(true);
1380     pushTerminal->setEnabled(true);
1381     pushStart->setIcon(QIcon(":stopjail.png"));
1382     pushStart->setIconSize(QSize(16,16));
1383     pushStart->setToolTip(tr("Stop the selected jail"));
1384   }
1385   if ( listJails->currentItem()->text(2) == "Not Running" ) {
1386     //pushStart->setEnabled(true);
1387     pushTerminal->setEnabled(false);
1388     pushStart->setIcon(QIcon(":running.png"));
1389     pushStart->setIconSize(QSize(16,16));
1390     pushStart->setToolTip(tr("Start the selected jail"));
1391   }
1392
1393   groupJailTab->setTitle(tr("Working on jail:") + " " + listJails->currentItem()->text(0));
1394   groupJailTab->setEnabled(true);
1395
1396   QString AutoStart = "Disabled";
1397   QFile file2(JailDir + "/." + listJails->currentItem()->text(0) + ".meta/autostart" );
1398   if ( file2.exists() )
1399      AutoStart = "Enabled";
1400   labelStartAtBoot->setText(AutoStart);
1401
1402   refreshJailDetailsView();
1403
1404}
1405
1406void dialogWarden::slotUserAdmin()
1407{
1408   if ( ! listJails->currentItem() )
1409     return;
1410   QString cmd = "pc-usermanager -warden /usr/jails/" + listJails->currentItem()->text(0) + " " + listJails->currentItem()->text(0) + " &"; 
1411   system(cmd.toLatin1());
1412   
1413}
1414
1415void dialogWarden::slotServiceGUI()
1416{
1417   if ( ! listJails->currentItem() )
1418     return;
1419   QString cmd = "pc-servicemanager -warden /usr/jails/" + listJails->currentItem()->text(0) + " " + listJails->currentItem()->text(0) + " &"; 
1420   system(cmd.toLatin1());
1421}
1422
1423void dialogWarden::slotTerminal()
1424{
1425   if ( ! listJails->currentItem() )
1426     return;
1427
1428   pcbsd::Utils::runInTerminal(QString("warden chroot ") + listJails->currentItem()->text(0),
1429                        QString("Jail: ") + listJails->currentItem()->text(0));
1430}
1431
1432void dialogWarden::slotPushEditIP()
1433{
1434
1435   if ( ! listJails->currentItem() )
1436     return;
1437
1438   dIP = new dialogEditIP();
1439   connect(dIP, SIGNAL(saved()),this, SLOT(slotMonitorJailDetails()) );
1440   dIP->programInit(listJails->currentItem()->text(0));
1441   dIP->exec();
1442
1443}
1444
1445void dialogWarden::slotPushPackage()
1446{
1447   
1448   if ( ! listJails->currentItem() )
1449     return;
1450   QString cmd = "pc-pkgmanager -chroot usr/jails/" + listJails->currentItem()->text(0) + " &"; 
1451   system(cmd.toLatin1());
1452}
1453
1454
1455void dialogWarden::slotUpdate()
1456{
1457   
1458   if ( ! listJails->currentItem() )
1459     return;
1460   QString cmd = "pc-updategui -warden /usr/jails/" + listJails->currentItem()->text(0) + " " + listJails->currentItem()->text(0) + " &"; 
1461   system(cmd.toLatin1());
1462}
1463
1464void dialogWarden::slotAddClone()
1465{
1466   if ( ! listJails->currentItem() )
1467      return;
1468
1469   // Update status
1470   groupSnaps->setEnabled(false); 
1471   labelSnap->setText(tr("Cloning snapshot... Please wait..."));
1472
1473   QString IP = listJails->currentItem()->text(0);
1474
1475   // Now start the script to stop this jail
1476   createJailProc = new QProcess( this ); 
1477   QString program = "warden";
1478   QStringList args;
1479   args << "zfsclonesnap" << IP << snapshotList.at(sliderSnaps->value());
1480
1481   // Connect the exited signal and start the process
1482   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1483   createJailProc->setReadChannel(QProcess::StandardOutput);
1484   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1485   createJailProc->start(program, args);
1486
1487   currentSnapshot = sliderSnaps->value();
1488
1489}
1490
1491void dialogWarden::slotRemoveClone()
1492{
1493   if ( ! listJails->currentItem() )
1494      return;
1495
1496   // Update status
1497   groupSnaps->setEnabled(false); 
1498   labelSnap->setText(tr("Removing clone... Please wait..."));
1499
1500   QString IP = listJails->currentItem()->text(0);
1501
1502   // Now start the script to stop this jail
1503   createJailProc = new QProcess( this ); 
1504   QString program = "warden";
1505   QStringList args;
1506   args << "zfsrmclone" << IP << snapshotList.at(sliderSnaps->value());
1507
1508   // Connect the exited signal and start the process
1509   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1510   createJailProc->setReadChannel(QProcess::StandardOutput);
1511   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1512   createJailProc->start(program, args);
1513
1514   currentSnapshot = sliderSnaps->value();
1515}
1516
1517
1518void dialogWarden::slotCreateSnap()
1519{
1520   if ( ! listJails->currentItem() )
1521      return;
1522
1523   currentSnapshot = -1;
1524
1525   // Update status
1526   groupSnaps->setEnabled(false); 
1527   labelSnap->setText(tr("Creating new snapshot... Please wait..."));
1528
1529   QString IP = listJails->currentItem()->text(0);
1530
1531   // Now start the script to stop this jail
1532   createJailProc = new QProcess( this ); 
1533   QString program = "warden";
1534   QStringList args;
1535   args << "zfsmksnap" << IP;
1536
1537   // Connect the exited signal and start the process
1538   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1539   createJailProc->setReadChannel(QProcess::StandardOutput);
1540   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1541   createJailProc->start(program, args);
1542
1543}
1544
1545void dialogWarden::slotRestoreSnap()
1546{
1547   // Update status
1548   currentSnapshot = -1;
1549
1550   QString IP = listJails->currentItem()->text(0);
1551
1552   int ret = QMessageBox::question(this, tr("Warden"),
1553                                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!"),
1554                                QMessageBox::Yes | QMessageBox::No,
1555                                QMessageBox::No);
1556   if ( ret != QMessageBox::Yes )
1557      return;
1558
1559   groupSnaps->setEnabled(false); 
1560   labelSnap->setText(tr("Reverting snapshot... Please wait..."));
1561
1562   dialogOutput = new dialogDisplayOutput();
1563   dialogOutput->setModal(true);
1564   dialogOutput->programInit(FALSE);
1565   dialogOutput->setDialogCaption(tr("Reverting snapshot"));
1566   dialogOutput->setDialogText(tr("Reverting to snapshot:") + " " + getSnapDateReadable(snapshotList.at(sliderSnaps->value() ) ));
1567   dialogOutput->show();
1568   
1569
1570   // Revert the snapshot
1571   createJailProc = new QProcess( this ); 
1572   QString program = "warden";
1573   QStringList args;
1574   args << "zfsrevertsnap" << IP << snapshotList.at(sliderSnaps->value());
1575
1576   // Connect the exited signal and start the process
1577   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1578   createJailProc->setReadChannel(QProcess::StandardOutput);
1579   connect( createJailProc, SIGNAL(readyReadStandardOutput ()), this, SLOT(slotReadCreateOutput() ) );
1580   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotShowDialogCloseButton() ) );
1581   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1582   createJailProc->start(program, args);
1583
1584
1585}
1586
1587void dialogWarden::slotRemoveSnap()
1588{
1589
1590   QString IP = listJails->currentItem()->text(0);
1591
1592   currentSnapshot = -1;
1593
1594   int ret = QMessageBox::question(this, tr("Warden"),
1595                                tr("Are you sure you want to remove the snapshot:") + "\n" + getSnapDateReadable(snapshotList.at(sliderSnaps->value() ) ) + "?",
1596                                QMessageBox::Yes | QMessageBox::No,
1597                                QMessageBox::No);
1598   if ( ret != QMessageBox::Yes )
1599      return;
1600
1601   // Update status
1602   groupSnaps->setEnabled(false); 
1603   labelSnap->setText(tr("Removing snapshot... Please wait..."));
1604
1605   // Remove the snapshot
1606   createJailProc = new QProcess( this ); 
1607   QString program = "warden";
1608   QStringList args;
1609   args << "zfsrmsnap" << IP << snapshotList.at(sliderSnaps->value());
1610
1611   // Connect the exited signal and start the process
1612   createJailProc->setProcessChannelMode(QProcess::MergedChannels);
1613   createJailProc->setReadChannel(QProcess::StandardOutput);
1614   connect( createJailProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotLoadSnapshots() ) );
1615   createJailProc->start(program, args);
1616
1617}
1618
1619
1620void dialogWarden::slotSnapSliderChanged(int newVal)
1621{ 
1622   QString IP = listJails->currentItem()->text(0);
1623   QString tmp;
1624   int cloneId = -1;
1625   if ( hasClone(snapshotList.at(newVal)) ) {
1626      tmp = tr("(Cloned)");
1627      pushAddClone->setEnabled(false);
1628      pushRemoveClone->setEnabled(true);
1629      pushRemoveSnap->setEnabled(false);
1630
1631      for (int i = 0; i < cloneList.size(); ++i)
1632        if ( cloneList.at(i) == snapshotList.at(newVal) )
1633           cloneId = i;
1634
1635      if ( cloneId != -1 )
1636        // List the clone
1637        labelClone->setText(tr("Mounted on: ") + "/usr/jails/clones/" + IP + "-" + cloneList.at(cloneId) );
1638
1639   } else {
1640      labelClone->setText(tr("Snapshot not mounted"));
1641      pushAddClone->setEnabled(true);
1642      pushRemoveClone->setEnabled(false);
1643      pushRemoveSnap->setEnabled(true);
1644   }
1645   labelSnap->setText(getSnapDateReadable(snapshotList.at(newVal)) + " " + tmp);
1646}
1647
1648void dialogWarden::slotShowDialogCloseButton()
1649{
1650    // Unhide the close button
1651    dialogOutput->setCloseHide(FALSE);
1652}
1653
1654void dialogWarden::slotCronSnapshotChanged()
1655{
1656   QString IP = listJails->currentItem()->text(0);
1657
1658   if ( groupSnapSchedule->isChecked() ) {
1659     qDebug() << "Enabling cron snapshots";
1660     QProcess m;
1661     m.start(QString("warden"), QStringList() << "zfscronsnap" << IP << "start" << comboSnapFrequency->currentText() << QString::number(spinSnapDays->value()) );
1662     while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
1663        m.waitForFinished(200);
1664        QCoreApplication::processEvents();
1665     }
1666   } else {
1667     qDebug() << "Disabling cron snapshots";
1668     QProcess m;
1669     m.start(QString("warden"), QStringList() << "zfscronsnap" << IP << "stop" );
1670     while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
1671        m.waitForFinished(200);
1672        QCoreApplication::processEvents();
1673     }
1674   }
1675
1676}
1677
1678void dialogWarden::slotSingleInstance()
1679{
1680  this->hide();
1681  this->showNormal();
1682  this->activateWindow();
1683  this->raise();
1684}
Note: See TracBrowser for help on using the repository browser.