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

releng/10.0releng/10.0.1releng/10.0.2
Last change on this file since 58a4795 was 58a4795, checked in by Kris Moore <kris@…>, 6 months ago

Fix some bugs importing jails via the Warden GUI, in particular when we try to set a new
ipv4 address.

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