From 188f20ff165ed4cbdb349c1a50b788192a0ee076 Mon Sep 17 00:00:00 2001 From: Kris Moore Date: Fri, 29 Jan 2016 14:45:37 -0500 Subject: [PATCH 1/5] Add new 'getjailsettings' API call which returns all the 'iocage get all ' properties in json REST Request: ------------------------------- PUT /sysadm/iocage { "jail" : "testjail", "action" : "getjailsettings" } REST Response: ------------------------------- { "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: ------------------------------- { "args" : { "jail" : "testjail", "action" : "getjailsettings" }, "id" : "fooid", "name" : "iocage", "namespace" : "sysadm" } WebSocket Response: ------------------------------- { "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" } --- src/library/sysadm-iocage.cpp | 34 ++++++++++++++++++++++++++++++++++ src/library/sysadm-iocage.h | 1 + src/server/WebBackend.cpp | 4 ++++ tests/api-test.sh | 14 ++++++++++---- 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/library/sysadm-iocage.cpp b/src/library/sysadm-iocage.cpp index 3652059..5c6a35d 100644 --- a/src/library/sysadm-iocage.cpp +++ b/src/library/sysadm-iocage.cpp @@ -12,6 +12,40 @@ using namespace sysadm; //PLEASE: Keep the functions in the same order as listed in pcbsd-general.h +// 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() { QJsonObject retObject; diff --git a/src/library/sysadm-iocage.h b/src/library/sysadm-iocage.h index d9f191e..d23a444 100644 --- a/src/library/sysadm-iocage.h +++ b/src/library/sysadm-iocage.h @@ -14,6 +14,7 @@ namespace sysadm{ class Iocage{ public: + static QJsonObject getJailSettings(QJsonObject); static QJsonObject listJails(); }; diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index 352c67c..26d331b 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -343,6 +343,10 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmIocageRequest(const QJsonVal bool ok = false; if(keys.contains("action")){ QString act = JsonValueToString(in_args.toObject().value("action")); + 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()); diff --git a/tests/api-test.sh b/tests/api-test.sh index 2321f04..00f947b 100755 --- a/tests/api-test.sh +++ b/tests/api-test.sh @@ -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 From 5a53aacf9f43a4e20108810c31cc5f6ddddc32d9 Mon Sep 17 00:00:00 2001 From: Kris Moore Date: Fri, 29 Jan 2016 15:37:43 -0500 Subject: [PATCH 2/5] Add new API call to get all iocage default settings REST Request: ------------------------------- PUT /sysadm/iocage { "action" : "getdefaultsettings" } REST Response: ------------------------------- { "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: ------------------------------- { "args" : { "action" : "getdefaultsettings" }, "id" : "fooid", "name" : "iocage", "namespace" : "sysadm" } WebSocket Response: ------------------------------- { "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" } --- src/library/sysadm-iocage.cpp | 24 ++++++++++++++++++++++++ src/library/sysadm-iocage.h | 1 + src/server/WebBackend.cpp | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/src/library/sysadm-iocage.cpp b/src/library/sysadm-iocage.cpp index 5c6a35d..393282b 100644 --- a/src/library/sysadm-iocage.cpp +++ b/src/library/sysadm-iocage.cpp @@ -11,6 +11,30 @@ 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) { diff --git a/src/library/sysadm-iocage.h b/src/library/sysadm-iocage.h index d23a444..3a1f9f7 100644 --- a/src/library/sysadm-iocage.h +++ b/src/library/sysadm-iocage.h @@ -14,6 +14,7 @@ namespace sysadm{ class Iocage{ public: + static QJsonObject getDefaultSettings(); static QJsonObject getJailSettings(QJsonObject); static QJsonObject listJails(); }; diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index 26d331b..dea1650 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -343,6 +343,10 @@ 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())); From 04c366f1143160e4e0a0beb9036b22abb10ad1a1 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 29 Jan 2016 16:24:40 -0500 Subject: [PATCH 3/5] Finish adding in the new dispatcher system (untested). This should be ready for trying out in some subsystem now. Note: to queue up a job you just need to run one of the DISPATCHER->queue() functions (there are a few overloaded versions for simplicity) --- src/server/Dispatcher.cpp | 53 ++++++++++++++++++++++++++----------- src/server/Dispatcher.h | 12 +++------ src/server/EventWatcher.cpp | 32 ++++++++++++++++++---- src/server/EventWatcher.h | 6 ++++- src/server/LogManager.h | 5 ++-- src/server/WebBackend.cpp | 6 ++--- src/server/globals.h | 8 +++--- src/server/main.cpp | 5 ++++ src/server/server.pro | 6 +++-- 9 files changed, 91 insertions(+), 42 deletions(-) diff --git a/src/server/Dispatcher.cpp b/src/server/Dispatcher.cpp index 411edb9..74f6ff2 100644 --- a/src/server/Dispatcher.cpp +++ b/src/server/Dispatcher.cpp @@ -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 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(i); + bool found = false; + for(int i=0; i(i); if(HASH.contains(queue)){ QList list = HASH[queue]; - bool found = false; for(int l=0; lID==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(i); + if(HASH.contains(queue)){ + QList list = HASH[queue]; + for(int j=0; j0 && 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 } diff --git a/src/server/Dispatcher.h b/src/server/Dispatcher.h index 19d5af1..5a40332 100644 --- a/src/server/Dispatcher.h +++ b/src/server/Dispatcher.h @@ -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 > QUEUES; + QHash > 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); diff --git a/src/server/EventWatcher.cpp b/src/server/EventWatcher.cpp index 6c53046..7b08090 100644 --- a/src/server/EventWatcher.cpp +++ b/src/server/EventWatcher.cpp @@ -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(); } diff --git a/src/server/EventWatcher.h b/src/server/EventWatcher.h index 7f464ab..35e6bed 100644 --- a/src/server/EventWatcher.h +++ b/src/server/EventWatcher.h @@ -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&); diff --git a/src/server/LogManager.h b/src/server/LogManager.h index 7237c59..eee6ac0 100644 --- a/src/server/LogManager.h +++ b/src/server/LogManager.h @@ -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 diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index 26d331b..08559e5 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -35,10 +35,10 @@ RestOutputStruct::ExitCode WebSocket::AvailableSubsystems(bool allaccess, QJsonO out->insert("rpc/syscache","read"); //no write to syscache - only reads } // - dispatcher - if(DispatcherClient::DispatcherAvailable()){ + //if(DispatcherClient::DispatcherAvailable()){ //"read" is the event notifications, "write" is the ability to queue up jobs out->insert("rpc/dispatcher", allaccess ? "read/write" : "read"); - } + //} // - network out->insert("sysadm/network","read/write"); @@ -143,7 +143,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 diff --git a/src/server/globals.h b/src/server/globals.h index ad9ec30..05dd4d7 100644 --- a/src/server/globals.h +++ b/src/server/globals.h @@ -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 diff --git a/src/server/main.cpp b/src/server/main.cpp index a32abaa..5b3deba 100644 --- a/src/server/main.cpp +++ b/src/server/main.cpp @@ -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(); diff --git a/src/server/server.pro b/src/server/server.pro index 81e4a8a..a006f6b 100644 --- a/src/server/server.pro +++ b/src/server/server.pro @@ -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 From e4ca592edcadae89a67c55de8cca020055078be8 Mon Sep 17 00:00:00 2001 From: dlavigne Date: Mon, 1 Feb 2016 09:49:34 -0500 Subject: [PATCH 4/5] Doc getdefaultsettings action. --- api/classes/iocage.rst | 280 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 279 insertions(+), 1 deletion(-) diff --git a/api/classes/iocage.rst b/api/classes/iocage.rst index d1d7d6a..bb56128 100644 --- a/api/classes/iocage.rst +++ b/api/classes/iocage.rst @@ -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" | | | | | +---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ 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: From d637759e1bd3098a5bd6e4085a167eaa676ed391 Mon Sep 17 00:00:00 2001 From: dlavigne Date: Mon, 1 Feb 2016 09:57:33 -0500 Subject: [PATCH 5/5] Doc getjailsettings action. --- api/classes/iocage.rst | 277 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 276 insertions(+), 1 deletion(-) diff --git a/api/classes/iocage.rst b/api/classes/iocage.rst index bb56128..dea8b7a 100644 --- a/api/classes/iocage.rst +++ b/api/classes/iocage.rst @@ -20,7 +20,7 @@ Every iocage class request contains the following parameters: | namespace | sysadm | | | | | | +---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ -| action | | supported actions include "getdefaultsettings", "listjails" | +| action | | supported actions include "getdefaultsettings", "listjails", "getjailsettings" | | | | | +---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ @@ -374,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 `. + +**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" + } + \ No newline at end of file