From 7b2a98647cf796b24a605aa08516dc23ad7e041e Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 13 Aug 2013 16:42:22 -0400 Subject: [PATCH] Get the new life-preserver dataset reversion and single file reversion working. --- life-preserver/LPBackend.cpp | 32 ++++++++++++++++++++++++++--- life-preserver/LPBackend.h | 2 +- life-preserver/LPTray.cpp | 6 ++++-- life-preserver/mainUI.cpp | 39 +++++++++++++++++++++++++++--------- life-preserver/mainUI.h | 1 + life-preserver/mainUI.ui | 10 ++++----- 6 files changed, 69 insertions(+), 21 deletions(-) diff --git a/life-preserver/LPBackend.cpp b/life-preserver/LPBackend.cpp index 5ee8f61..35ee8f4 100644 --- a/life-preserver/LPBackend.cpp +++ b/life-preserver/LPBackend.cpp @@ -173,9 +173,35 @@ bool LPBackend::revertSnapshot(QString dataset, QString snapshot){ return (ret == 0); } -bool LPBackend::browseSnapshot(QString dataset, QString snapshot){ - //Not implemented yet - return false; +QString LPBackend::revertSnapshotFile(QString dsmountpoint, QString snapshot, QString filepath){ + //Copy the given file from the snapshot back into the main dataset + // -- filepath: full path to the file in the snapshot directory + + //Check that the file path is complete and the file exists + if(!QFile::exists(filepath)){ + //invalid file given + return ""; + } + //Generate the new file path + QString newfilepath = filepath.replace(dsmountpoint+"/.zfs/snapshot/"+snapshot, dsmountpoint); + if( QFile::exists(newfilepath) ){ + //get the file extension + QString ext = newfilepath.section(".",-1); + newfilepath.chop(ext.length()+1); + newfilepath.append("-reversion."+ext); + int i=1; + //append a number to the end if a reversion file already exists + while(QFile::exists(newfilepath)){ + newfilepath.chop(ext.length()+1); + newfilepath.append(QString::number(i)+"."+ext); + i++; + } + } + //perform the copy + bool ok = QFile::copy(filepath,newfilepath); + //return the path to the new file if the copy was successful + if(ok){ return newfilepath; } + else{ return ""; } } // ================== diff --git a/life-preserver/LPBackend.h b/life-preserver/LPBackend.h index 646c7d0..2aafd21 100644 --- a/life-preserver/LPBackend.h +++ b/life-preserver/LPBackend.h @@ -26,7 +26,7 @@ class LPBackend{ static bool newSnapshot(QString dataset); static bool removeSnapshot(QString dataset, QString snapshot); static bool revertSnapshot(QString dataset, QString snapshot); //revert to given snapshot - static bool browseSnapshot(QString dataset, QString snapshot); + static QString revertSnapshotFile(QString dataset, QString snapshot, QString filepath); //Replication Management static bool setupReplication(QString dataset, QString remotehost, QString user, int port, QString remotedataset, int time); static bool removeReplication(QString dataset); diff --git a/life-preserver/LPTray.cpp b/life-preserver/LPTray.cpp index cca7f27..9bdf2a8 100644 --- a/life-preserver/LPTray.cpp +++ b/life-preserver/LPTray.cpp @@ -175,8 +175,10 @@ void LPTray::slotNewLogMessage(QString file){ } void LPTray::slotTrayClicked(QSystemTrayIcon::ActivationReason reason){ - if(reason == QSystemTrayIcon::Trigger){ startGUI(); } - else if( reason == QSystemTrayIcon::Context){ + if(reason == QSystemTrayIcon::Trigger){ + if(GUI->isVisible()){ GUI->hide(); } + else{ startGUI(); } + }else if( reason == QSystemTrayIcon::Context){ this->contextMenu()->popup(QCursor::pos()); } } diff --git a/life-preserver/mainUI.cpp b/life-preserver/mainUI.cpp index 07480a4..e16897b 100644 --- a/life-preserver/mainUI.cpp +++ b/life-preserver/mainUI.cpp @@ -138,7 +138,6 @@ void mainUI::updateMenus(){ //Now set the items appropriately revMenu->clear(); brMenu->clear(); - if(ok){ //Reset the Menu Contents QStringList subsets = HLIST[ds].subsets(); @@ -154,9 +153,6 @@ void mainUI::updateMenus(){ } revMenu->addMenu(menu); brMenu->addMenu(menu); - // - //revMenu->addAction( new QAction(snaps[i], this) ); - //brMenu->addAction( new QAction(snaps[i], this) ); } //Enable the buttons if appropriate if(revMenu->isEmpty()){ @@ -229,23 +225,23 @@ void mainUI::slotRevertToSnapshot(QAction *act){ QString subset = info.section(":::",1,1); QString snap = info.section(":::",2,2); qDebug() << "Revert Clicked:" << ds << subset << snap; - return; - /*QString ds = getSelectedDS(); if(!ds.isEmpty()){ //Verify the reversion if( QMessageBox::Yes == QMessageBox::question(this,tr("Verify Snapshot Reversion"), - QString(tr("Are you sure that you wish to revert %1 to the following snapshot?")).arg(ds)+"\n"+tr("WARNING: This will result in the loss of any data not previously backed up.")+"\n\n"+ds, + QString(tr("Are you sure that you wish to revert %1 to the selected snapshot?")).arg(subset)+"\n"+tr("WARNING: This will result in the loss of any data not previously backed up."), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ){ //Perform the reversion - if( !LPBackend::revertSnapshot(ds,snapshot) ){ + if( !LPBackend::revertSnapshot(ds+subset,snap) ){ //Error performing the reversion + qDebug() << " - Error:" << ds+subset << snap; QMessageBox::warning(this,tr("Reversion Error"), tr("The snapshot reversion could not be completed successfully.")); }else{ //Good reversion + qDebug() << " - Revert Complete"; QMessageBox::information(this,tr("Reversion Success"), tr("The snapshot reversion was completed successfully.")); } } - }*/ + } } void mainUI::slotBrowseSnapshot(QAction *act){ @@ -253,7 +249,30 @@ void mainUI::slotBrowseSnapshot(QAction *act){ QString ds = info.section(":::",0,0); QString subset = info.section(":::",1,1); QString snap = info.section(":::",2,2); - qDebug() << "Browse Clicked:" << ds << subset << snap; + //Now let the user select a file within the snapshot to revert + QString snapPath = subset+"/.zfs/snapshot/"+snap+"/"; + QString filepath = QFileDialog::getOpenFileName(this,tr("Revert a file"), snapPath, tr("Backup Files (*)") ); + qDebug() << "File to revert:" << filepath; + //Check to make sure that it is a valid file (within the snapshot) + if(filepath.isEmpty() ){ + qDebug() << " - Cancelled"; + //action cancelled - do nothing + }else if(!filepath.startsWith(snapPath)){ + qDebug() << " - Invalid File"; + QMessageBox::warning(this, tr("Invalid Snapshot File"), tr("Please select a file from within the chosen snapshot that you wish to revert")); + }else{ + //Revert the file + QString newfile = LPBackend::revertSnapshotFile(subset,snap,filepath); + if(newfile.isEmpty()){ + //Error copying the new file over + qDebug() << " - Error copying file"; + QMessageBox::warning(this, tr("Error Reverting File"), QString(tr("An error occurred while tring to revert the file %1. Please try again.")).arg(filepath)); + }else{ + //Let the user know the location of the reverted file + qDebug() << " - Successful reversion:" << newfile; + QMessageBox::information(this, tr("FIle Reverted"), QString(tr("The reverted file is now available at: %1")).arg(newfile) ); + } + } return; } diff --git a/life-preserver/mainUI.h b/life-preserver/mainUI.h index a456753..29e5499 100644 --- a/life-preserver/mainUI.h +++ b/life-preserver/mainUI.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "LPBackend.h" #include "LPWizard.h" diff --git a/life-preserver/mainUI.ui b/life-preserver/mainUI.ui index f7d1935..42ed6e7 100644 --- a/life-preserver/mainUI.ui +++ b/life-preserver/mainUI.ui @@ -6,8 +6,8 @@ 0 0 - 398 - 174 + 456 + 175 @@ -128,7 +128,7 @@ - Browse the files in a snapshot of the current dataset + Browse a snapshot and safely recover that version of a file Browse @@ -145,7 +145,7 @@ - Revert the selected dataset to a previous snapshot + Revert an entire data subset to a previous snapshot (overwrites all files) Revert @@ -169,7 +169,7 @@ 0 0 - 398 + 456 20