mirror of
https://github.com/outbackdingo/sysadm.git
synced 2026-01-27 10:20:26 +00:00
Commit my work in progress for the new Dispatcher subsystem. This is ~80% done right now (still filling out some of the internals - but the class framework is set in stone).
This commit is contained in:
137
src/server/Dispatcher.cpp
Normal file
137
src/server/Dispatcher.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// ===============================
|
||||
// PC-BSD REST API Server
|
||||
// Available under the 3-clause BSD License
|
||||
// Written by: Ken Moore <ken@pcbsd.org> 2015-2016
|
||||
// =================================
|
||||
#include "Dispatcher.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
// ================================
|
||||
// DProcess Class (Internal)
|
||||
// ================================
|
||||
DProcess::DProcess(QObject *parent) : QProcess(parent){
|
||||
//Setup the process
|
||||
this->setProcessEnvironment(QProcessEnvironment::systemEnvironment());
|
||||
this->setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
//setup internal connections
|
||||
connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(cmdFinished(int, QProcess::ExitStatus)) );
|
||||
}
|
||||
|
||||
DProcess::~DProcess(){
|
||||
if(this->state()!=QProcess::NotRunning)){
|
||||
this->terminate();
|
||||
}
|
||||
}
|
||||
|
||||
void DProcess::startProc(){
|
||||
if(cmds.isEmpty()){ emit ProcFinished(ID); return; }
|
||||
QString cmd = cmds.takeFirst();
|
||||
success = false; //not finished yet
|
||||
if(!proclog.isEmpty()){ proclog.append("\n"); }
|
||||
proclog.append("[Running Command: "+cmd+" ]");
|
||||
this->start(cmd);
|
||||
}
|
||||
|
||||
bool DProcess::isRunning(){
|
||||
return (this->state()!=QProcess::NotRunning);
|
||||
}
|
||||
|
||||
QString DProcess::getProcLog(){
|
||||
//First update the internal log as needed
|
||||
proclog.append( this->readAllStandardOutput() );
|
||||
//Now return the current version of the log
|
||||
return proclog;
|
||||
}
|
||||
|
||||
void DProcess::cmdFinished(int ret, QProcess::ExitStatus status){
|
||||
//determin success/failure
|
||||
success = (status==QProcess::NormalExit && ret==0);
|
||||
//update the log before starting another command
|
||||
proclog.append( this->readAllStandardOutput() );
|
||||
//Now run any additional commands
|
||||
if(success){ startProc(); }//will emit the finished signal as needed if no more commands
|
||||
else{
|
||||
if(status==QProcess::NormalExit){
|
||||
proclog.append("\n[Command Failed: " + QString::number(ret)+" ]");
|
||||
}else{
|
||||
proclog.append("\n[Command Failed: Process Crashed ]");
|
||||
}
|
||||
emit ProcFinished(ID);
|
||||
}
|
||||
}
|
||||
|
||||
// ================================
|
||||
// Dispatcher Class
|
||||
// ================================
|
||||
Dispatcher::Dispatcher(){
|
||||
|
||||
}
|
||||
|
||||
Dispatcher::~Dispatcher(){
|
||||
|
||||
}
|
||||
|
||||
void Dispatcher::start(QString queuefile){
|
||||
//load any previously-unrun processes
|
||||
// TO DO
|
||||
}
|
||||
|
||||
void Dispatcher::stop(){
|
||||
//save any currently-unrun processes for next time the server starts
|
||||
// TO DO
|
||||
}
|
||||
|
||||
//Overloaded Main Calling Functions (single command, or multiple in-order commands)
|
||||
void Dispatcher::queueProcess(QString ID, QString cmd){
|
||||
queueProcess(NO_QUEUE, ID, QStringList() << cmd);
|
||||
}
|
||||
void Dispatcher::queueProcess(QString ID, QStringList cmds){
|
||||
queueProcess(NO_QUEUE, ID, cmds);
|
||||
}
|
||||
void Dispatcher::queueProcess(Dispatcher::PROC_QUEUE queue, QString ID, QString cmd){
|
||||
queueProcess(queue, ID, QStringList() << cmd);
|
||||
}
|
||||
void Dispatcher::queueProcess(Dispatcher::PROC_QUEUE queue, QString ID, QStringList cmds){
|
||||
//This is the primary queueProcess() function - all the overloads end up here to do the actual work
|
||||
DProcess *P = createProcess(ID, cmds);
|
||||
QList<DProcess*> list;
|
||||
if(!HASH.contains(queue)){ HASH.insert(queue, list); } //insert an empty list
|
||||
HASH[queue] << P; //add this proc to the end of the list
|
||||
if(queue==NO_QUEUE || HASH[queue].length()==1){ P->startProc(); } //go ahead and start it now
|
||||
else{ CheckQueues(); }
|
||||
}
|
||||
|
||||
// === PRIVATE ===
|
||||
//Simplification routine for setting up a process
|
||||
DProcess* Dispatcher:: createProcess(QString ID, QStringList cmds){
|
||||
DProcess* P = new DProcess(this);
|
||||
P->cmds = cmds;
|
||||
P->ID = ID;
|
||||
connect(P, SIGNAL(ProcFinished(QString)), this, SLOT(ProcFinished(QString)) );
|
||||
return P;
|
||||
}
|
||||
|
||||
// === PRIVATE SLOTS ===
|
||||
void Dispatcher::ProcFinished(QString ID){
|
||||
//Find the process with this ID and close it down (with proper events)
|
||||
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];
|
||||
bool found = false;
|
||||
for(int l=0; l<list.length() && !found; l++){
|
||||
if(list[l].ID==ID){
|
||||
|
||||
found = true;
|
||||
}
|
||||
} //end loop over queue list
|
||||
}
|
||||
}//end loop over queue enumeration
|
||||
CheckQueues();
|
||||
}
|
||||
|
||||
void Dispatcher::CheckQueues(){
|
||||
|
||||
}
|
||||
88
src/server/Dispatcher.h
Normal file
88
src/server/Dispatcher.h
Normal file
@@ -0,0 +1,88 @@
|
||||
// ===============================
|
||||
// PC-BSD REST API Server
|
||||
// Available under the 3-clause BSD License
|
||||
// Written by: Ken Moore <ken@pcbsd.org> 2015-2016
|
||||
// =================================
|
||||
#ifndef _PCBSD_SYSADM_DISPATCH_PROCESS_SYSTEM_H
|
||||
#define _PCBSD_SYSADM_DISPATCH_PROCESS_SYSTEM_H
|
||||
|
||||
#include "globals-qt.h"
|
||||
|
||||
|
||||
// == Simple Process class for running sequential commands ==
|
||||
// == INTERNAL ONLY - Do not use directly ==
|
||||
class DProcess : public QProcess{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DProcess(QObject parent = 0);
|
||||
~DProcess();
|
||||
|
||||
QString ID;
|
||||
QStringList cmds;
|
||||
bool success;
|
||||
|
||||
void startProc();
|
||||
|
||||
//Get the current process log (can be run during/after the process runs)
|
||||
QString getProcLog();
|
||||
|
||||
bool isRunning();
|
||||
|
||||
private:
|
||||
QString proclog;
|
||||
|
||||
private slots:
|
||||
void cmdFinished(int, QProcess::ExitStatus);
|
||||
|
||||
signals:
|
||||
void ProcFinished(QString ID);
|
||||
};
|
||||
|
||||
|
||||
class Dispatcher : public QObject{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum PROC_QUEUE { NO_QUEUE = 0, PKG_QUEUE, IOCAGE_QUEUE };
|
||||
#define enum_length 3 //This needs to be the number of items in the enum above
|
||||
|
||||
Dispatcher();
|
||||
~Dispatcher();
|
||||
|
||||
public slots:
|
||||
//Main start/stop
|
||||
void start(QString queuefile); //load any previously-unrun processes
|
||||
void stop(); //save any currently-unrun processes for next time
|
||||
|
||||
//Main Calling Functions (single command, or multiple in-order commands)
|
||||
void queueProcess(QString ID, QString cmd); //uses NO_QUEUE
|
||||
void queueProcess(QString ID, QStringList cmds); //uses NO_QUEUE
|
||||
void queueProcess(Dispatcher::PROC_QUEUE, QString ID, QString cmd);
|
||||
void queueProcess(Dispatcher::PROC_QUEUE, QString ID, QStringList cmds);
|
||||
|
||||
private:
|
||||
// Queue file
|
||||
QString queue_file;
|
||||
|
||||
//Internal lists
|
||||
QHash<PROC_QUEUE, QList<DProcess*> > QUEUES;
|
||||
|
||||
//Simplification routine for setting up a process
|
||||
DProcess* createProcess(QString ID, QStringList cmds){
|
||||
DProcess* P = new DProcess(this);
|
||||
P->cmds = cmds;
|
||||
P->ID = ID;
|
||||
connect(P, SIGNAL(ProcFinished(QString)), this, SLOT(ProcFinished(QString)) );
|
||||
return P;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ProcFinished(QString ID);
|
||||
void CheckQueues();
|
||||
|
||||
signals:
|
||||
void DispatchFinished(QString ID, bool success);
|
||||
void DispatchStarting(QString ID);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <QDateTime>
|
||||
#include <QTextStream>
|
||||
#include <QProcess>
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
#include <QSslKey>
|
||||
#include <QSslCertificate>
|
||||
#include <QSslError>
|
||||
@@ -46,10 +48,14 @@
|
||||
#include <QDebug>
|
||||
#include <QtDebug>
|
||||
|
||||
// SSL Version/File defines
|
||||
#define SSLVERSION QSsl::TlsV1_0
|
||||
#define SSLCERTFILE "/usr/local/etc/sysadm/restserver.crt"
|
||||
#define SSLKEYFILE "/usr/local/etc/sysadm/restserver.key"
|
||||
|
||||
// Server Settings defines
|
||||
#define DISPATCH_QUEUE "/usr/local/etc/sysadm/dispatch_queue"
|
||||
|
||||
inline QString DisplayPriority(int pri){
|
||||
//ensure bounds
|
||||
if(pri<0){ pri = 0; }
|
||||
|
||||
Reference in New Issue
Block a user