Пример #1
0
// ==== Disks Menu ====
void LPMain::menuAddDisk(){
  QString pool = ui->combo_pools->currentText();
  //Get the available disks and remove the current disks
  QStringList adisks = LPGUtils::listAvailableHardDisks();
  for(int i=0; i<POOLDATA.harddisks.length(); i++){
    adisks.removeAll( POOLDATA.harddisks[i].section("s",0,0,QString::SectionSkipEmpty) );
  }
  if(adisks.isEmpty()){
    QMessageBox::information(this,tr("Attach New Disk"), tr("No available disks could be found"));
    return;
  }
  //Find a disk that can be added to the system
  bool ok=false;
  QString disk = QInputDialog::getItem(this, tr("Attach New Disk"),tr("Detected Disks:"), adisks,0,false, &ok);
  if( !ok || disk.isEmpty() ){ return; }
  qDebug() << "Add Disk:" << disk << pool;
  showWaitBox(tr("Attaching disk"));
  ok = LPBackend::attachDisk(pool, disk);
  hideWaitBox();
  if(ok){
    QMessageBox::information(this,tr("Disk Attached"),QString(tr("Success: %1 was added to %2")).arg(disk,pool) );
    QTimer::singleShot(0,this,SLOT(updateTabs()) );
  }else{
    QMessageBox::warning(this,tr("Disk Attach Error"),QString(tr("Failure: %1 could not be attached to %2.")).arg(disk,pool) );
  }	
}
Пример #2
0
void LPMain::restoreFiles(){
  QString filePath = fsModel->filePath( ui->treeView->currentIndex() );
  qDebug() << " Restore file(s):" << filePath;
  QFileInfo info(filePath);	
  QString destDir = filePath;
	destDir.remove("/.zfs/snapshot/"+ui->label_snapshot->text());
	destDir.chop( filePath.section("/",-1).size()+1 ); //get rid of the filename at the end
	while(!QFile::exists(destDir)){ destDir.chop( destDir.section("/",-1).size() +1); }
  QString newFilePath = destDir+"/"+LPGUtils::generateReversionFileName(filePath, destDir);
  //qDebug() << "Destination:" << newFilePath;
  //Perform the reversion(s)
  QStringList errors;
  if( info.isDir() ){
    //Is a directory
    showWaitBox( QString(tr("Restoring Directory: %1")).arg(newFilePath) );
    errors = LPGUtils::revertDir(filePath, newFilePath);
    hideWaitBox();
    if(!errors.isEmpty()){
      qDebug() << "Failed Reversions:" << errors;
      errors.prepend(tr("File destination(s) that could not be restored:")+"\n");
      showErrorDialog(tr("Reversion Error"), tr("Some files could not be restored from the snapshot."), errors.join("\n") );
    }else{
      qDebug() << "Reversion successful";	    
      QMessageBox::information(this,tr("Restore Successful"),QString(tr("The following directory was succesfully restored: %1")).arg(newFilePath) );
    }
  }else{
    //Just a single file
    showWaitBox( QString(tr("Restoring file: %1")).arg(newFilePath) );
    bool ok = LPGUtils::revertFile(filePath, newFilePath);
    hideWaitBox();
    if( !ok ){
      qDebug() << "Failed Reversion:" << newFilePath;
      errors << QString(tr("Snapshot file: %1")).arg(filePath);
      errors << QString(tr("Destination: %1")).arg(newFilePath);
      errors << tr("Please check that the destination directory exists and is writable");
      showErrorDialog(tr("Reversion Error"), tr("The file could not be restored from the snapshot."), errors.join("\n") );
    }else{
      qDebug() << "Reversion successful";
      QMessageBox::information(this,tr("Restore Successful"),QString(tr("The following file was succesfully restored: %1")).arg(newFilePath) );
    }
  }	  
	
}
Пример #3
0
void LPMain::menuRemovePool(QAction *act){
  QString ds = act->text();
  qDebug() << "Remove Pool:" << ds;
  if(!ds.isEmpty()){
    //Verify the removal of the dataset
    if( QMessageBox::Yes == QMessageBox::question(this,tr("Verify Dataset Backup Removal"),tr("Are you sure that you wish to cancel automated snapshots and/or replication of the following dataset?")+"\n\n"+ds,QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ){	    
      //verify the removal of all the snapshots for this dataset
      QStringList snapComments;
      QStringList snaps = LPBackend::listLPSnapshots(ds, snapComments);
      if(!snaps.isEmpty()){
        if( QMessageBox::Yes == QMessageBox::question(this,tr("Verify Snapshot Deletion"),tr("Do you wish to remove the local snapshots for this dataset?")+"\n"+tr("WARNING: This is a permanant change that cannot be reversed"),QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ){
	  //Remove all the snapshots
	  ui->statusbar->showMessage(QString(tr("%1: Removing snapshots")).arg(ds),0);
	  showWaitBox(tr("Removing snapshots"));
	  for(int i=0; i<snaps.length(); i++){
	    LPBackend::removeSnapshot(ds,snaps[i]);
	  }
	  ui->statusbar->clearMessage();
        }
      }
      //Remove the dataset from life-preserver management
      if(LPBackend::listReplicationTargets().contains(ds)){ 
        ui->statusbar->showMessage(QString(tr("%1: Disabling Replication")).arg(ds),0);
	showWaitBox(tr("Disabling Replication"));
	//Need the replication host(s)
	QList<LPRepHost> rhosts = LPBackend::replicationInfo(ds);
	for(int i=0; i<rhosts.length(); i++){
	  LPBackend::removeReplication(ds,rhosts[i].host()); 
	}
	ui->statusbar->clearMessage();      
      }
      if(LPBackend::listScrubs().contains(ds)){
        ui->statusbar->showMessage(QString(tr("%1: Disabling Scrubs")).arg(ds),0);
	showWaitBox(tr("Disabling Scrubs"));
	LPBackend::removeScrub(ds);
	ui->statusbar->clearMessage();
      }
      ui->statusbar->showMessage(QString(tr("%1: Disabling Life-Preserver Management")).arg(ds),0);
      showWaitBox(tr("Removing Life Preserver Schedules"));
      LPBackend::removeDataset(ds);
      ui->statusbar->clearMessage();
      updatePoolList();
      hideWaitBox();
    }
  } //end check for empty ds

}
Пример #4
0
void LPMain::menuOnlineDisk(QAction *act){
  QString disk = act->text();
  QString pool = ui->combo_pools->currentText();
  //Verify action
  if(QMessageBox::Yes != QMessageBox::question(this,tr("Verify Disk Online"),QString(tr("Are you sure you wish to set %1 online?")).arg(disk), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ){
    return; //cancelled
  }
  qDebug() << "Online Disk:" << disk << pool;
  showWaitBox(tr("Setting disk online"));
  bool ok = LPBackend::setDiskOnline(pool, disk);
  hideWaitBox();
  if(ok){
    QMessageBox::information(this,tr("Disk Online Success"),QString(tr("Success: %1 has been set online.")).arg(disk) );
    QTimer::singleShot(0,this,SLOT(updateTabs()) );
  }else{
    QMessageBox::warning(this,tr("Disk Online Failure"),QString(tr("Failure: %1 could not be set online at this time.")).arg(disk) );
  }
}
Пример #5
0
void LPMain::menuRemoveDisk(QAction *act){
  QString disk = act->text();
  QString pool = ui->combo_pools->currentText();
  //Verify action
  if(QMessageBox::Yes != QMessageBox::question(this,tr("Verify Disk Removal"),QString(tr("Are you sure that you want to remove %1 from %2?")).arg(disk,pool) + "\n\n" + tr("CAUTION: This disk can only be re-attached later as a brand new disk"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ){
    return; //cancelled
  }
  qDebug() << "Remove Disk:" << disk << pool;
  showWaitBox(tr("Detaching disk"));
  bool ok = LPBackend::detachDisk(pool, disk);
  hideWaitBox();
  if(ok){
    QMessageBox::information(this,tr("Disk Removal Success"),QString(tr("Success: %1 was removed from %2")).arg(disk, pool) );
    QTimer::singleShot(0,this,SLOT(updateTabs()) );
  }else{
    QMessageBox::warning(this,tr("Disk Removal Failure"),QString(tr("Failure: %1 could not be removed from %2 at this time.")).arg(disk, pool) );
  }
}
Пример #6
0
void LPMain::menuStopScrub(){
  QString pool = ui->combo_pools->currentText();
  //Verify stopping a scrub
  if( QMessageBox::Yes != QMessageBox::question(this,tr("Verify Scrub"),QString(tr("Are you sure you want to stop the scrub on %1?")).arg(pool), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ){
    return; //cancelled	  
  }
  qDebug() << "Stop Scrub:" << pool;
  QString cmd = "zpool scrub -s "+pool;
  showWaitBox(tr("Trying to stop scrub"));
  int ret = system(cmd.toUtf8());
  hideWaitBox();
  if(ret == 0){
    //Now let te user know that one has been triggered
    QMessageBox::information(this,tr("Scrub Stopped"),QString(tr("The scrub on %1 has been stopped.")).arg(pool));
    QTimer::singleShot(0,this,SLOT(updateTabs()) );
  }else{
    QMessageBox::warning(this,tr("Scrub Not Running"), QString(tr("There was no scrub running on %1.")).arg(pool) );
  }	
}
Пример #7
0
void LPMain::menuStartScrub(){
  QString pool = ui->combo_pools->currentText();
  //Verify starting a scrub
  if( QMessageBox::Yes != QMessageBox::question(this,tr("Verify Scrub"),QString(tr("Are you sure you want to start a scrub on %1?")).arg(pool) + "\n"+tr("NOTE: This may take quite a while to complete"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ){
    return; //cancelled	  
  }
  qDebug() << "Start Scrub:" << pool;
  QString cmd = "zpool scrub "+pool;
  showWaitBox(tr("Trying to start a scrub"));
  int ret = system(cmd.toUtf8());
  hideWaitBox();
  if(ret == 0){
    //Now let te user know that one has been triggered
    QMessageBox::information(this,tr("Scrub Started"),QString(tr("A scrub has just been started on %1")).arg(pool));
    QTimer::singleShot(0,this,SLOT(updateTabs()) );
  }else{
    QMessageBox::warning(this,tr("Scrub Not Started"), QString(tr("A scrub on %1 could not be started at this time.")).arg(pool) + "\n"+tr("Please wait until any current resilvering or scrubs are finished before trying again.") );
  }
}
Пример #8
0
void LPMain::menuExtractHomeDir(){
  qDebug() << "Extract Home Dir";
  //Get the file path from the user
  QString filePath = QFileDialog::getOpenFileName(this,tr("Find Home Dir Package"), "/usr/home", tr("Home Dir Package (*.home.tar.gz)") );
  if(filePath.isEmpty() || !QFile::exists(filePath)){ return; } //cancelled
  //Now check if the user in the package is also on the system
  QString username;
  bool ok = LPGUtils::checkPackageUserPath(filePath, &username);
  if(!ok){
    QMessageBox::warning(this,tr("User Missing"),QString(tr("The user (%1) does not exist on this system. Please create this user first and then try again.")).arg(username) );
    return;
  }
  //Now extract the package
  showWaitBox(tr("Extracting Home Directory"));
  ok = LPGUtils::extractHomeDirPackage(filePath);
  hideWaitBox();
  //Now report the results
  if(ok){
    QMessageBox::information(this,tr("Package Extracted"), QString(tr("The package was successfully extracted within %1")).arg("/usr/home/"+username) );
  }else{
    QMessageBox::warning(this, tr("Package Failure"), QString(tr("The package could not be extracted within %1")).arg("/usr/home/"+username) );
  }
  
}
Пример #9
0
void LPMain::updateTabs(){
  //qDebug() << "Update Tabs" << poolSelected;
  qDebug() << "[DEBUG] start updateTabs():" << poolSelected;
  viewChanged();
  ui->tabWidget->setEnabled(poolSelected);
  ui->menuView->setEnabled(poolSelected);	
  ui->menuDisks->setEnabled(poolSelected); 
  ui->menuSnapshots->setEnabled(poolSelected);
  ui->push_configure->setVisible(poolSelected);
  ui->action_SaveKeyToUSB->setEnabled(poolSelected);
  if(poolSelected){
    showWaitBox(tr("Loading zpool information"));
    qDebug() << "[DEBUG] loadPoolData:" << ui->combo_pools->currentText();
    POOLDATA = LPGUtils::loadPoolData(ui->combo_pools->currentText());
    qDebug() << "[DEBUG] loaded data";
    hideWaitBox();
    //Now list the status information
    ui->label_status->setText(POOLDATA.poolStatus);
    ui->label_numdisks->setText( QString::number(POOLDATA.harddisks.length()) );
    ui->label_latestsnapshot->setText(POOLDATA.latestSnapshot);
    if(POOLDATA.finishedStatus.isEmpty()){ ui->label_finishedstat->setVisible(false); }
    else{
      ui->label_finishedstat->setText(POOLDATA.finishedStatus);
      ui->label_finishedstat->setVisible(true);
    }
    if(POOLDATA.runningStatus.isEmpty()){ 
      ui->label_runningstat->setVisible(false);
      ui->action_startScrub->setEnabled(true);
      ui->action_stopScrub->setEnabled(false);
    }else{
      ui->label_runningstat->setText(POOLDATA.runningStatus);
      ui->label_runningstat->setVisible(true);
      ui->action_startScrub->setEnabled(false); //Something already running
      ui->action_stopScrub->setEnabled(POOLDATA.runningStatus.contains("scrub", Qt::CaseInsensitive));
    }	    
    if(POOLDATA.errorStatus.isEmpty()){ ui->label_errorstat->setVisible(false); }
    else{
      ui->label_errorstat->setText(POOLDATA.errorStatus);
      ui->label_errorstat->setVisible(true);
    }	    
    //Now list the data restore options
    QString cds = ui->combo_datasets->currentText();
    ui->combo_datasets->clear();
    QStringList dslist = POOLDATA.subsets();
    dslist.sort();
    //Now move the home directories to the top of the list
    int moved = 0;
    for(int i=0; i<dslist.length(); i++){  //make sure it stays in alphabetical order
      if(dslist[i].startsWith("/usr/home/")){
        dslist.move(i,moved);
	moved++; 
	i--; //make sure to not miss any items from moving
      }
    }
    ui->combo_datasets->addItems(dslist);
    int dsin = dslist.indexOf(cds);
    if(dsin >= 0){ ui->combo_datasets->setCurrentIndex(dsin); }
    else if( !dslist.isEmpty() ){ ui->combo_datasets->setCurrentIndex(0); }
    else{ ui->combo_datasets->addItem(tr("No datasets available")); }
    //NOTE: this automatically calls the "updateDataset()" function in a new thread
    
    //Now update the snapshot removal menu list
    QStringList snaps = LPBackend::listLPSnapshots(ui->combo_pools->currentText());
    ui->menuDelete_Snapshot->clear();
    for(int i=0; i<snaps.length(); i++){
       ui->menuDelete_Snapshot->addAction(snaps[i]);
    }
    ui->menuDelete_Snapshot->setEnabled( !ui->menuDelete_Snapshot->isEmpty() );
    //Now update the disk menu items
    ui->menuRemove_Disk->clear();
    ui->menuSet_Disk_Offline->clear();
    ui->menuSet_Disk_Online->clear();
    for(int i=0; i<POOLDATA.harddisks.length(); i++){
      ui->menuRemove_Disk->addAction(POOLDATA.harddisks[i]);
      if(POOLDATA.harddiskStatus[i] == "OFFLINE"){
        ui->menuSet_Disk_Online->addAction(POOLDATA.harddisks[i]);
      }else{
	ui->menuSet_Disk_Offline->addAction(POOLDATA.harddisks[i]);      
      }
    }
    ui->menuRemove_Disk->setEnabled(!ui->menuRemove_Disk->isEmpty());
    ui->menuSet_Disk_Offline->setEnabled(!ui->menuSet_Disk_Offline->isEmpty());
    ui->menuSet_Disk_Online->setEnabled(!ui->menuSet_Disk_Online->isEmpty());
  }else{
    //No Pool selected
    ui->label_numdisks->clear();
    ui->label_latestsnapshot->clear();
    ui->label_status->clear();
	  ui->label_errorstat->setVisible(false);
	  ui->label_runningstat->setVisible(false);
	  ui->label_finishedstat->setVisible(false);
  }

}
Пример #10
0
void LPMain::updateTabs(){
  static bool updating = false;
  if(updating){ return; } //prevent double-taps on this function
  updating = true;
  QApplication::processEvents();
  //qDebug() << "Update Tabs" << poolSelected;
  qDebug() << "[DEBUG] start updateTabs():" << poolSelected;
  viewChanged();
  ui->tabWidget->setEnabled(poolSelected);
  ui->menuView->setEnabled(poolSelected);	
  ui->menuDisks->setEnabled(poolSelected); 
  ui->menuSnapshots->setEnabled(poolSelected);
  ui->push_configure->setVisible(poolSelected);
  ui->action_SaveKeyToUSB->setEnabled(poolSelected);
  //No Pool selected (yet)
    ui->label_numdisks->clear();
    ui->label_latestsnapshot->clear();
    ui->label_status->clear();
	  ui->label_errorstat->setVisible(false);
	  ui->label_runningstat->setVisible(false);
	  ui->label_finishedstat->setVisible(false);
  if(poolSelected){
    showWaitBox(tr("Loading zpool information"));
    qDebug() << "[DEBUG] loadPoolData:" << ui->combo_pools->currentText();
    POOLDATA = LPGUtils::loadPoolData(ui->combo_pools->currentText());
    qDebug() << "[DEBUG] loaded data";
    hideWaitBox();
    //Now list the status information
    ui->label_status->setText(POOLDATA.poolStatus);
    ui->label_numdisks->setText( QString::number(POOLDATA.harddisks.length()) );
    ui->label_latestsnapshot->setText(POOLDATA.latestSnapshot);
    qDebug() << "[DEBUG] Latest Snapshot:" << POOLDATA.latestSnapshot;
    if(POOLDATA.finishedStatus.isEmpty()){ ui->label_finishedstat->setVisible(false); }
    else{
      ui->label_finishedstat->setText(POOLDATA.finishedStatus);
      ui->label_finishedstat->setVisible(true);
    }
    if(POOLDATA.runningStatus.isEmpty()){ 
      ui->label_runningstat->setVisible(false);
      ui->action_startScrub->setEnabled(true);
      ui->action_stopScrub->setEnabled(false);
    }else{
      ui->label_runningstat->setText(POOLDATA.runningStatus);
      ui->label_runningstat->setVisible(true);
      ui->action_startScrub->setEnabled(false); //Something already running
      ui->action_stopScrub->setEnabled(POOLDATA.runningStatus.contains("scrub", Qt::CaseInsensitive));
    }	    
    if(POOLDATA.errorStatus.isEmpty()){ ui->label_errorstat->setVisible(false); }
    else{
      ui->label_errorstat->setText(POOLDATA.errorStatus);
      ui->label_errorstat->setVisible(true);
    }
    
    //Update the replication/disk menus
    QStringList repHosts = POOLDATA.repHost;
    ui->menuStart_Replication->clear();
    ui->menuInit_Replications->clear();
    for(int i=0; i<repHosts.length(); i++){
      ui->menuStart_Replication->addAction( repHosts[i] );
      ui->menuInit_Replications->addAction( repHosts[i] );
    }
    ui->menuStart_Replication->setEnabled( !ui->menuStart_Replication->isEmpty() );
    ui->menuInit_Replications->setEnabled( !ui->menuInit_Replications->isEmpty() );
    //Now update the disk menu items
    ui->menuRemove_Disk->clear();
    ui->menuSet_Disk_Offline->clear();
    ui->menuSet_Disk_Online->clear();
    for(int i=0; i<POOLDATA.harddisks.length(); i++){
      ui->menuRemove_Disk->addAction(POOLDATA.harddisks[i]);
      if(POOLDATA.harddiskStatus[i] == "OFFLINE"){
        ui->menuSet_Disk_Online->addAction(POOLDATA.harddisks[i]);
      }else{
	ui->menuSet_Disk_Offline->addAction(POOLDATA.harddisks[i]);      
      }
    }
    ui->menuRemove_Disk->setEnabled(!ui->menuRemove_Disk->isEmpty());
    ui->menuSet_Disk_Offline->setEnabled(!ui->menuSet_Disk_Offline->isEmpty());
    ui->menuSet_Disk_Online->setEnabled(!ui->menuSet_Disk_Online->isEmpty());
    
    //Now list the data restore options
    QString cds = ui->combo_datasets->currentText();
    ui->combo_datasets->clear();
    
    ui->menuDelete_Snapshot->clear();
    
    emit loadSnaps(&POOLDATA); //kickoff the snapshot loading in the background
  }
  QApplication::processEvents();
  updating = false;
}