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

9.2-releasereleng/10.0releng/10.0.1
Last change on this file since 6c1dd87 was 6c1dd87, checked in by Kris Moore <kris@…>, 10 months ago

Add the new Template UI manager to Warden, Now we can create / remove
jail templates, and during jail creation, pick from them

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