mirror of
https://github.com/outbackdingo/sysadm.git
synced 2026-01-27 02:20:17 +00:00
Make sure the system update check is done via a DISPATCHER process.
This prevent possible hangs in the main server thread from the health check, and also ensures that the system update check API call can now return a new "checkingforupdates" status.
This commit is contained in:
@@ -182,6 +182,24 @@ QJsonObject Dispatcher::killJobs(QStringList ids){
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool Dispatcher::isJobActive(QString ID){
|
||||
//qDebug() << " - Is Job Active:" << ID;
|
||||
for(int i=0; i<enum_length; i++){
|
||||
PROC_QUEUE queue = static_cast<PROC_QUEUE>(i);
|
||||
if(HASH.contains(queue)){
|
||||
QList<DProcess*> list = HASH[queue];
|
||||
for(int j=0; j<list.length(); j++){
|
||||
if(ID == list[j]->ID){
|
||||
//qDebug() << " -- " << !list[j]->isDone();
|
||||
return !(list[j]->isDone());
|
||||
}
|
||||
} //end loop over list
|
||||
}
|
||||
}
|
||||
//qDebug() << " -- NO";
|
||||
return false; //could not find process with this ID
|
||||
}
|
||||
|
||||
void Dispatcher::start(QString queuefile){
|
||||
//Setup connections here (in case it was moved to different thread after creation)
|
||||
//connect(this, SIGNAL(mkprocs(Dispatcher::PROC_QUEUE, DProcess*)), this, SLOT(mkProcs(Dispatcher::PROC_QUEUE, DProcess*)) );
|
||||
@@ -243,7 +261,7 @@ void Dispatcher::ProcFinished(QString ID, QJsonObject log){
|
||||
//qDebug() << " - Got Proc Finished Signal:" << ID;
|
||||
LogManager::log(LogManager::DISPATCH, log);
|
||||
//First emit any subsystem-specific event, falling back on the raw log
|
||||
QJsonObject ev = CreateDispatcherEventNotification(ID,log);
|
||||
QJsonObject ev = CreateDispatcherEventNotification(ID,log, true);
|
||||
if(!ev.isEmpty()){
|
||||
emit DispatchEvent(ev);
|
||||
}else{
|
||||
@@ -254,7 +272,7 @@ void Dispatcher::ProcFinished(QString ID, QJsonObject log){
|
||||
|
||||
void Dispatcher::ProcUpdated(QString ID, QJsonObject log){
|
||||
//See if this needs to generate an event
|
||||
QJsonObject ev = CreateDispatcherEventNotification(ID,log);
|
||||
QJsonObject ev = CreateDispatcherEventNotification(ID,log, false);
|
||||
if(!ev.isEmpty()){
|
||||
emit DispatchEvent(ev);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
|
||||
QJsonObject listJobs();
|
||||
QJsonObject killJobs(QStringList ids);
|
||||
bool isJobActive(QString ID); //returns true if a job with this ID is running/pending
|
||||
|
||||
public slots:
|
||||
//Main start/stop
|
||||
@@ -84,7 +85,7 @@ private:
|
||||
|
||||
//Simplification routine for setting up a process
|
||||
DProcess* createProcess(QString ID, QStringList cmds, QString workdir = "");
|
||||
QJsonObject CreateDispatcherEventNotification(QString, QJsonObject);
|
||||
QJsonObject CreateDispatcherEventNotification(QString, QJsonObject, bool);
|
||||
|
||||
// Functions to do parsing out dispatcher queued tasks
|
||||
// Please keep these sorted
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
#include "globals-qt.h"
|
||||
#include "EventWatcher.h"
|
||||
#include "Dispatcher.h"
|
||||
#include "library/sysadm-update.h"
|
||||
|
||||
QJsonObject Dispatcher::CreateDispatcherEventNotification(QString ID, QJsonObject log, bool full_log){
|
||||
//NOTE: full_log = true when the process has finished. If it is false, the process is still running and you are probably getting an incremental update of the process log
|
||||
|
||||
QJsonObject Dispatcher::CreateDispatcherEventNotification(QString ID, QJsonObject log){
|
||||
//key outputs - need to set these if an event is going to be sent out
|
||||
QJsonObject args; //any arguments to send out
|
||||
QString namesp, name; //the namespace/name of the subsystem used
|
||||
@@ -26,7 +29,7 @@ QJsonObject Dispatcher::CreateDispatcherEventNotification(QString ID, QJsonObjec
|
||||
//Add the generic process values
|
||||
args.insert("state",log.value("state").toString());
|
||||
args.insert("process_details", log); //full process log array here
|
||||
|
||||
|
||||
//Now parse the notification based on the dispatch ID or current command
|
||||
//NOTE: There might be a random string on the end of the ID (to accomodate similar process calls)
|
||||
// == sysadm/iohyve ==
|
||||
@@ -37,14 +40,18 @@ QJsonObject Dispatcher::CreateDispatcherEventNotification(QString ID, QJsonObjec
|
||||
//Do some parsing of the log
|
||||
parseIohyveFetchOutput(cLog,&args);
|
||||
}
|
||||
|
||||
|
||||
// == sysadm/update ==
|
||||
}else if(ID.startsWith("sysadm_update")){
|
||||
namesp = "sysadm"; name="update";
|
||||
//No special parsing here: the pc-updatemanager output should be available as-is
|
||||
args.insert("update_log",cLog);
|
||||
|
||||
|
||||
if(ID.section("::",0,0)=="sysadm_update_runupdates"){
|
||||
namesp = "sysadm"; name="update";
|
||||
//No special parsing here: the pc-updatemanager output should be available as-is
|
||||
args.insert("update_log",cLog);
|
||||
}else if(full_log && ID.section("::",0,0)=="sysadm_update_checkupdates"){
|
||||
//qDebug() << "Got update check process finished";
|
||||
sysadm::Update::saveCheckUpdateLog(cLog); //save this for use later
|
||||
}
|
||||
|
||||
// == sysadm/pkg ==
|
||||
}else if(ID.startsWith("sysadm_pkg")){
|
||||
namesp = "sysadm"; name="pkg";
|
||||
@@ -56,7 +63,7 @@ QJsonObject Dispatcher::CreateDispatcherEventNotification(QString ID, QJsonObjec
|
||||
bool hasupdates = !cLog.contains("Your packages are up to date.");
|
||||
args.insert("updates_available", hasupdates ? "true" : "false");
|
||||
}
|
||||
|
||||
|
||||
}else if(ID.section("-",0,0)=="sysadm_pkg_audit" && isFinished){
|
||||
QStringList info = cLog.split("\n");
|
||||
QStringList vuln, effects;
|
||||
@@ -71,9 +78,9 @@ QJsonObject Dispatcher::CreateDispatcherEventNotification(QString ID, QJsonObjec
|
||||
args.insert("vulnerable_pkgs",QJsonArray::fromStringList(vuln));
|
||||
args.insert("impacts_pkgs",QJsonArray::fromStringList(effects));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Now assemble the output as needed
|
||||
if(namesp.isEmpty() || name.isEmpty()){ return QJsonObject(); } //no event
|
||||
args.insert("event_system",namesp+"/"+name);
|
||||
@@ -93,3 +100,7 @@ void Dispatcher::parseIohyveFetchOutput(QString outputLog, QJsonObject *out){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*void Dispatcher::parseUpdateCheckOutput(QString outputLog, QJsonObject *out){
|
||||
|
||||
}*/
|
||||
|
||||
@@ -368,6 +368,7 @@ void EventWatcher::CheckSystemState(){
|
||||
|
||||
//Next Check for Updates
|
||||
QJsonObject updates = sysadm::Update::checkUpdates(true); //do the "fast" version of updates
|
||||
//qDebug() << "Health check - got updates status:" << updates;
|
||||
if(!updates.isEmpty()){
|
||||
if(updates.value("status").toString()!="noupdates"){
|
||||
int tmp = 2;
|
||||
@@ -387,6 +388,8 @@ void EventWatcher::CheckSystemState(){
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(updates.value("status").toString()=="checkingforupdates"){
|
||||
//do nothing more here - still checking for updates
|
||||
}else if(updates.value("status").toString()!="updaterunning"){
|
||||
//updates are available - see if the auto-update flag is set, and start the updates as needed
|
||||
QJsonObject upset = sysadm::Update::readSettings();
|
||||
|
||||
@@ -39,6 +39,11 @@ QJsonObject Update::checkUpdates(bool fast) {
|
||||
if(!QFile::exists("/usr/local/bin/pc-updatemanager")){
|
||||
return retObject;
|
||||
}
|
||||
//See if the check for updates is currently running - just return nothing at the moment for that
|
||||
if(DISPATCHER->isJobActive("sysadm_update_checkupdates")){
|
||||
retObject.insert("status", "checkingforupdates");
|
||||
return retObject;
|
||||
}
|
||||
//Check if the system is waiting to reboot
|
||||
if(QFile::exists(UP_RBFILE)){
|
||||
retObject.insert("status","rebootrequired");
|
||||
@@ -57,7 +62,7 @@ QJsonObject Update::checkUpdates(bool fast) {
|
||||
return retObject;
|
||||
}
|
||||
}
|
||||
//Get the list of deatils from the update checks (fast/full)
|
||||
//Get the list of details from the update checks (fast/full)
|
||||
QStringList output;
|
||||
QDateTime cdt = QDateTime::currentDateTime();
|
||||
QDateTime fdt = cdt.addDays(-1); //just enough to trip the checks below if needed
|
||||
@@ -72,18 +77,23 @@ QJsonObject Update::checkUpdates(bool fast) {
|
||||
//Note: The "fast" check will only be used if the last full check was less than 12 hours earlier.
|
||||
//qDebug() << " - UseFast Re-read";
|
||||
output = General::readTextFile(UP_UPFILE);
|
||||
}else if(secs<600 ){
|
||||
//Note: This will re-use the previous check if it was less than 10 minutes ago (prevent hammering servers from user checks)
|
||||
//qDebug() << " - Use Fast Re-read (failsafe - less than 10 minute interval)";
|
||||
}else if(secs<300 ){
|
||||
//Note: This will re-use the previous check if it was less than 5 minutes ago (prevent hammering servers from user checks)
|
||||
//qDebug() << " - Use Fast Re-read (failsafe - less than 5 minute interval)";
|
||||
output = General::readTextFile(UP_UPFILE);
|
||||
}else{
|
||||
//qDebug() << " - Run full check";
|
||||
General::RunCommand("pc-updatemanager syncconf"); //always resync the config file before starting an update check
|
||||
QStringList cmds; cmds << "pc-updatemanager syncconf" << "pc-updatemanager pkgcheck";
|
||||
DISPATCHER->queueProcess("sysadm_update_checkupdates", cmds );
|
||||
retObject.insert("status", "checkingforupdates");
|
||||
//qDebug() << " - Done starting check";
|
||||
return retObject;
|
||||
/*General::RunCommand("pc-updatemanager syncconf"); //always resync the config file before starting an update check
|
||||
output.append( General::RunCommand("pc-updatemanager pkgcheck").split("\n") );
|
||||
while(output.last().simplified()==""){ output.removeLast(); }
|
||||
if(!output.last().contains("ERROR:")){ //make sure there was network access available first - otherwise let it try again soon
|
||||
General::writeTextFile(UP_UPFILE, output); //save this check for later "fast" updates
|
||||
}
|
||||
}*/
|
||||
}
|
||||
//qDebug() << "pc-updatemanager checks:" << output;
|
||||
|
||||
@@ -139,6 +149,16 @@ QJsonObject Update::checkUpdates(bool fast) {
|
||||
return retObject;
|
||||
}
|
||||
|
||||
void Update::saveCheckUpdateLog(QString log){
|
||||
QStringList output = log.split("\n");
|
||||
qDebug() << "Got Check Update Log:" << log << output;
|
||||
while(!output.isEmpty() && output.last().simplified().isEmpty()){ output.removeLast(); }
|
||||
if(output.isEmpty()){ return; }
|
||||
if(!output.last().contains("ERROR:")){ //make sure there was network access available first - otherwise let it try again soon
|
||||
General::writeTextFile(UP_UPFILE, output); //save this check for later "fast" updates
|
||||
}
|
||||
}
|
||||
|
||||
// List available branches we can switch to
|
||||
QJsonObject Update::listBranches() {
|
||||
QJsonObject retObject;
|
||||
|
||||
@@ -19,6 +19,8 @@ public:
|
||||
static QDateTime rebootRequiredSince();
|
||||
//Listing routines
|
||||
static QJsonObject checkUpdates(bool fast = false);
|
||||
static void saveCheckUpdateLog(QString); //Internal for Dispatcher process usage - do not expose to public API
|
||||
|
||||
static QJsonObject listBranches();
|
||||
//Start/stop update routine
|
||||
static QJsonObject startUpdate(QJsonObject);
|
||||
@@ -31,7 +33,7 @@ public:
|
||||
static QJsonObject readLog(QJsonObject);
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user