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

9.1-release9.2-releasereleng/10.0releng/10.0.1
Last change on this file since 0cfe72f was 0cfe72f, checked in by Kris Moore <kris@…>, 13 months ago

Add all the changes for related using of split pcbsd-utils libs

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