Esempio n. 1
0
int main(int argc, char *argv[])
{
    QString APP_ID = (APP_DEBUG) ? UNIQUIE_DEBUG_ID : UNIQUE_ID;
    SingleApplication App(argc, argv,APP_ID);
    //check if there is another process running
    if(App.AlreadyExists())
    {
        App.SendInstanceMessage(QString(APP_MESSAGE_SHOWAPP));
        return 0;
    }

    WriteAppInfo(APP_LOCAL_VERSION_FILENAME,QString::number(APP_MAJOR_VERSION),QString::number(APP_MINOR_VERSION));
    CheckUpdaterFiles(APP_UPDATER);

    bool Args = false;

    if(!APP_DEBUG)
    {
        if(argc < 2)
        {
            Args = true;
            QString UpdaterPath = QApplication::applicationDirPath() + QDir::separator() + APP_UPDATER;

            // Check if an updater exists
            QFile Updater(UpdaterPath);
            if(!Updater.exists())
            {
                if(QMessageBox::critical(0,"Error","Cannot find Ouroboros Updater.exe, please re-install Ouroboros") == QMessageBox::Ok)
                    return 0;
            }

            QProcess::startDetached(UpdaterPath,QStringList());
        }
    }

    if(!Args)
    {
        //run the application
        Ouroboros Window;
        Window.show();
        Window.raise();
        Window.activateWindow();
        App.connect(&App,SIGNAL(MessageAvailable(QStringList)),&Window,SLOT(RecievedMessageFromInstance(QStringList)));
        return App.exec();
    }

    return 0;
}
Esempio n. 2
0
void LPWatcher::readReplicationFile(){
  QString stat;
  while( !RFSTREAM->atEnd() ){ 
    QString line = RFSTREAM->readLine(); 
    if(line.contains("total estimated size")){ repTotK = line.section(" ",-1).simplified(); } //save the total size to replicate
    else if(line.startsWith("send from ")){}
    else if(line.startsWith("TIME ")){}
    else if(line.startsWith("warning: ")){} //start of an error
    else{ stat = line; } //only save the relevant/latest status line
  }
  if(!stat.isEmpty()){
    //qDebug() << "New Status Message:" << stat;	    
    //Divide up the status message into sections
    stat.replace("\t"," ");
    QString dataset = stat.section(" ",2,2,QString::SectionSkipEmpty).section("/",0,0).simplified();
    QString cSize = stat.section(" ",1,1,QString::SectionSkipEmpty);
    //Now Setup the tooltip
    if(cSize != lastSize){ //don't update the info if the same size info
      QString percent;
      if(!repTotK.isEmpty()){
        //calculate the percentage
        double tot = displayToDoubleK(repTotK);
        double c = displayToDoubleK(cSize);
        if( tot!=-1 & c!=-1){
          double p = (c*100)/tot;
	  p = int(p*10)/10.0; //round to 1 decimel places
	  percent = QString::number(p) + "%";
        }
      }
      if(repTotK.isEmpty()){ repTotK = "??"; }
      //Format the info string
      QString status = cSize+"/"+repTotK;
      if(!percent.isEmpty()){ status.append(" ("+percent+")"); }
      QString txt = QString(tr("Replicating %1: %2")).arg(dataset, status);
      lastSize = cSize; //save the current size for later
      //Now set the current process status
      LOGS.insert(20,"RUNNING");
      LOGS.insert(21,dataset);
      LOGS.insert(22,txt);
      LOGS.insert(23,txt);
      emit MessageAvailable("");
    }
  }
}
Esempio n. 3
0
void LPWatcher::checkPoolStatus(){
  //Now check zpool status for bad/running statuses
  QStringList zstat = getCmdOutput("zpool status");
    //parse the output
    QString pool, state, timestamp;
    QStringList cDev, cStat, cMsg, cSummary;
    //qDebug() << "-----zpool status------\n" << zstat.join("\n");
    bool newresilver = false; bool newscrub = false; bool newerror = false;
    for(int i=0; i<zstat.length(); i++){
      zstat[i] = zstat[i].simplified();
      if(zstat[i].isEmpty()){ continue; }
      //qDebug() << zstat[i];
      if(zstat[i].startsWith("pool:")){ pool = zstat[i].section(":",1,10).simplified(); }
      else if(zstat[i].startsWith("state:")){ state = zstat[i].section(":",1,10).simplified(); }
      else if(zstat[i].startsWith("scan:")){
	//check for scrubs/resilvering progress
	// ------ SCRUB ------
	if(zstat[i].contains("scrub")){
	  if(zstat[i].contains(" scrub repaired ")){
	    //Scrub Finished
	    zstat[i]  = zstat[i].replace("\t"," ").simplified();
	    timestamp = zstat[i].section(" ",10,14,QString::SectionSkipEmpty);
	    QString numFixed = zstat[i].section(" ",3,3,QString::SectionSkipEmpty);
	    QString numErr = zstat[i].section(" ",7,7,QString::SectionSkipEmpty);
	    QString timeRun = zstat[i].section(" ",5,5,QString::SectionSkipEmpty);
	    //Scrub finished previously
	    if(numFixed.toInt() > 0){ 
	      if(LOGS.value(60)!="ERROR"){ newscrub=true; }
	      LOGS.insert(60, "ERROR"); 
	      LOGS.insert(62, QString(tr("Scrub repaired %1 bad blocks")).arg(numFixed) );
	      LOGS.insert(63, QString(tr("Scrub repaired %1 blocks in %2 with %3 errors")).arg(numFixed, timeRun, numErr) );
	    }else{ 
	      if(LOGS.contains(60) && LOGS.value(60)!="FINISHED"){ newscrub=true; }
	      LOGS.insert(60,"FINISHED"); 
	      LOGS.insert(62, tr("Scrub completed") );
	      LOGS.insert(63, tr("Scrub completed without needing repairs") );
	    }
	    LOGS.insert(61,pool);
	    LOGS.insert(64, timestamp);
	    LOGS.insert(65, timestamp.section(" ",3,3) );
	    if(timer->interval() != sysCheckTime){ timer->start(sysCheckTime); }
          }else if(zstat[i].contains(" scrub cancel")){
	    //Scrub was cancelled before finishing
	    zstat[i]  = zstat[i].replace("\t"," ").simplified();
	    timestamp = zstat[i].section(" ",4,8,QString::SectionSkipEmpty);
	    LOGS.insert(60, "FINISHED");
	    LOGS.insert(61, pool);
	    LOGS.insert(62, QString(tr("Scrub cancelled for %1")).arg(pool) );
	    LOGS.insert(63, QString(tr("Scrub cancelled for %1")).arg(pool) );
	    LOGS.insert(64, timestamp);
	    LOGS.insert(65,timestamp.section(" ",3,3) );
	  }else{
	    //Scrub is running - parse the line
	    timestamp = zstat[i].section(" ",5,9,QString::SectionSkipEmpty);
	    i++; QString remain = zstat[i].section(" ",7,7,QString::SectionSkipEmpty);
	    i++; QString percent = zstat[i].section(" ",2,2,QString::SectionSkipEmpty);
	    if(LOGS.value(60) != "RUNNING"){newscrub=true;}
	    LOGS.insert(60,"RUNNING");
	    LOGS.insert(61,pool);
	    LOGS.insert(62, QString(tr("Scrubbing %1: %2 (%3 remaining)")).arg(pool, percent, remain) );
	    LOGS.insert(63, QString(tr("Scrubbing %1: %2 (%3 remaining)")).arg(pool, percent, remain) );
	    LOGS.insert(64, timestamp);
	    LOGS.insert(65, timestamp.section(" ",3,3) );
	    if(timer->interval() != 60000){ timer->start(60000); } //put the timer on a 1 minute refresh since it is running
	  }
	  if(LOGS.contains(50) ){
	    //Only resilvering OR scrub is shown at a time - so remove the resilver info
	    LOGS.remove(50);
	    LOGS.remove(51);
	    LOGS.remove(52);
	    LOGS.remove(53);
	    LOGS.remove(54);
	    LOGS.remove(55);
	  }
	// --------- RESILVERING -------
	}else if(zstat[i].contains("resilver in progress")){
	  //Resilvering is currently running
	  timestamp = zstat[i].section(" ",5,9,QString::SectionSkipEmpty);
	  //need info from the next two lines
	  i++; QString timeleft = zstat[i].section(" ",7,7,QString::SectionSkipEmpty);
	  i++; QString percent = zstat[i].section(" ", 2,2,QString::SectionSkipEmpty);
	  //Setup the running re-silvering progress
	  if(LOGS.value(50)!="RUNNING"){newresilver=true; }
	  LOGS.insert(50, "RUNNING");
	  // 51 - need to put the actual device in here (not available on this line)
	  LOGS.insert(52, QString(tr("Resilvering: %1 (%2 remaining)")).arg(percent, timeleft) );
	  if(newresilver){ LOGS.insert(53, QString(tr("Resilvering Started: %1 remaining ")).arg( timeleft) ); }
	  else{ LOGS.insert(53,QString(tr("Resilvering: %1 (%2 remaining)")).arg(percent, timeleft) ); }
	  LOGS.insert(54, timestamp);
	  LOGS.insert(55, timestamp.section(" ",3,3) );
	  if(LOGS.contains(60) ){
	    //Only resilvering OR scrub is shown at a time - so remove the scrub info
	    LOGS.remove(60);
	    LOGS.remove(61);
	    LOGS.remove(62);
	    LOGS.remove(63);
	    LOGS.remove(64);
	    LOGS.remove(65);
	  }
	  if(timer->interval() != 60000){ timer->start(60000); }//put the timer on a 1 minute refresh since it is running
	}else if(zstat[i].contains("resilvered")){
	  //Resilvering is finished
	  timestamp = zstat[i].section(" ",9,13,QString::SectionSkipEmpty);
	  QString timecomplete = zstat[i].section(" ",4,4,QString::SectionSkipEmpty);
	  QString errors = zstat[i].section(" ", 6,6,QString::SectionSkipEmpty);
	  //Setup the running re-silvering progress
	  if(LOGS.value(50) != "FINISHED" && LOGS.value(50) != "ERROR" ){newresilver=true; } //don't display message for first run
	  if(errors.toInt() > 0){ 
	    LOGS.insert(50, "ERROR");
	    LOGS.insert(52, QString(tr("Resilver completed in %1 with %2 errors")).arg(timecomplete, errors) );
	    LOGS.insert(53, QString(tr("Resilver completed in %1 with %2 errors")).arg(timecomplete, errors) );
	  }else{
	    LOGS.insert(50, "FINISHED");
	    LOGS.insert(52, QString(tr("Resilver completed successfully in %1")).arg(timecomplete) );
	    LOGS.insert(53, QString(tr("Resilver completed successfully in %1")).arg(timecomplete) ); 
          }
	  // 51 - need to put the actual device in here (not available on this line)
	  LOGS.insert(54, timestamp);
	  LOGS.insert(55, timestamp.section(" ",3,3) );
	  if(LOGS.contains(60) ){
	    //Only resilvering OR scrub is shown at a time - so remove the scrub info
	    LOGS.remove(60);
	    LOGS.remove(61);
	    LOGS.remove(62);
	    LOGS.remove(63);
	    LOGS.remove(64);
	    LOGS.remove(65);
	  }
	  if(timer->interval() != sysCheckTime){ timer->start(sysCheckTime); }
	}
      }else if(zstat[i].startsWith("errors:")){
	if(zstat[i] != "errors: No known data errors"){
	  qDebug() << "New zpool status error line that needs parsing:" << zstat[i];
	}
      }else if( state != "ONLINE" || !LOGS.value(50).isEmpty() ){
        //Check for state/resilvering of all real devices
	QString msg, summary, status;
	QString device = zstat[i].section(" ",0,0,QString::SectionSkipEmpty);
	if(zstat[i].contains("NAME STATE READ")){continue;} //nothing on this header line
	else if(zstat[i].contains("(resilvering)")){ LOGS.insert(51, device ); continue;}
	else if(zstat[i].contains("ONLINE")){continue;} //do nothing for this device - it is good
	else if(zstat[i].contains("OFFLINE")){ continue; } //do nothing - this status must be set manually - it is not a "random" status
        else if(zstat[i].contains("DEGRADED")){
	  // This should only happen on pools, not actual devices
	  cStat << "DEGRADED";
	  cMsg << tr("The pool is in a degraded state. See additional device error(s).");
	  cSummary << QString(tr("%1 is degraded.")).arg(device);
	  cDev << device;
	}else if(zstat[i].contains("FAULTED")){ 
	  cStat << "FAULTED";
	  cMsg << tr("The device is faulty, and should be replaced.");
	  cSummary << QString(tr("%1 is faulty.")).arg(device);
	  cDev << device;
	}else if(zstat[i].contains("REMOVED")){ 
	  cStat << "REMOVED";
	  cMsg << tr("The device was removed, and should be either be re-attached or replaced.");
	  cSummary << QString(tr("%1 was removed.")).arg(device);
	  cDev << device;
	}else if(zstat[i].contains("UNAVAIL")){ 
	  cStat << "UNAVAILABLE";
	  cMsg << tr("The device is unavailable and should be re-added to the pool.");
	  cSummary << QString(tr("%1 is unavailable.")).arg(device);
	  cDev << device;
	}
      }
    } //end of loop over zpool status lines
    
  //Add the critical messages to the hash
  if(cStat.isEmpty() || (cStat.join(" ").simplified() == "DEGRADED") ){
    //No errors, or the pool is degraded without any additional errors (usually because of a resilver going on)
    if(LOGS.contains(30)){
      LOGS.remove(30);
      LOGS.remove(31);
      LOGS.remove(32);
      LOGS.remove(33);
      LOGS.remove(34);
      LOGS.remove(35);
    }
  }else{
    if(LOGS.value(30) != cStat.join(":::") ){ newerror = true; }
    LOGS.insert(30, cStat.join(":::") );
    LOGS.insert(31, cDev.join(":::") );
    LOGS.insert(32, cSummary.join(":::") );
    LOGS.insert(33, cMsg.join(":::") );
    LOGS.insert(34, timestamp);
    LOGS.insert(35, timestamp.section(" ",3,3) );
  }
    
  //Now emit the appropriate signal
  if(newerror){ emit MessageAvailable("critical"); }
  else if(newresilver){ emit MessageAvailable("resilver"); }
  else if(newscrub){ emit MessageAvailable("scrub"); }
  else{ emit StatusUpdated(); }
}
Esempio n. 4
0
// -------------------------------------
//    PRIVATE FUNCTIONS
// -------------------------------------
void LPWatcher::readLogFile(bool quiet){
  QStringList reppools = listReplicatedPools();
  QTextStream in(logfile);
  while(!LFSTREAM->atEnd()){
    QString log = LFSTREAM->readLine();
    //Divide up the log into it's sections
    QString timestamp = log.section(":",0,2).simplified();
    QString time = timestamp.section(" ",3,3).simplified();
    QString message = log.section(":",3,3).toLower().simplified();
    QString dev = log.section(":",4,4).simplified(); //dataset/snapshot/nothing
    //Now decide what to do/show because of the log message
    //qDebug() << "New Log Message:" << log;
    if(message.contains("creating snapshot")){
      dev = message.section(" ",-1).simplified();
      //Setup the status of the message
      LOGS.insert(10,"SNAPCREATED");
      LOGS.insert(11,dev); //dataset
      LOGS.insert(12, QString(tr("New snapshot of %1")).arg(dev) ); //summary
      LOGS.insert(13, QString(tr("Creating snapshot for %1")).arg(dev) );
      LOGS.insert(14, timestamp); //full timestamp
      LOGS.insert(15, time); // time only
      if(!quiet){ emit MessageAvailable("message"); }
    }else if(message.contains("starting replication")){
      //Setup the file watcher for this new log file
      FILE_REPLICATION = dev;
      dev = message.section(" ",5,5,QString::SectionSkipEmpty);
      //Make sure the device is currently setup for replication
      if( !reppools.contains(dev) ){ FILE_REPLICATION.clear(); continue; }
      //Try to start the replication watcher
      if( startRepFileWatcher() ){
        //Set the appropriate status variables
        LOGS.insert(20,"STARTED");
        LOGS.insert(21, dev); //zpool
        LOGS.insert(22, tr("Replication Starting") ); //summary
        LOGS.insert(23, QString(tr("Starting replication for %1")).arg(dev) ); //Full message
        LOGS.insert(24, timestamp); //full timestamp
        LOGS.insert(25, time); // time only
        LOGS.insert(26,tr("Replication Log")+" <"+FILE_REPLICATION+">"); //log file
        if(!quiet){ emit MessageAvailable("replication"); }
      }
    }else if(message.contains("finished replication")){
      stopRepFileWatcher();
      dev = message.section(" ",-1).simplified();
      //Make sure the device is currently setup for replication
      if( reppools.contains(dev) ){
        //Now set the status of the process
        LOGS.insert(20,"FINISHED");
        LOGS.insert(21,dev); //dataset
        LOGS.insert(22, tr("Finished Replication") ); //summary
        LOGS.insert(23, QString(tr("Finished replication for %1")).arg(dev) );
        LOGS.insert(24, timestamp); //full timestamp
        LOGS.insert(25, time); // time only
        LOGS.insert(26, ""); //clear the log file entry
        if(!quiet){ emit MessageAvailable("replication"); }
      }else if( !reppools.contains( LOGS.value(21) ) ){
        //Clear the current replication log, device was removed from replication
	LOGS.remove(20);
	LOGS.remove(21);
	LOGS.remove(22);
	LOGS.remove(23);
	LOGS.remove(24);
	LOGS.remove(25);
	LOGS.remove(26);
	if(!quiet){ emit MessageAvailable(""); }
      }
    }else if( message.contains("failed replication") ){
      stopRepFileWatcher();
      //Now set the status of the process
      dev = message.section(" ",-1).simplified();
      //Make sure the device is currently setup for replication
      if( reppools.contains(dev) ){
	//Update the logs
        QString file = log.section("LOGFILE:",1,1).simplified();
        QString tt = QString(tr("Replication Failed for %1")).arg(dev) +"\n"+ QString(tr("Logfile available at: %1")).arg(file);
        LOGS.insert(20,"ERROR");
        LOGS.insert(21,dev); //dataset
        LOGS.insert(22, tr("Replication Failed") ); //summary
        LOGS.insert(23, tt );
        LOGS.insert(24, timestamp); //full timestamp
        LOGS.insert(25, time); // time only      
        LOGS.insert(26, tr("Replication Error Log")+" <"+file+">" );
        if(!quiet){ emit MessageAvailable("replication"); }
      }else if( !reppools.contains( LOGS.value(21) ) ){
        //Clear the current replication log, device was removed from replication
	LOGS.remove(20);
	LOGS.remove(21);
	LOGS.remove(22);
	LOGS.remove(23);
	LOGS.remove(24);
	LOGS.remove(25);
	LOGS.remove(26);
	if(!quiet){ emit MessageAvailable(""); }
      }
    }
	  
  }
}
Esempio n. 5
0
void LPWatcher::checkPoolStatus(){
  //Now check zpool status for bad/running statuses
  QStringList zstat = LPBackend::getCmdOutput("zpool status");
    //parse the output
    QString pool, state, timestamp;
    qDebug() << "-----zpool status------";
    bool newresilver = false;
    for(int i=0; i<zstat.length(); i++){
      zstat[i] = zstat[i].simplified();
      if(zstat[i].isEmpty()){ continue; }
      qDebug() << zstat[i];
      if(zstat[i].startsWith("pool:")){ pool = zstat[i].section(":",1,10).simplified(); }
      else if(zstat[i].startsWith("state:")){ state = zstat[i].section(":",1,10).simplified(); }
      else if(zstat[i].startsWith("scan:")){
	//check for scrubs/resilvering progress
	bool isnew = false;
	// ------ SCRUB ------
	if(zstat[i].contains("scrub")){
	  //Setup the latest/running scrub info
	  if(zstat[i].contains(" scrub repaired ")){
	    zstat[i]  = zstat[i].replace("\t"," ").simplified();
	    timestamp = zstat[i].section(" ",10,14,QString::SectionSkipEmpty);
	    QString numFixed = zstat[i].section(" ",3,3,QString::SectionSkipEmpty);
	    QString numErr = zstat[i].section(" ",7,7,QString::SectionSkipEmpty);
	    QString timeRun = zstat[i].section(" ",5,5,QString::SectionSkipEmpty);
	    //Scrub finished previously
	    if(numFixed.toInt() > 0){ 
	      if(LOGS.value(60)!="ERROR"){ isnew=true; }
	      LOGS.insert(60, "ERROR"); 
	      LOGS.insert(62, QString(tr("Scrub repaired %1 bad blocks")).arg(numFixed) );
	      LOGS.insert(63, QString(tr("Scrub repaired %1 blocks in %2 with %3 errors")).arg(numFixed, timeRun, numErr) );
	    }else{ 
	      if(LOGS.value(60)!= " " && LOGS.value(60)!="FINISHED"){ isnew=true; }
	      LOGS.insert(60,"FINISHED"); 
	      LOGS.insert(62, tr("Scrub completed") );
	      LOGS.insert(63, tr("Scrub completed without needing repairs") );
	    }
	    LOGS.insert(61,pool);
	    LOGS.insert(64, timestamp);
	    LOGS.insert(65, timestamp.section(" ",3,3) );
	  }else{
	    //Scrub is running - parse the line
	    timestamp = "??";
	    QString percent = "??";
	    QString remain = "??";
	    if(LOGS.value(60) != "RUNNING"){isnew=true;}
	    LOGS.insert(60,"RUNNING");
	    LOGS.insert(61,pool);
	    LOGS.insert(62, QString(tr("Scrubbing: %1 (%2 remaining)")).arg(percent, remain) );
	    LOGS.insert(63, QString(tr("Scrubbing: %1 (%2 remaining)")).arg(percent, remain) );
	    LOGS.insert(64, timestamp);
	    LOGS.insert(65, timestamp.section(" ",3,3) );
	    qDebug() << "***Running Scrub: line needs parsing";
	  }
	  if(isnew){ emit MessageAvailable("scrub"); }
	  if(LOGS.contains(50) ){
	    //Only resilvering OR scrub is shown at a time - so remove the resilver info
	    LOGS.remove(50);
	    LOGS.remove(51);
	    LOGS.remove(52);
	    LOGS.remove(53);
	    LOGS.remove(54);
	    LOGS.remove(55);
	  }
	// --------- RESILVERING -------
	}else if(zstat[i].contains("resilver in progress")){
	  //Resilvering is currently running
	  timestamp = zstat[i].section(" ",5,9,QString::SectionSkipEmpty);
	  //need info from the next two lines
	  i++; QString timeleft = zstat[i].section(" ",7,7,QString::SectionSkipEmpty);
	  i++; QString percent = zstat[i].section(" ", 2,2,QString::SectionSkipEmpty);
	  //Setup the running re-silvering progress
	  if(LOGS.value(50)!="RUNNING"){newresilver=true; }
	  LOGS.insert(50, "RUNNING");
	  // 51 - need to put the actual device in here (not available on this line)
	  LOGS.insert(52, QString(tr("Resilvering: %1 (%2 remaining)")).arg(percent, timeleft) );
	  if(newresilver){ LOGS.insert(53, QString(tr("Resilvering Started: %1 remaining ")).arg( timeleft) ); }
	  else{ LOGS.insert(53,QString(tr("Resilvering: %1 (%2 remaining)")).arg(percent, timeleft) ); }
	  LOGS.insert(54, timestamp);
	  LOGS.insert(55, timestamp.section(" ",3,3) );
	  if(LOGS.contains(60) ){
	    //Only resilvering OR scrub is shown at a time - so remove the scrub info
	    LOGS.remove(60);
	    LOGS.remove(61);
	    LOGS.remove(62);
	    LOGS.remove(63);
	    LOGS.remove(64);
	    LOGS.remove(65);
	  }
	}else if(zstat[i].contains("resilvered")){
	  //Resilvering is finished
	  timestamp = zstat[i].section(" ",9,13,QString::SectionSkipEmpty);
	  QString timecomplete = zstat[i].section(" ",4,4,QString::SectionSkipEmpty);
	  QString errors = zstat[i].section(" ", 6,6,QString::SectionSkipEmpty);
	  //Setup the running re-silvering progress
	  if(LOGS.value(50)!= " "){newresilver=true; } //don't display message for first run
	  if(errors.toInt() > 0){ 
	    LOGS.insert(50, "ERROR");
	    LOGS.insert(52, QString(tr("Resilver completed in &1 with %2 errors")).arg(timecomplete, errors) );
	    LOGS.insert(53, QString(tr("Resilver completed in &1 with %2 errors")).arg(timecomplete, errors) );
	  }else{
	    LOGS.insert(50, "FINISHED");
	    LOGS.insert(52, QString(tr("Resilver completed successfully in &1")).arg(timecomplete) );
	    LOGS.insert(53, QString(tr("Resilver completed successfully in &1")).arg(timecomplete) ); 
          }
	  // 51 - need to put the actual device in here (not available on this line)
	  LOGS.insert(54, timestamp);
	  LOGS.insert(55, timestamp.section(" ",3,3) );
	  if(LOGS.contains(60) ){
	    //Only resilvering OR scrub is shown at a time - so remove the scrub info
	    LOGS.remove(60);
	    LOGS.remove(61);
	    LOGS.remove(62);
	    LOGS.remove(63);
	    LOGS.remove(64);
	    LOGS.remove(65);
	  }
	}
      }else if(zstat[i].startsWith("errors:")){
	if(zstat[i] != "errors: No known data errors"){
	  qDebug() << "New zpool status error line that needs parsing:" << zstat[i];
	}
      }else if( state != "ONLINE" || !LOGS.value(50).isEmpty() ){
        //Check for state/resilvering of all real devices
	if(zstat[i].contains("NAME\tSTATE\tREAD")){continue;} //nothing on this header line
	else if(zstat[i].contains("(resilvering)")){ LOGS.insert(51, zstat[i].section("\t",0,0,QString::SectionSkipEmpty) ); }
	else if(zstat[i].contains("ONLINE")){continue;} //do nothing for this device - it is good
	else if(zstat[i].contains("OFFLINE")){ }
	else if(zstat[i].contains("DEGRADED")){ }
	else if(zstat[i].contains("FAULTED")){ }
	else if(zstat[i].contains("REMOVED")){ }
	else if(zstat[i].contains("UNAVAIL")){ }
      }
    } //end of loop over zpool status lines
  if(newresilver){ emit MessageAvailable("resilvering"); }
}
Esempio n. 6
0
// -------------------------------------
//    PRIVATE FUNCTIONS
// -------------------------------------
void LPWatcher::readLogFile(bool quiet){
  QTextStream in(logfile);
  while(!LFSTREAM->atEnd()){
    QString log = LFSTREAM->readLine();
    //Divide up the log into it's sections
    QString timestamp = log.section(":",0,2).simplified();
    QString time = timestamp.section(" ",3,3).simplified();
    QString message = log.section(":",3,3).toLower().simplified();
    QString dev = log.section(":",4,4).simplified(); //dataset/snapshot/nothing
    //Now decide what to do/show because of the log message
    //qDebug() << "New Log Message:" << log;
    if(message.contains("creating snapshot")){
      dev = message.section(" ",-1).simplified();
      //Setup the status of the message
      LOGS.insert(10,"SNAPCREATED");
      LOGS.insert(11,dev); //dataset
      LOGS.insert(12, QString(tr("New snapshot of %1")).arg(dev) ); //summary
      LOGS.insert(13, QString(tr("Creating snapshot for %1")).arg(dev) );
      LOGS.insert(14, timestamp); //full timestamp
      LOGS.insert(15, time); // time only
      if(!quiet){ emit MessageAvailable("message"); }
    }else if(message.contains("starting replication")){
      //Setup the file watcher for this new log file
      FILE_REPLICATION = dev;
      startRepFileWatcher();
      //Set the appropriate status variables
      LOGS.insert(20,"REPSTARTED");
      // 21 - dataset set on update ping
      LOGS.insert(22, tr("Replication Started") ); //summary
      // 23 - Full message set on update ping
      LOGS.insert(24, timestamp); //full timestamp
      LOGS.insert(25, time); // time only
      if(!quiet){ emit MessageAvailable("replication"); }
    }else if(message.contains("finished replication")){
      stopRepFileWatcher();
      dev = message.section(" ",-1).simplified();
      //Now set the status of the process
      LOGS.insert(20,"REPFINISHED");
      LOGS.insert(21,dev); //dataset
      LOGS.insert(22, tr("Finished Replication") ); //summary
      LOGS.insert(23, QString(tr("Finished replication for %1")).arg(dev) );
      LOGS.insert(24, timestamp); //full timestamp
      LOGS.insert(25, time); // time only      
      if(!quiet){ emit MessageAvailable("replication"); }
    }else if( message.contains("FAILED replication") ){
      stopRepFileWatcher();
      //Now set the status of the process
      dev = message.section(" ",-1).simplified();
      QString file = log.section("LOGFILE:",1,1).simplified();
      QString tt = QString(tr("Replication Failed for %1")).arg(dev) +"\n"+ QString(tr("Logfile available at: %1")).arg(file);
      LOGS.insert(20,"REPERROR");
      LOGS.insert(21,dev); //dataset
      LOGS.insert(22, tr("Replication Failed") ); //summary
      LOGS.insert(23, tt );
      LOGS.insert(24, timestamp); //full timestamp
      LOGS.insert(25, time); // time only      
      if(!quiet){ emit MessageAvailable("replication"); }
    }
	  
  }
}
Esempio n. 7
0
//PUBLIC
LPTray::LPTray() : QSystemTrayIcon() {
    qDebug() << "Starting up Life-preserver Tray...";
    //Start up the log file watcher and connect the signals/slots
    watcher = new LPWatcher();
    connect(watcher,SIGNAL(MessageAvailable(QString)),this,SLOT(watcherMessage(QString)) );
    connect(watcher,SIGNAL(StatusUpdated()),this,SLOT(watcherMessage()) );
    //Load the tray settings file
    settings = new QSettings(QSettings::UserScope,"PCBSD", "life-preserver-tray");
    //Create the notification option widgets
    nShowAll = new QRadioButton(tr("Show all"));
    naAll = new QWidgetAction(this);
    naAll->setDefaultWidget(nShowAll);
    nShowError = new QRadioButton(tr("Warnings Only"));
    naErr = new QWidgetAction(this);
    naErr->setDefaultWidget(nShowError);
    nShowNone = new QRadioButton(tr("None"));
    naNone = new QWidgetAction(this);
    naNone->setDefaultWidget(nShowNone);
    //Create notification menu
    notificationMenu = new QMenu(tr("Popup Settings"));
    notificationMenu->setIcon( QIcon(":/images/configure.png") );
    notificationMenu->addAction(naAll);
    notificationMenu->addAction(naErr);
    notificationMenu->addAction(naNone);
    //Activate the proper notification setting widget
    QString popset = settings->value("popup-policy", "").toString();
    qDebug() << "Current Popup Policy:" << popset;
    if(popset=="all") {
        nShowAll->setChecked(true);
        popupPolicy = 2;
    }
    else if(popset=="errors") {
        nShowError->setChecked(true);
        popupPolicy = 1;
    }
    else if(popset=="none") {
        nShowNone->setChecked(true);
        popupPolicy = 0;
    }
    else {
        nShowError->setChecked(true);
        settings->setValue("popup-policy","errors"); //save the proper setting
        popupPolicy = 1;
    }
    //Now connect the popup settings signals/slots
    connect(nShowAll, SIGNAL(clicked()), this, SLOT(changePopupPolicy()) );
    connect(nShowError, SIGNAL(clicked()), this, SLOT(changePopupPolicy()) );
    connect(nShowNone, SIGNAL(clicked()), this, SLOT(changePopupPolicy()) );
    //Setup the context menu
    menu = new QMenu;
    menu->addAction(QIcon(":/images/tray-icon-idle.png"),tr("Open Life Preserver"),this,SLOT(startGUI()) );
    menu->addSeparator();
    menu->addAction(QIcon(":/images/backup-failed.png"),tr("View Messages"),this,SLOT(startMessageDialog()) );
    menu->addMenu(notificationMenu);
    menu->addAction(QIcon(":/images/refresh.png"),tr("Refresh Tray"),this,SLOT(refreshStatus()) );
    menu->addSeparator();
    menu->addAction(QIcon(":/images/application-exit.png"),tr("Close Tray"),this,SLOT(slotClose()) );
    this->setContextMenu(menu);
    //Setup initial icon for the tray
    this->setIcon( QIcon(":/images/tray-icon-idle.png") );
    //Create the messages GUI
    msgdlg = new LPMessages();
    //connect other signals/slots
    connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)) );
    //Start up the watcher
    watcher->start();
    updateTrayIcon();
    updateToolTip();
}