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

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