QStringList LPWatcher::listReplicatedPools(){ QStringList out; QStringList cmdout = getCmdOutput("lpreserver replicate list"); for(int i=0; i<cmdout.length(); i++){ if(cmdout[i].contains("->")){ QString ds = cmdout[i].section("->",0,0).simplified(); if(!ds.isEmpty()){ out << ds; } } } return out; }
std::string GetMac(std::string oneIP) { std::string txt="arp -a "+oneIP;//+" |awk '{print $4}'"; printf("GetMac: "); printf(txt.c_str()); std::string resultado; //getCmdOutput("( ping "+oneIP+" -c 1 )"); resultado=getCmdOutput("( "+txt+" )"); for(int i =0;i<3;i++) { resultado=resultado.substr(resultado.find(" ")+1); } printf("FOR: "); printf(resultado.c_str()); printf("\n"); resultado=resultado.substr(0,resultado.find(" ")); return resultado; }
std::string CommandEventHandler::ps(std::vector<std::string>& args) { // might need to change command on linux since the output is different on B2G return getCmdOutput("ps | tr -s \" \" | cut -d' ' -f1,2,9 | tail +2"); }
// need to figure a better way std::string CommandEventHandler::uptime() { return getCmdOutput("uptime"); }
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(); } }
int main() { SSVU_TEST_RUN_ALL(); ssvu::lo("Dictionary") << "Loading dictionary" << std::endl; auto dictionary(getReadFileLineByLine("/media/veeData/Temp/itaDict.txt")); ssvu::lo("Dictionary") << "Done" << std::endl; std::srand(std::time(0)); auto getRndWord([&dictionary]() -> std::string { return dictionary[ssvu::getRnd(0ul, dictionary.size())]; }); auto getSanitized([](const std::string& mStr) { return ssvu::getReplacedAll(mStr, " ", "%20"); }); // ssvu::lo("Dictionary") << "10 random words" << std::endl; for(auto i(0u); i < 10; ++i) ssvu::lo() << getSyllabized(getRndWord()) << std::endl; std::string curlPrefix{ R"(curl 'https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=)"}; auto getGoogleResult([&curlPrefix, &getSanitized](const std::string& mStr) { return getCmdOutput(curlPrefix + getSanitized(mStr) + R"(')") + "}"; }); auto getRndImgUrl([&getGoogleResult](const std::string& mStr) { return getRndImgUrlFromJson(getGoogleResult(mStr)); }); std::vector<std::string> words, urls, extensions, paths; std::string pathOutput{"/media/veeData/Temp/rebusOutput.png"}; words.emplace_back("test"); words.emplace_back("test"); for(const auto& w : words) urls.emplace_back(getRndImgUrl(w)); for(const auto& u : urls) extensions.emplace_back(getExtension(u)); for(auto i(0u); i < words.size(); ++i) { paths.emplace_back( "/media/veeData/img" + ssvu::toStr(i) + getExtension(urls[i])); ssvu::lo() << urls[i] << " -> " << paths[i] << std::endl; getCmdOutput(R"(curl ')" + urls[i] + R"(' > ')" + paths[i] + R"(')"); } std::string lenString, pathString; for(auto i(0u); i < words.size(); ++i) { lenString += ssvu::toStr(words[i].size()); pathString += paths[i]; if(i != words.size() - 1) { lenString += ", "; pathString += " "; } } std::string imgSize{ssvu::toStr(paths.size() * 400)}; getCmdOutput(R"(montage )" + pathString + R"( -tile )" + ssvu::toStr(words.size()) + R"(x1 -geometry )" + imgSize + "x600 " + pathOutput); getCmdOutput("convert -pointsize 48 " + pathOutput + " -background Khaki label:'(" + lenString + ")' -gravity Center -append " + pathOutput); return 0; }
vector<string> getCmdOutputStrings(const char* cmd) { return MakeStrings(getCmdOutput(cmd)); }