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

releng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since 4efda4d was 4efda4d, checked in by Kris Moore <kris@…>, 12 months ago

Fix up exporting jails via the warden GUI.

While here, I made the export process a bit more "chatty" so the user
knows whats going on.

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