Merge branch 'master' of github.com:pcbsd/sysadm

This commit is contained in:
Ken Moore
2016-02-01 11:21:04 -05:00
13 changed files with 722 additions and 45 deletions

View File

@@ -20,12 +20,290 @@ Every iocage class request contains the following parameters:
| namespace | sysadm | |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| action | | supported actions include "listjails" |
| action | | supported actions include "getdefaultsettings", "listjails", "getjailsettings" |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
The rest of this section provides examples of the available *actions* for each type of request, along with their responses.
.. index:: getdefaultsettings, iocage
.. _Default Settings:
Default Settings
================
The "getdefaultsettings" action lists all of the global settings that apply to all jails.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "getdefaultsettings"
}
**REST Response**
.. code-block:: json
{
"args": {
"getdefaultsettings": {
"defaults": {
"allow_chflags": "0",
"allow_mount": "0",
"allow_mount_devfs": "0",
"allow_mount_nullfs": "0",
"allow_mount_procfs": "0",
"allow_mount_tmpfs": "0",
"allow_mount_zfs": "0",
"allow_quotas": "0",
"allow_raw_sockets": "0",
"allow_set_hostname": "1",
"allow_socket_af": "0",
"allow_sysvipc": "0",
"available": "426G",
"boot": "off",
"bpf": "off",
"children_max": "0",
"compression": "lz4",
"compressratio": "1.00x",
"coredumpsize": "off",
"count": "1",
"cpuset": "off",
"cputime": "off",
"datasize": "off",
"dedup": "off",
"defaultrouter": "none",
"defaultrouter6": "none",
"devfs_ruleset": "4",
"dhcp": "off",
"enforce_statfs": "2",
"exec_clean": "1",
"exec_fib": "0",
"exec_jail_user": "root",
"exec_poststart": "/usr/bin/true",
"exec_poststop": "/usr/bin/true",
"exec_prestart": "/usr/bin/true",
"exec_prestop": "/usr/bin/true",
"exec_start": "/bin/sh /etc/rc",
"exec_stop": "/bin/sh /etc/rc.shutdown",
"exec_system_jail_user": "0",
"exec_system_user": "root",
"exec_timeout": "60",
"ftpfiles": "base.txz doc.txz lib32.txz src.txz",
"ftphost": "ftp.freebsd.org",
"gitlocation": "https://github.com",
"hack88": "0",
"host_domainname": "none",
"host_hostname": "442a5843-c6bd-11e5-bbe9-fcaa14deb15d",
"host_hostuuid": "442a5843-c6bd-11e5-bbe9-fcaa14deb15d",
"hostid": "4145fbb8-c5b6-11e5-9f2f-fcaa14deb15d",
"interfaces": "vnet0:bridge0,vnet1:bridge1",
"ip4": "new",
"ip4_addr": "none",
"ip4_autoend": "none",
"ip4_autostart": "none",
"ip4_autosubnet": "none",
"ip4_saddrsel": "1",
"ip6": "new",
"ip6_addr": "none",
"ip6_saddrsel": "1",
"istemplate": "no",
"jail_zfs": "off",
"jail_zfs_dataset": "iocage/jails/442a5843-c6bd-11e5-bbe9-fcaa14deb15d/data",
"jail_zfs_mountpoint": "none",
"last_started": "none",
"login_flags": "-f root",
"maxproc": "off",
"memorylocked": "off",
"memoryuse": "8G:log",
"mount_devfs": "1",
"mount_fdescfs": "1",
"mount_linprocfs": "0",
"mount_procfs": "0",
"mountpoint": "/iocage/.defaults",
"msgqqueued": "off",
"msgqsize": "off",
"nmsgq": "off",
"notes": "none",
"nsemop": "off",
"nshm": "off",
"nthr": "off",
"openfiles": "off",
"origin": "-",
"owner": "root",
"pcpu": "off",
"pkglist": "none",
"priority": "99",
"pseudoterminals": "off",
"quota": "none",
"release": "11.0-CURRENTJAN2016",
"reservation": "none",
"resolver": "none",
"rlimits": "off",
"securelevel": "2",
"shmsize": "off",
"stacksize": "off",
"stop_timeout": "30",
"swapuse": "off",
"sync_target": "none",
"sync_tgt_zpool": "none",
"tag": "2016-01-29@14:19:49",
"type": "basejail",
"used": "96K",
"vmemoryuse": "off",
"vnet": "off",
"vnet0_mac": "none",
"vnet1_mac": "none",
"vnet2_mac": "none",
"vnet3_mac": "none",
"wallclock": "off"
}
}
}
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"action" : "getdefaultsettings"
},
"id" : "fooid",
"name" : "iocage",
"namespace" : "sysadm"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"getdefaultsettings": {
"defaults": {
"allow_chflags": "0",
"allow_mount": "0",
"allow_mount_devfs": "0",
"allow_mount_nullfs": "0",
"allow_mount_procfs": "0",
"allow_mount_tmpfs": "0",
"allow_mount_zfs": "0",
"allow_quotas": "0",
"allow_raw_sockets": "0",
"allow_set_hostname": "1",
"allow_socket_af": "0",
"allow_sysvipc": "0",
"available": "426G",
"boot": "off",
"bpf": "off",
"children_max": "0",
"compression": "lz4",
"compressratio": "1.00x",
"coredumpsize": "off",
"count": "1",
"cpuset": "off",
"cputime": "off",
"datasize": "off",
"dedup": "off",
"defaultrouter": "none",
"defaultrouter6": "none",
"devfs_ruleset": "4",
"dhcp": "off",
"enforce_statfs": "2",
"exec_clean": "1",
"exec_fib": "0",
"exec_jail_user": "root",
"exec_poststart": "/usr/bin/true",
"exec_poststop": "/usr/bin/true",
"exec_prestart": "/usr/bin/true",
"exec_prestop": "/usr/bin/true",
"exec_start": "/bin/sh /etc/rc",
"exec_stop": "/bin/sh /etc/rc.shutdown",
"exec_system_jail_user": "0",
"exec_system_user": "root",
"exec_timeout": "60",
"ftpfiles": "base.txz doc.txz lib32.txz src.txz",
"ftphost": "ftp.freebsd.org",
"gitlocation": "https://github.com",
"hack88": "0",
"host_domainname": "none",
"host_hostname": "442a5843-c6bd-11e5-bbe9-fcaa14deb15d",
"host_hostuuid": "442a5843-c6bd-11e5-bbe9-fcaa14deb15d",
"hostid": "4145fbb8-c5b6-11e5-9f2f-fcaa14deb15d",
"interfaces": "vnet0:bridge0,vnet1:bridge1",
"ip4": "new",
"ip4_addr": "none",
"ip4_autoend": "none",
"ip4_autostart": "none",
"ip4_autosubnet": "none",
"ip4_saddrsel": "1",
"ip6": "new",
"ip6_addr": "none",
"ip6_saddrsel": "1",
"istemplate": "no",
"jail_zfs": "off",
"jail_zfs_dataset": "iocage/jails/442a5843-c6bd-11e5-bbe9-fcaa14deb15d/data",
"jail_zfs_mountpoint": "none",
"last_started": "none",
"login_flags": "-f root",
"maxproc": "off",
"memorylocked": "off",
"memoryuse": "8G:log",
"mount_devfs": "1",
"mount_fdescfs": "1",
"mount_linprocfs": "0",
"mount_procfs": "0",
"mountpoint": "/iocage/.defaults",
"msgqqueued": "off",
"msgqsize": "off",
"nmsgq": "off",
"notes": "none",
"nsemop": "off",
"nshm": "off",
"nthr": "off",
"openfiles": "off",
"origin": "-",
"owner": "root",
"pcpu": "off",
"pkglist": "none",
"priority": "99",
"pseudoterminals": "off",
"quota": "none",
"release": "11.0-CURRENTJAN2016",
"reservation": "none",
"resolver": "none",
"rlimits": "off",
"securelevel": "2",
"shmsize": "off",
"stacksize": "off",
"stop_timeout": "30",
"swapuse": "off",
"sync_target": "none",
"sync_tgt_zpool": "none",
"tag": "2016-01-29@14:19:49",
"type": "basejail",
"used": "96K",
"vmemoryuse": "off",
"vnet": "off",
"vnet0_mac": "none",
"vnet1_mac": "none",
"vnet2_mac": "none",
"vnet3_mac": "none",
"wallclock": "off"
}
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: listjails, iocage
.. _List Jails:
@@ -96,3 +374,278 @@ system boot, the jail ID (only applies to running jails), whether or not the jai
"name": "response",
"namespace": "sysadm"
}
.. index:: getjailsettings, iocage
.. _Jail Settings:
Jail Settings
=============
The "getjailsettings" action lists all of the settings that apply to the specified jail. This is equivalent to running :command:`iocage get all <jail>`.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"jail" : "testjail",
"action" : "getjailsettings"
}
**REST Response**
.. code-block:: json
{
"args": {
"getjailsettings": {
"testjail": {
"allow_chflags": "0",
"allow_mount": "0",
"allow_mount_devfs": "0",
"allow_mount_nullfs": "0",
"allow_mount_procfs": "0",
"allow_mount_tmpfs": "0",
"allow_mount_zfs": "0",
"allow_quotas": "0",
"allow_raw_sockets": "0",
"allow_set_hostname": "1",
"allow_socket_af": "0",
"allow_sysvipc": "0",
"boot": "off",
"bpf": "off",
"branch": "-",
"children_max": "0",
"coredumpsize": "off",
"count": "1",
"cpuset": "off",
"cputime": "off",
"datasize": "off",
"defaultrouter": "none",
"defaultrouter6": "none",
"devfs_ruleset": "4",
"dhcp": "off",
"enforce_statfs": "2",
"exec_clean": "1",
"exec_fib": "0",
"exec_jail_user": "root",
"exec_poststart": "/usr/bin/true",
"exec_poststop": "/usr/bin/true",
"exec_prestart": "/usr/bin/true",
"exec_prestop": "/usr/bin/true",
"exec_start": "/bin/sh /etc/rc",
"exec_stop": "/bin/sh /etc/rc.shutdown",
"exec_system_jail_user": "0",
"exec_system_user": "root",
"exec_timeout": "60",
"ftpdir": "-",
"ftpfiles": "-",
"ftphost": "-",
"ftplocaldir": "-",
"gitlocation": "https",
"hack88": "0",
"host_domainname": "none",
"host_hostname": "4bb3f929-c6bf-11e5-bbe9-fcaa14deb15d",
"host_hostuuid": "4bb3f929-c6bf-11e5-bbe9-fcaa14deb15d",
"hostid": "4145fbb8-c5b6-11e5-9f2f-fcaa14deb15d",
"interfaces": "vnet0",
"ip4": "new",
"ip4_addr": "none",
"ip4_autoend": "none",
"ip4_autostart": "none",
"ip4_autosubnet": "none",
"ip4_saddrsel": "1",
"ip6": "new",
"ip6_addr": "none",
"ip6_saddrsel": "1",
"istemplate": "no",
"jail_zfs": "off",
"jail_zfs_dataset": "iocage/jails/4ba5d76b-c6bf-11e5-bbe9-fcaa14deb15d/data",
"jail_zfs_mountpoint": "none",
"last_started": "none",
"login_flags": "-f root",
"maxproc": "off",
"memorylocked": "off",
"memoryuse": "8G",
"mount_devfs": "1",
"mount_fdescfs": "1",
"mount_linprocfs": "0",
"mount_procfs": "0",
"msgqqueued": "off",
"msgqsize": "off",
"nmsgq": "off",
"notes": "none",
"nsemop": "off",
"nshm": "off",
"nthr": "off",
"openfiles": "off",
"owner": "root",
"pcpu": "off",
"pkglist": "none",
"priority": "99",
"pseudoterminals": "off",
"release": "10.2-RELEASE",
"resolver": "none",
"rlimits": "off",
"securelevel": "2",
"shmsize": "off",
"stacksize": "off",
"start": "-",
"stop_timeout": "30",
"swapuse": "off",
"sync_stat": "-",
"sync_target": "none",
"sync_tgt_zpool": "none",
"tag": "testjail",
"template": "-",
"type": "basejail",
"vmemoryuse": "off",
"vnet": "off",
"vnet0_mac": "none",
"vnet1_mac": "none",
"vnet2_mac": "none",
"vnet3_mac": "none",
"wallclock": "off"
}
}
}
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"jail" : "testjail",
"action" : "getjailsettings"
},
"id" : "fooid",
"name" : "iocage",
"namespace" : "sysadm"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"getjailsettings": {
"testjail": {
"allow_chflags": "0",
"allow_mount": "0",
"allow_mount_devfs": "0",
"allow_mount_nullfs": "0",
"allow_mount_procfs": "0",
"allow_mount_tmpfs": "0",
"allow_mount_zfs": "0",
"allow_quotas": "0",
"allow_raw_sockets": "0",
"allow_set_hostname": "1",
"allow_socket_af": "0",
"allow_sysvipc": "0",
"boot": "off",
"bpf": "off",
"branch": "-",
"children_max": "0",
"coredumpsize": "off",
"count": "1",
"cpuset": "off",
"cputime": "off",
"datasize": "off",
"defaultrouter": "none",
"defaultrouter6": "none",
"devfs_ruleset": "4",
"dhcp": "off",
"enforce_statfs": "2",
"exec_clean": "1",
"exec_fib": "0",
"exec_jail_user": "root",
"exec_poststart": "/usr/bin/true",
"exec_poststop": "/usr/bin/true",
"exec_prestart": "/usr/bin/true",
"exec_prestop": "/usr/bin/true",
"exec_start": "/bin/sh /etc/rc",
"exec_stop": "/bin/sh /etc/rc.shutdown",
"exec_system_jail_user": "0",
"exec_system_user": "root",
"exec_timeout": "60",
"ftpdir": "-",
"ftpfiles": "-",
"ftphost": "-",
"ftplocaldir": "-",
"gitlocation": "https",
"hack88": "0",
"host_domainname": "none",
"host_hostname": "4bb3f929-c6bf-11e5-bbe9-fcaa14deb15d",
"host_hostuuid": "4bb3f929-c6bf-11e5-bbe9-fcaa14deb15d",
"hostid": "4145fbb8-c5b6-11e5-9f2f-fcaa14deb15d",
"interfaces": "vnet0",
"ip4": "new",
"ip4_addr": "none",
"ip4_autoend": "none",
"ip4_autostart": "none",
"ip4_autosubnet": "none",
"ip4_saddrsel": "1",
"ip6": "new",
"ip6_addr": "none",
"ip6_saddrsel": "1",
"istemplate": "no",
"jail_zfs": "off",
"jail_zfs_dataset": "iocage/jails/4ba5d76b-c6bf-11e5-bbe9-fcaa14deb15d/data",
"jail_zfs_mountpoint": "none",
"last_started": "none",
"login_flags": "-f root",
"maxproc": "off",
"memorylocked": "off",
"memoryuse": "8G",
"mount_devfs": "1",
"mount_fdescfs": "1",
"mount_linprocfs": "0",
"mount_procfs": "0",
"msgqqueued": "off",
"msgqsize": "off",
"nmsgq": "off",
"notes": "none",
"nsemop": "off",
"nshm": "off",
"nthr": "off",
"openfiles": "off",
"owner": "root",
"pcpu": "off",
"pkglist": "none",
"priority": "99",
"pseudoterminals": "off",
"release": "10.2-RELEASE",
"resolver": "none",
"rlimits": "off",
"securelevel": "2",
"shmsize": "off",
"stacksize": "off",
"start": "-",
"stop_timeout": "30",
"swapuse": "off",
"sync_stat": "-",
"sync_target": "none",
"sync_tgt_zpool": "none",
"tag": "testjail",
"template": "-",
"type": "basejail",
"vmemoryuse": "off",
"vnet": "off",
"vnet0_mac": "none",
"vnet1_mac": "none",
"vnet2_mac": "none",
"vnet3_mac": "none",
"wallclock": "off"
}
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}

View File

@@ -11,6 +11,64 @@
using namespace sysadm;
//PLEASE: Keep the functions in the same order as listed in pcbsd-general.h
// Return all the default iocage settings
QJsonObject Iocage::getDefaultSettings() {
QJsonObject retObject;
QStringList output = General::RunCommand("iocage defaults").split("\n");
QJsonObject vals;
for ( int i = 0; i < output.size(); i++)
{
if ( output.at(i).indexOf("JID") != -1 )
continue;
if ( output.at(i).isEmpty() )
break;
QString key = output.at(i).simplified().section("=", 0, 0);
QString value = output.at(i).simplified().section("=", 1, 1);
vals.insert(key, value);
}
retObject.insert("defaults", vals);
return retObject;
}
// List the jails on the box
QJsonObject Iocage::getJailSettings(QJsonObject jsin) {
QJsonObject retObject;
QStringList keys = jsin.keys();
if (! keys.contains("jail") ) {
retObject.insert("error", "Missing required keys");
return retObject;
}
// Get the key values
QString jail = jsin.value("jail").toString();
QStringList output = General::RunCommand("iocage get all " + jail).split("\n");
QJsonObject vals;
for ( int i = 0; i < output.size(); i++)
{
if ( output.at(i).indexOf("JID") != -1 )
continue;
if ( output.at(i).isEmpty() )
break;
QString key = output.at(i).simplified().section(":", 0, 0);
QString value = output.at(i).simplified().section(":", 1, 1);
vals.insert(key, value);
}
retObject.insert(jail, vals);
return retObject;
}
// List the jails on the box
QJsonObject Iocage::listJails() {

View File

@@ -14,6 +14,8 @@ namespace sysadm{
class Iocage{
public:
static QJsonObject getDefaultSettings();
static QJsonObject getJailSettings(QJsonObject);
static QJsonObject listJails();
};

View File

@@ -20,7 +20,7 @@ DProcess::DProcess(QObject *parent) : QProcess(parent){
}
DProcess::~DProcess(){
if(this->state()!=QProcess::NotRunning)){
if( this->state()!=QProcess::NotRunning ){
this->terminate();
}
}
@@ -30,11 +30,14 @@ void DProcess::startProc(){
finished = QDateTime::currentDateTime();
emit ProcFinished(ID);
return;
}else if(proclog.isEmpty()){
started = QDateTime::currentDateTime(); //first cmd started
rawcmds = cmds;
}else{
proclog.append("\n");
}
QString cmd = cmds.takeFirst();
success = false; //not finished yet
if(!proclog.isEmpty()){ proclog.append("\n"); }
else{ started = QDateTime::currentDateTime(); } //first cmd started
proclog.append("[Running Command: "+cmd+" ]");
this->start(cmd);
}
@@ -105,8 +108,10 @@ void Dispatcher::queueProcess(Dispatcher::PROC_QUEUE queue, QString ID, QStringL
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(); }
if(queue==NO_QUEUE || HASH[queue].length()==1){
emit DispatchStarting(P->ID);
P->startProc(); //go ahead and start it now
}else{ CheckQueues(); }
}
// === PRIVATE ===
@@ -115,6 +120,7 @@ DProcess* Dispatcher:: createProcess(QString ID, QStringList cmds){
DProcess* P = new DProcess(this);
P->cmds = cmds;
P->ID = ID;
P->success = false;
connect(P, SIGNAL(ProcFinished(QString)), this, SLOT(ProcFinished(QString)) );
return P;
}
@@ -122,22 +128,23 @@ DProcess* Dispatcher:: createProcess(QString ID, QStringList cmds){
// === 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);
bool found = false;
for(int i=0; i<enum_length && !found; i++){
Dispatcher::PROC_QUEUE queue = static_cast<Dispatcher::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){
if(list[l]->ID==ID){
QJsonObject obj;
obj.insert("log",list[l].procLog());
obj.insert("success", list[l].success ? "true" : "false" );
obj.insert("log",list[l]->getProcLog());
obj.insert("success", list[l]->success ? "true" : "false" );
obj.insert("proc_id", ID);
obj.insert("cmd_list", QJsonArray::fromStringList( list[l].rawcmds );
obj.insert("time_started", list[l].started.toString(QT::ISODate) );
obj.insert("time_finished", list[l].finished.toString(QT::ISODate) );
obj.insert("cmd_list", QJsonArray::fromStringList( list[l]->rawcmds ) );
obj.insert("time_started", list[l]->started.toString(Qt::ISODate) );
obj.insert("time_finished", list[l]->finished.toString(Qt::ISODate) );
emit DispatchFinished(ID, list[l]->success);
delete list.takeAt(l);
LogManager::log(LogManager::EV_DISPATCH, obj);
LogManager::log(LogManager::DISPATCH, obj);
found = true;
}
} //end loop over queue list
@@ -147,5 +154,19 @@ void Dispatcher::ProcFinished(QString ID){
}
void Dispatcher::CheckQueues(){
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(j>0 && queue!=NO_QUEUE){ break; } //done with this - only first item in these queues should run at a time
if(!list[j]->isRunning() && list[j]->getProcLog().isEmpty()){
//Need to start this one - has not run yet
emit DispatchStarting(list[j]->ID);
list[j]->startProc();
}
} //end loop over list
}
} //end loop over queue types
}

View File

@@ -14,7 +14,7 @@
class DProcess : public QProcess{
Q_OBJECT
public:
DProcess(QObject parent = 0);
DProcess(QObject *parent = 0);
~DProcess();
QString ID;
@@ -68,16 +68,10 @@ private:
QString queue_file;
//Internal lists
QHash<PROC_QUEUE, QList<DProcess*> > QUEUES;
QHash<PROC_QUEUE, QList<DProcess*> > HASH;
//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;
}
DProcess* createProcess(QString ID, QStringList cmds);
private slots:
void ProcFinished(QString ID);

View File

@@ -5,6 +5,8 @@
// =================================
#include "EventWatcher.h"
#include "globals.h"
// === PUBLIC ===
EventWatcher::EventWatcher(){
starting = true;
@@ -24,9 +26,9 @@ EventWatcher::~EventWatcher(){
void EventWatcher::start(){
// - DISPATCH Events
starting = true;
if(!QFile::exists(DISPATCHWORKING)){ QProcess::execute("touch "+DISPATCHWORKING); }
//if(!QFile::exists(DISPATCHWORKING)){ QProcess::execute("touch "+DISPATCHWORKING); }
//qDebug() << " Dispatcher Events:" << DISPATCHWORKING;
WatcherUpdate(DISPATCHWORKING); //load it initially (will also add it to the watcher)
//WatcherUpdate(DISPATCHWORKING); //load it initially (will also add it to the watcher)
// - Life Preserver Events
WatcherUpdate(LPLOG); //load it initially (will also add it to the watcher);
WatcherUpdate(LPERRLOG); //load it initially (will also add it to the watcher);
@@ -86,10 +88,29 @@ double EventWatcher::displayToDoubleK(QString displayNumber){
return num;
}
// === PUBLIC SLOTS ===
//Slots for the global Dispatcher to connect to
void EventWatcher::DispatchStarting(QString ID){
QJsonObject obj;
obj.insert("process_id", ID);
obj.insert("state", "running");
LogManager::log(LogManager::EV_DISPATCH, obj);
emit NewEvent(DISPATCHER, obj);
}
void EventWatcher::DispatchFinished(QString ID, bool success){
QJsonObject obj;
obj.insert("process_id", ID);
obj.insert("state", "finished");
obj.insert("result", success ? "success" : "failure");
LogManager::log(LogManager::EV_DISPATCH, obj);
emit NewEvent(DISPATCHER, obj);
}
// === PRIVATE SLOTS ===
void EventWatcher::WatcherUpdate(const QString &path){
if(!starting){ qDebug() << "Event Watcher Update:" << path; }
if(path==DISPATCHWORKING){
/*if(path==DISPATCHWORKING){
//Read the file contents
QString stat = readFile(DISPATCHWORKING);
if(stat.simplified().isEmpty()){ stat = "idle"; }
@@ -97,7 +118,8 @@ void EventWatcher::WatcherUpdate(const QString &path){
HASH.insert(DISPATCHER,stat); //save for later
//Forward those contents on to the currently-open sockets
emit NewEvent(DISPATCHER, QJsonValue(stat) );
}else if(path==LPLOG){
}else*/
if(path==LPLOG){
//Main Life Preserver Log File
ReadLPLogFile();
}else if(path==LPERRLOG){
@@ -121,7 +143,7 @@ void EventWatcher::CheckLogFiles(){
if(!watched.contains(LPLOG) && QFile::exists(LPLOG)){ watcher->addPath(LPLOG); }
if(!watched.contains(LPERRLOG) && QFile::exists(LPERRLOG)){ watcher->addPath(LPERRLOG); }
if(!watched.contains(tmpLPRepFile) && QFile::exists(tmpLPRepFile)){ watcher->addPath(tmpLPRepFile); }
if(!watched.contains(DISPATCHWORKING) && QFile::exists(LPLOG)){ watcher->addPath(DISPATCHWORKING); }
//if(!watched.contains(DISPATCHWORKING) && QFile::exists(LPLOG)){ watcher->addPath(DISPATCHWORKING); }
//qDebug() << "watched:" << watcher->files() << watcher->directories();
}

View File

@@ -8,7 +8,7 @@
#include "globals-qt.h"
#define DISPATCHWORKING QString("/var/tmp/appcafe/dispatch-queue.working")
//#define DISPATCHWORKING QString("/var/tmp/appcafe/dispatch-queue.working")
#define LPLOG QString("/var/log/lpreserver/lpreserver.log")
#define LPERRLOG QString("/var/log/lpreserver/error.log")
#define LPREPLOGDIR QString("/var/log/lpreserver/")
@@ -49,6 +49,10 @@ private:
public slots:
void start();
//Slots for the global Dispatcher to connect to
void DispatchStarting(QString);
void DispatchFinished(QString, bool);
private slots:
//File watcher signals
void WatcherUpdate(const QString&);

View File

@@ -15,7 +15,7 @@
//===========================================
// Event Files (EV_*): JSON input/output (full event)
// HOST: String input/output (simple messages)
//
// DISPATCH: Full log of dispatcher processes
//===========================================
#define LOGDIR QString("/var/log/sysadm")
@@ -24,11 +24,12 @@ class LogManager{
public:
//Enumeration of common log files (will automatically use proper file)
// === ADD NEW FILE SUPPORT HERE ===
enum LOG_FILE {HOST, EV_DISPATCH, EV_LP};
enum LOG_FILE {HOST, DISPATCH, EV_DISPATCH, EV_LP};
//Conversion function for flag->path
static QString flagToPath(LogManager::LOG_FILE flag){
QString filepath;
if(flag==HOST){ filepath.append("hostinfo"); }
else if(flag==DISPATCH){ filepath.append("dispatcher"); }
else if(flag==EV_DISPATCH){ filepath.append("events-dispatcher"); }
else if(flag==EV_LP){ filepath.append("events-lifepreserver"); }
else{ return ""; } //invalid file given

View File

@@ -34,6 +34,7 @@ RestOutputStruct::ExitCode WebSocket::AvailableSubsystems(bool allaccess, QJsonO
if(QFile::exists("/var/run/syscache.pipe")){
out->insert("rpc/syscache","read"); //no write to syscache - only reads
}
// - dispatcher (Internal to server - always available)
//"read" is the event notifications, "write" is the ability to queue up jobs
out->insert("rpc/dispatcher", allaccess ? "read/write" : "read");
@@ -150,7 +151,7 @@ RestOutputStruct::ExitCode WebSocket::EvaluateDispatcherRequest(const QJsonValue
}else{ return RestOutputStruct::BADREQUEST; }
//Run the Request (should be one value for each in_req)
QStringList values = DispatcherClient::parseInputs(in_req, AUTHSYSTEM);;
QStringList values = DispatcherClient::parseInputs(in_req, AUTHSYSTEM);
while(values.length() < in_req.length()){ values << "[ERROR]"; } //ensure lists are same length
//Format the result
@@ -350,6 +351,14 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmIocageRequest(const QJsonVal
bool ok = false;
if(keys.contains("action")){
QString act = JsonValueToString(in_args.toObject().value("action"));
if(act=="getdefaultsettings"){
ok = true;
out->insert("getdefaultsettings", sysadm::Iocage::getDefaultSettings());
}
if(act=="getjailsettings"){
ok = true;
out->insert("getjailsettings", sysadm::Iocage::getJailSettings(in_args.toObject()));
}
if(act=="listjails"){
ok = true;
out->insert("listjails", sysadm::Iocage::listJails());

View File

@@ -8,15 +8,15 @@
#include "globals-qt.h"
#include "LogManager.h"
//Global variables/classes (intially created in main.cpp)
extern QSettings *CONFIG;
#include "EventWatcher.h"
extern EventWatcher *EVENTS;
//#include "ProcessQueue.h"
//extern ProcessQueue *PQUEUE;
//#include "LogManager.h"
//extern LogManager *LOGS;
#include "Dispatcher.h"
extern Dispatcher *DISPATCHER;
//Special defines
#define WSPORTNUMBER 12150 // WebSocket server default port

View File

@@ -15,6 +15,7 @@
//Create any global classes
QSettings *CONFIG = new QSettings("PCBSD","sysadm");
EventWatcher *EVENTS = new EventWatcher();
Dispatcher *DISPATCHER = new Dispatcher();
//Create the default logfile
QFile logfile;
@@ -76,6 +77,10 @@ int main( int argc, char ** argv )
logfile.open(QIODevice::WriteOnly | QIODevice::Append);
qInstallMessageHandler(MessageOutput);
//Connect the background classes
QObject::connect(DISPATCHER, SIGNAL(DispatchFinished(QString, bool)), EVENTS, SLOT(DispatchFinished(QString,bool)) );
QObject::connect(DISPATCHER, SIGNAL(DispatchStarting(QString)), EVENTS, SLOT(DispatchStarting(QString)) );
//Create the daemon
qDebug() << "Starting the PC-BSD sysadm server...." << (websocket ? "(WebSocket)" : "(TCP)");
WebServer *w = new WebServer();

View File

@@ -13,7 +13,8 @@ HEADERS += globals.h globals-qt.h \
AuthorizationManager.h \
SslServer.h \
EventWatcher.h \
LogManager.h
LogManager.h \
Dispatcher.h
SOURCES += main.cpp \
WebServer.cpp \
@@ -23,7 +24,8 @@ SOURCES += main.cpp \
dispatcher-client.cpp \
AuthorizationManager.cpp \
EventWatcher.cpp \
LogManager.cpp
LogManager.cpp \
Dispatcher.cpp
TARGET=sysadm-server

View File

@@ -7,14 +7,20 @@ JSAWK="./utils/jsawk -j js24"
which npm >/dev/null 2>/dev/null
if [ $? -ne 0 ] ; then
echo "Please install npm first"
exit 1
pkg install -y npm
if [ $? -ne 0 ] ; then
echo "Requires npm!"
exit 1
fi
fi
pkg info p5-JSON >/dev/null 2>/dev/null
if [ $? -ne 0 ] ; then
echo "Please install p5-JSON first"
exit 1
pkg install -y p5-JSON
if [ $? -ne 0 ] ; then
echo "Requires p5-JSON!"
exit 1
fi
fi
if [ ! -d "${HOME}/.npm/ws" ] ; then