diff --git a/api/classes/iocage.rst b/api/classes/iocage.rst index f8be2d7..d1d7d6a 100644 --- a/api/classes/iocage.rst +++ b/api/classes/iocage.rst @@ -1,7 +1,98 @@ .. _iocage: iocage -====== +****** -Some intro text here... +The iocage class is used to manage jails which provide a light-weight, operating system-level virtualization for running applications or services. +Every iocage class request contains the following parameters: + ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| **Parameter** | **Value** | **Description** | +| | | | ++=================================+===============+======================================================================================================================+ +| id | | any unique value for the request; examples include a hash, checksum, or uuid | +| | | | ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| name | iocage | | +| | | | ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| namespace | sysadm | | +| | | | ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| action | | supported actions include "listjails" | +| | | | ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ + +The rest of this section provides examples of the available *actions* for each type of request, along with their responses. + +.. index:: listjails, iocage + +.. _List Jails: + +List Jails +========== + +The "listjails" action lists information about currently installed jails. For each jail, the response includes the UUID of the jail, whether or not the jail has been configured to start at +system boot, the jail ID (only applies to running jails), whether or not the jail is running, a friendly name for the jail (tag), and the type of jail (basejail or thickjail). + +**REST Request** + +.. code-block:: json + + PUT /sysadm/iocage + { + "action" : "listjails" + } + +**REST Response** + +.. code-block:: json + + { + "args": { + "listjails": { + "611c89ae-c43c-11e5-9602-54ee75595566": { + "boot": "off", + "jid": "-", + "state": "down", + "tag": "testjail", + "type": "basejail" + } + } + } + } + +**WebSocket Request** + +.. code-block:: json + + { + "args" : { + "action" : "listjails" + }, + "name" : "iocage", + "id" : "fooid", + "namespace" : "sysadm" + } + +**WebSocket Response** + +.. code-block:: json + + { + "args": { + "listjails": { + "611c89ae-c43c-11e5-9602-54ee75595566": { + "boot": "off", + "jid": "-", + "state": "down", + "tag": "testjail", + "type": "basejail" + } + } + }, + "id": "fooid", + "name": "response", + "namespace": "sysadm" + } diff --git a/api/classes/systeminfo.rst b/api/classes/systeminfo.rst index 919f013..06ff53f 100644 --- a/api/classes/systeminfo.rst +++ b/api/classes/systeminfo.rst @@ -18,12 +18,224 @@ The systeminfo class is used to retrieve information about the system. Every sys | namespace | sysadm | | | | | | +---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ -| action | | supported actions include "batteryinfo", "externalmounts" | +| action | | supported actions include "memorystats", "cpupercentage", "cputemps", "batteryinfo", "externalmounts", "systeminfo" | | | | | +---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ The rest of this section provides examples of the available *actions* for each type of request, along with their responses. +.. index:: memorystats, systeminfo + +.. _Memory Statistics: + +Memory Statistics +================= + +The "memorystats" action returns memory statistics, including the amount of active, cached, free, inactive, and total physical (wired) memory. + +**REST Request** + +.. code-block:: json + + PUT /sysadm/systeminfo + { + "action" : "memorystats" + } + +**REST Response** + +.. code-block:: json + + { + "args": { + "memorystats": { + "active": "818", + "cache": "69", + "free": "4855", + "inactive": "2504", + "wired": "1598" + } + } + } + +**WebSocket Request** + +.. code-block:: json + + { + "id" : "fooid", + "args" : { + "action" : "memorystats" + }, + "namespace" : "sysadm", + "name" : "systeminfo" + } + +**WebSocket Response** + +.. code-block:: json + + { + "args": { + "memorystats": { + "active": "826", + "cache": "69", + "free": "4847", + "inactive": "2505", + "wired": "1598" + } + }, + "id": "fooid", + "name": "response", + "namespace": "sysadm" + } + +.. index:: cpupercentage, systeminfo + +.. _CPU Usage: + +CPU Usage +========= + +The "cpupercentage" action returns the usage percentage of each CPU. + +**REST Request** + +.. code-block:: json + + PUT /sysadm/systeminfo + { + "action" : "cpupercentage" + } + +**REST Response** + +.. code-block:: json + + { + "args": { + "cpupercentage": { + "busytotal": "28", + "cpu1": { + "busy": "28" + }, + "cpu2": { + "busy": "31" + }, + "cpu3": { + "busy": "29" + }, + "cpu4": { + "busy": "24" + } + } + } + } + +**WebSocket Request** + +.. code-block:: json + + { + "args" : { + "action" : "cpupercentage" + }, + "name" : "systeminfo", + "id" : "fooid", + "namespace" : "sysadm" + } + +**WebSocket Response** + +.. code-block:: json + + { + "args": { + "cpupercentage": { + "busytotal": "28", + "cpu1": { + "busy": "28" + }, + "cpu2": { + "busy": "31" + }, + "cpu3": { + "busy": "29" + }, + "cpu4": { + "busy": "24" + } + } + }, + "id": "fooid", + "name": "response", + "namespace": "sysadm" + } + +.. index:: cputemps, systeminfo + +.. _CPU Temperature: + +CPU Temperature +=============== + +The "cputemps" action returns the temperature of each CPU. + +**REST Request** + +.. code-block:: json + + PUT /sysadm/systeminfo + { + "action" : "cputemps" + } + +**REST Response** + +.. code-block:: json + + { + "args": { + "cputemps": { + "cpu0": "27.0C", + "cpu1": "34.0C", + "cpu2": "33.0C", + "cpu3": "31.0C" + } + } + } + +**WebSocket Request** + +.. code-block:: json + + { + "args" : { + "action" : "cputemps" + }, + "id" : "fooid", + "name" : "systeminfo", + "namespace" : "sysadm" + } + +**WebSocket Response** + +.. code-block:: json + + { + "args": { + "cputemps": { + "cpu0": "34.0C", + "cpu1": "32.0C", + "cpu2": "34.0C", + "cpu3": "31.0C" + } + }, + "id": "fooid", + "name": "response", + "namespace": "sysadm" + } + .. index:: batteryinfo, systeminfo .. _Battery Information: @@ -31,9 +243,8 @@ The rest of this section provides examples of the available *actions* for each t Battery Information =================== -The "batteryinfo" action will indicate whether or not a battery exists. If it does, it will also report its current charge percentage level (1-99) and its -status (offline, charging, on backup, or unknown) and estimated time left (in seconds) -timeleft (1-XXXXXX) +The "batteryinfo" action will indicate whether or not a battery exists. If it does, it will also report its current charge percentage level (1-99). its +status (offline, charging, on backup, or unknown), and estimated time left (in seconds). **REST Request** @@ -150,3 +361,78 @@ For each mounted device, the response will include the device name, filesystem, "name": "response", "namespace": "sysadm" } + +.. index:: systeminfo + +.. _System Information: + +System Information +================== + +The "systeminfo" action lists system information, including the architecture, number of CPUs, type of CPU, hostname, kernel name and version, system version and patch level, total amount +of RAM, and the system's uptime. + +**REST Request** + +.. code-block:: json + + PUT /sysadm/systeminfo + { + "action" : "systeminfo" + } + +**REST Response** + +.. code-block:: json + + { + "args": { + "systeminfo": { + "arch": "amd64", + "cpucores": "4", + "cputype": "Intel(R) Xeon(R) CPU E3-1220 v3 @ 3.10GHz", + "hostname": "krisdesktop", + "kernelident": "GENERIC", + "kernelversion": "10.2-RELEASE-p11", + "systemversion": "10.2-RELEASE-p12", + "totalmem": 10720, + "uptime": "up 2 days 5:09" + } + } + } + +**WebSocket Request** + +.. code-block:: json + + { + "args" : { + "action" : "systeminfo" + }, + "id" : "fooid", + "name" : "systeminfo", + "namespace" : "sysadm" + } + +**WebSocket Response** + +.. code-block:: json + + { + "args": { + "systeminfo": { + "arch": "amd64", + "cpucores": "4", + "cputype": "Intel(R) Xeon(R) CPU E3-1220 v3 @ 3.10GHz", + "hostname": "krisdesktop", + "kernelident": "GENERIC", + "kernelversion": "10.2-RELEASE-p11", + "systemversion": "10.2-RELEASE-p12", + "totalmem": 10720, + "uptime": "up 2 days 5:09" + } + }, + "id": "fooid", + "name": "response", + "namespace": "sysadm" + } \ No newline at end of file diff --git a/api/classes/updates.rst b/api/classes/updates.rst index 3e7dab5..a665234 100644 --- a/api/classes/updates.rst +++ b/api/classes/updates.rst @@ -20,7 +20,7 @@ Every update class request contains the following parameters: | namespace | sysadm | | | | | | +---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ -| action | | supported actions include "checkupdates" | +| action | | supported actions include "checkupdates", "listbranches" | | | | | +---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ @@ -83,4 +83,64 @@ upgrade to a newer version of the operating system, a system patch, or an update "id": "fooid", "name": "response", "namespace": "sysadm" + } + +.. index:: listbranches, update + +.. _List Branches: + +List Branches +============= + +The "listbranches" action retrieves the list of available branches (operating system versions). The currently installed version will be listed as "active". + +**REST Request** + +.. code-block:: json + + PUT /sysadm/update + { + "action" : "listbranches" + } + +**REST Response** + +.. code-block:: json + + { + "args": { + "listbranches": { + "10.2-RELEASE": "active", + "11.0-CURRENTJAN2016": "available" + } + } + } + +**WebSocket Request** + +.. code-block:: json + + { + "args" : { + "action" : "listbranches" + }, + "namespace" : "sysadm", + "name" : "update", + "id" : "fooid" + } + +**WebSocket Response** + +.. code-block:: json + + { + "args": { + "listbranches": { + "10.2-RELEASE": "active", + "11.0-CURRENTJAN2016": "available" + } + }, + "id": "fooid", + "name": "response", + "namespace": "sysadm" } \ No newline at end of file diff --git a/api/events.rst b/api/events.rst new file mode 100644 index 0000000..3d3c498 --- /dev/null +++ b/api/events.rst @@ -0,0 +1,61 @@ +.. _Events: + +Events +****** + +The "events" namespace can be used to setup and receive asyncronous updates about system status and other types of system notifications. + +.. _note: the events namespace does not really translate over to REST which was not designed for asyncronous events. For this reason, only Websocket examples are used in this section. + +Every events request contains the following parameters: + ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| **Parameter** | **Value** | **Description** | +| | | | ++=================================+===============+======================================================================================================================+ +| id | | any unique value for the request; examples include a hash, checksum, or uuid | +| | | | ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| name | | supported values are "subscribe" or unsubscribe" | +| | | | ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| namespace | events | | +| | | | ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ +| args | | values vary by type of class | +| | | | ++---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+ + +Here is an example of subscribing to Life Preserver events: + +**Websocket Request** + +.. code-block:: json + + { + "namespace" : "events", + "name" : "subscribe", + "id" : "sampleID", + "args" : ["dispatcher", "life-preserver"] + } + +Once subscribed, events will be received as they are produced. To unsubscribe from events, repeat the request, using "unsubscribe" for the "name". + +Here is an example reply: + +**Websocket Reply** + +.. code-block:: json + + { + "namespace" : "events", + "name" : "life-preserver", + "id" : "" + "args" : { + "message" : , + "priority" : " - + ", + "class" : "[snapshot/replication]" + } + } + diff --git a/api/index.rst b/api/index.rst index 3f1675f..c81f9ba 100644 --- a/api/index.rst +++ b/api/index.rst @@ -7,6 +7,7 @@ PC-BSDĀ® API Reference connection users + events classes/index Indices and tables diff --git a/mkports-list b/mkports-list new file mode 100644 index 0000000..c898fca --- /dev/null +++ b/mkports-list @@ -0,0 +1 @@ +src sysutils/sysadm sysadm diff --git a/mkports.sh b/mkports.sh new file mode 100755 index 0000000..81b1970 --- /dev/null +++ b/mkports.sh @@ -0,0 +1,146 @@ +#!/bin/sh +# Helper script which will create the port / distfiles +# from a checked out git repo + +get_last_rev_git() +{ + oPWD=`pwd` + cd "${1}" + rev=0 + rev=`git log -n 1 --date=raw . | grep 'Date:' | awk '{print $2}'` + cd "$oPWD" + if [ -n "$rev" ] ; then + echo "$rev" + return 0 + else + rev=`git log -n 1 --date=raw . | grep 'Date:' | awk '{print $2}'` + echo $rev + return 0 + fi + return 1 +} + +massage_subdir() { + cd "$1" + if [ $? -ne 0 ] ; then + echo "SKIPPING $i" + continue + fi + + echo "# \$FreeBSD\$ +# + +$comment +" > Makefile.tmp + + for d in `ls` + do + if [ "$d" = ".." ]; then continue ; fi + if [ "$d" = "." ]; then continue ; fi + if [ "$d" = "Makefile" ]; then continue ; fi + if [ ! -f "$d/Makefile" ]; then continue ; fi + echo " SUBDIR += $d" >> Makefile.tmp + done + echo "" >> Makefile.tmp + echo ".include " >> Makefile.tmp + mv Makefile.tmp Makefile + +} + +if [ -z "$1" ] ; then + echo "Usage: ./mkports.sh " + exit 1 +fi + +if [ ! -d "${1}/Mk" ] ; then + echo "Invalid directory: $1" + exit 1 +fi + +portsdir="${1}" +if [ -z "$2" ] ; then + distdir="${1}/distfiles" +else + distdir="${2}" +fi +if [ ! -d "$distdir" ] ; then + mkdir -p ${distdir} +fi + +ODIR=`pwd` + +# Get this jail version +export UNAME_r="`freebsd-version`" + +# Get the GIT tag +ghtag=`git log -n 1 . | grep '^commit ' | awk '{print $2}'` + + +# Read the list of ports and build them now +while read pline +do + + cd "$ODIR" + ldir=`echo $pline | awk '{print $1}'` + + # Check for sub-dir + echo "$ldir" | grep -q '/' + if [ $? -eq 0 ] ; then + lsubdir=`echo $ldir | cut -d '/' -f 1` + ltopdir=`echo $ldir | cut -d '/' -f 2` + tOps="-C $lsubdir $ltopdir" + else + unset lsubdir ltopdir + tOps="$ldir" + fi + + tdir=`echo $pline | awk '{print $2}'` + tcat=`echo $tdir | cut -d '/' -f 1` + dfile=`echo $pline | awk '{print $3}'` + + # Get git revision number + REV=`get_last_rev_git "./$ldir"` + + port=`echo $pline | awk '{print $2}'` + tverfile="/tmp/.pcbsd-tests/`echo $port | sed 's|/|_|g'`" + if [ -e "$tverfile" -a -n "$PCBSD_MKTESTS" ] ; then + # If this file exists, we did a previous build of this port + oVer=`cat $tverfile` + echo "$port - $REV - $oVer -" + if [ "$REV" = "$oVer" ] ; then + echo "No changes to port: $port" + continue + fi + fi + + # Make the dist files + rm ${distdir}/${dfile}-* 2>/dev/null + echo "Creating $tdir dist file for version: $REV" + tar cvJf ${distdir}/${dfile}-${REV}.tar.xz --exclude .git $tOps 2>/dev/null >/dev/null + if [ $? -ne 0 ] ; then + echo "Error creating distfile..." + exit 1 + fi + + # Copy ports files + if [ -d "${portsdir}/$tdir" ] ; then + rm -rf ${portsdir}/$tdir 2>/dev/null + fi + cp -r ${ldir}/port-files ${portsdir}/$tdir + + # Set the version numbers + sed -i '' "s|%%CHGVERSION%%|${REV}|g" ${portsdir}/$tdir/Makefile + sed -i '' "s|%%GHTAG%%|${ghtag}|g" ${portsdir}/$tdir/Makefile + + # Create the makesums / distinfo file + cd "${portsdir}/$tdir" + make makesum + if [ $? -ne 0 ] ; then + echo "Failed makesum" + exit 1 + fi + + # Now make sure subdir Makefile is correct + massage_subdir "${portsdir}/$tcat" + +done < mkports-list diff --git a/port-files/pkg-descr b/port-files/pkg-descr deleted file mode 100644 index 0d3fd26..0000000 --- a/port-files/pkg-descr +++ /dev/null @@ -1,3 +0,0 @@ -PC-BSD SysAdm utility and websocket server - -WWW: https://github.com/pcbsd/sysadm diff --git a/src/library/library.pro b/src/library/library.pro index b0c650e..d4bb7df 100644 --- a/src/library/library.pro +++ b/src/library/library.pro @@ -12,6 +12,7 @@ VERSION = 1.0.0 HEADERS += sysadm-global.h \ sysadm-general.h \ + sysadm-iocage.h \ sysadm-lifepreserver.h \ sysadm-network.h \ sysadm-firewall.h \ @@ -22,6 +23,7 @@ HEADERS += sysadm-global.h \ SOURCES += NetDevice.cpp \ sysadm-general.cpp \ + sysadm-iocage.cpp \ sysadm-lifepreserver.cpp \ sysadm-network.cpp \ sysadm-firewall.cpp \ diff --git a/src/library/sysadm-iocage.cpp b/src/library/sysadm-iocage.cpp new file mode 100644 index 0000000..3652059 --- /dev/null +++ b/src/library/sysadm-iocage.cpp @@ -0,0 +1,43 @@ +//=========================================== +// PC-BSD source code +// Copyright (c) 2015, PC-BSD Software/iXsystems +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "sysadm-general.h" +#include "sysadm-iocage.h" +#include "sysadm-global.h" + +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::listJails() { + QJsonObject retObject; + + QStringList output = General::RunCommand("iocage list").split("\n"); + + for ( int i = 0; i < output.size(); i++) + { + if ( output.at(i).indexOf("JID") != -1 ) + continue; + + if ( output.at(i).isEmpty() ) + break; + + QJsonObject jail; + QString line = output.at(i).simplified(); + QString uuid = line.section(" ", 1, 1); + + jail.insert("jid", line.section(" ", 0, 0)); + jail.insert("boot", line.section(" ", 2, 2)); + jail.insert("state", line.section(" ", 3, 3)); + jail.insert("tag", line.section(" ", 4, 4)); + jail.insert("type", line.section(" ", 5, 5)); + + retObject.insert(uuid, jail); + } + + return retObject; +} diff --git a/src/library/sysadm-iocage.h b/src/library/sysadm-iocage.h new file mode 100644 index 0000000..d9f191e --- /dev/null +++ b/src/library/sysadm-iocage.h @@ -0,0 +1,22 @@ +//=========================================== +// PC-BSD source code +// Copyright (c) 2015, PC-BSD Software/iXsystems +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef __PCBSD_LIB_UTILS_IOCAGE_H +#define __PCBSD_LIB_UTILS_IOCAGE_H + +#include +#include "sysadm-global.h" + +namespace sysadm{ + +class Iocage{ +public: + static QJsonObject listJails(); +}; + +} //end of pcbsd namespace + +#endif diff --git a/src/library/sysadm-systeminfo.cpp b/src/library/sysadm-systeminfo.cpp index 89d56cf..235da49 100644 --- a/src/library/sysadm-systeminfo.cpp +++ b/src/library/sysadm-systeminfo.cpp @@ -161,16 +161,91 @@ QJsonObject SysInfo::externalDevicePaths() { return retObject; } -// KPM 1-21-2016 -// This needs to beefed up as well, so we return more stats on arc, wired, etc -QJsonObject SysInfo::memoryPercentage() { +// Return information about memory +QJsonObject SysInfo::memoryStats() { QJsonObject retObject; - //SYSCTL: vm.stats.vm.v__count - QStringList info = General::RunCommand("sysctl -n vm.stats.vm.v_page_count vm.stats.vm.v_wire_count vm.stats.vm.v_active_count").split("\n"); - if(info.length()<3){ return retObject; } //error in fetching information - //List output: [total, wired, active] - double perc = 100.0* (info[1].toLong()+info[2].toLong())/(info[0].toDouble()); - retObject.insert("memoryused", qRound(perc)); + + QString tmp; + long pageSize; + bool ok; + + // Get the page size + tmp = General::RunCommand("sysctl -n vm.stats.vm.v_page_size").simplified(); + tmp.toLong(&ok); + if ( ok ) + pageSize = tmp.toLong(); + else + return retObject; + + // Get the free size + tmp = General::RunCommand("sysctl -n vm.stats.vm.v_free_count").simplified(); + tmp.toLong(&ok); + if ( ok ) + retObject.insert("free", tmp.setNum((tmp.toLong() * pageSize) / 1024 / 1024)); + + // Get the inactive size + tmp = General::RunCommand("sysctl -n vm.stats.vm.v_inactive_count").simplified(); + tmp.toLong(&ok); + if ( ok ) + retObject.insert("inactive", tmp.setNum((tmp.toLong() * pageSize) / 1024 / 1024)); + + // Get the cache size + tmp = General::RunCommand("sysctl -n vm.stats.vm.v_cache_count").simplified(); + tmp.toLong(&ok); + if ( ok ) + retObject.insert("cache", tmp.setNum((tmp.toLong() * pageSize) / 1024 / 1024)); + + // Get the wired size + tmp = General::RunCommand("sysctl -n vm.stats.vm.v_wire_count").simplified(); + tmp.toLong(&ok); + if ( ok ) + retObject.insert("wired", tmp.setNum((tmp.toLong() * pageSize) / 1024 / 1024)); + + // Get the active size + tmp = General::RunCommand("sysctl -n vm.stats.vm.v_active_count").simplified(); + tmp.toLong(&ok); + if ( ok ) + retObject.insert("active", tmp.setNum((tmp.toLong() * pageSize) / 1024 / 1024)); + + return retObject; +} + +// Return a bunch of various system information +QJsonObject SysInfo::systemInfo() { + QJsonObject retObject; + + QString arch = General::RunCommand("uname -m").simplified(); + retObject.insert("arch", arch); + + QString sysver = General::RunCommand("freebsd-version").simplified(); + retObject.insert("systemversion", sysver); + + QString kernver = General::RunCommand("uname -r").simplified(); + retObject.insert("kernelversion", kernver); + + QString kernident = General::RunCommand("uname -i").simplified(); + retObject.insert("kernelident", kernident); + + QString host = General::RunCommand("hostname").simplified(); + retObject.insert("hostname", host); + + QString uptime = General::RunCommand("uptime").simplified().section(" ", 1, 4).simplified().replace(",", ""); + retObject.insert("uptime", uptime); + + QString cputype = General::RunCommand("sysctl -n hw.model").simplified(); + retObject.insert("cputype", cputype); + + QString cpucores = General::RunCommand("sysctl -n kern.smp.cpus").simplified(); + retObject.insert("cpucores", cpucores); + + bool ok; + QString tmp; + QString totalmem = General::RunCommand("sysctl -n hw.realmem").simplified(); + totalmem.toLong(&ok); + if ( ok ) { + retObject.insert("totalmem", tmp.setNum(totalmem.toLong() / 1024 / 1024)); + } + return retObject; } diff --git a/src/library/sysadm-systeminfo.h b/src/library/sysadm-systeminfo.h index d2c654a..a9c1c4a 100644 --- a/src/library/sysadm-systeminfo.h +++ b/src/library/sysadm-systeminfo.h @@ -18,7 +18,8 @@ public: static QJsonObject cpuPercentage(); static QJsonObject cpuTemps(); static QJsonObject externalDevicePaths(); - static QJsonObject memoryPercentage(); + static QJsonObject memoryStats(); + static QJsonObject systemInfo(); }; } //end of pcbsd namespace diff --git a/src/library/sysadm-update.cpp b/src/library/sysadm-update.cpp index f65de87..fc345cf 100644 --- a/src/library/sysadm-update.cpp +++ b/src/library/sysadm-update.cpp @@ -14,56 +14,87 @@ using namespace sysadm; // Return a list of updates available QJsonObject Update::checkUpdates() { - QJsonObject retObject; + QJsonObject retObject; - QStringList output = General::RunCommand("pc-updatemanager check").split("\n"); - QString nameval; + QStringList output = General::RunCommand("pc-updatemanager check").split("\n"); + QString nameval; - for ( int i = 0; i < output.size(); i++) - { - if ( output.at(i).indexOf("Your system is up to date!") != -1 ) - { - retObject.insert("status", "noupdates"); - return retObject; - } - if ( output.at(i).indexOf("NAME: ") != -1 ) - nameval = output.at(i).section(" ", 1, 1); + for ( int i = 0; i < output.size(); i++) + { + if ( output.at(i).indexOf("Your system is up to date!") != -1 ) + { + retObject.insert("status", "noupdates"); + return retObject; + } + if ( output.at(i).indexOf("NAME: ") != -1 ) + nameval = output.at(i).section(" ", 1, 1); - if ( output.at(i).indexOf("TYPE: SECURITYUPDATE") != -1 ) { - QJsonObject itemvals; - itemvals.insert("name", nameval); - retObject.insert("security", itemvals); - } - if ( output.at(i).indexOf("TYPE: SYSTEMUPDATE") != -1 ) { - QJsonObject itemvals; - itemvals.insert("name", nameval); - if ( output.size() > ( i + 1) ) - itemvals.insert("tag", output.at(i+1).section(" ", 1, 1)); - if ( output.size() > ( i + 2) ) - itemvals.insert("version", output.at(i+2).section(" ", 1, 1)); - retObject.insert("majorupgrade", itemvals); - } - if ( output.at(i).indexOf("TYPE: PATCH") != -1 ) { - QJsonObject itemvals; - itemvals.insert("name", nameval); - if ( output.size() > ( i + 1) ) - itemvals.insert("tag", output.at(i+1).section(" ", 1, 1)); - if ( output.size() > ( i + 2) ) - itemvals.insert("details", output.at(i+2).section(" ", 1, 1)); - if ( output.size() > ( i + 3) ) - itemvals.insert("date", output.at(i+3).section(" ", 1, 1)); - if ( output.size() > ( i + 4) ) - itemvals.insert("size", output.at(i+4).section(" ", 1, 1)); - retObject.insert("patch", itemvals); - } - if ( output.at(i).indexOf("TYPE: PKGUPDATE") != -1 ) { - QJsonObject itemvals; - itemvals.insert("name", nameval); - retObject.insert("packageupdate", itemvals); - } + if ( output.at(i).indexOf("TYPE: SECURITYUPDATE") != -1 ) { + QJsonObject itemvals; + itemvals.insert("name", nameval); + retObject.insert("security", itemvals); + } + if ( output.at(i).indexOf("TYPE: SYSTEMUPDATE") != -1 ) { + QJsonObject itemvals; + itemvals.insert("name", nameval); + if ( output.size() > ( i + 1) ) + itemvals.insert("tag", output.at(i+1).section(" ", 1, 1)); + if ( output.size() > ( i + 2) ) + itemvals.insert("version", output.at(i+2).section(" ", 1, 1)); + retObject.insert("majorupgrade", itemvals); + } + if ( output.at(i).indexOf("TYPE: PATCH") != -1 ) { + QJsonObject itemvals; + itemvals.insert("name", nameval); + if ( output.size() > ( i + 1) ) + itemvals.insert("tag", output.at(i+1).section(" ", 1, 1)); + if ( output.size() > ( i + 2) ) + itemvals.insert("details", output.at(i+2).section(" ", 1, 1)); + if ( output.size() > ( i + 3) ) + itemvals.insert("date", output.at(i+3).section(" ", 1, 1)); + if ( output.size() > ( i + 4) ) + itemvals.insert("size", output.at(i+4).section(" ", 1, 1)); + retObject.insert("patch", itemvals); + } + if ( output.at(i).indexOf("TYPE: PKGUPDATE") != -1 ) { + QJsonObject itemvals; + itemvals.insert("name", nameval); + retObject.insert("packageupdate", itemvals); + } } // Update status that we have updates retObject.insert("status", "updatesavailable"); return retObject; } + +// List available branches we can switch to +QJsonObject Update::listBranches() { + QJsonObject retObject; + + QStringList output = General::RunCommand("pc-updatemanager branches").split("\n"); + + bool inSection = false; + for ( int i = 0; i < output.size(); i++) + { + if ( output.at(i).indexOf("-----------------") != -1 ) { + inSection = true; + continue; + } + + if (!inSection) + continue; + + if ( output.at(i).isEmpty() ) + break; + + QString tmp = output.at(i).section(" ", 0, 0); + QString tmp2 = output.at(i).section(" ", 1, 1); + if ( tmp2 == "*" ) + retObject.insert(tmp, "active"); + else + retObject.insert(tmp, "available"); + } + + return retObject; +} diff --git a/src/library/sysadm-update.h b/src/library/sysadm-update.h index f2a9284..efc7e3d 100644 --- a/src/library/sysadm-update.h +++ b/src/library/sysadm-update.h @@ -15,6 +15,7 @@ namespace sysadm{ class Update{ public: static QJsonObject checkUpdates(); + static QJsonObject listBranches(); }; } //end of pcbsd namespace diff --git a/port-files/Makefile b/src/port-files/Makefile similarity index 78% rename from port-files/Makefile rename to src/port-files/Makefile index e9c32d9..18d51c3 100644 --- a/port-files/Makefile +++ b/src/port-files/Makefile @@ -1,7 +1,7 @@ # Created by: Kris Moore # $FreeBSD$ -PORTNAME= pcbsd-sysadm +PORTNAME= sysadm PORTVERSION= %%CHGVERSION%% CATEGORIES= sysutils @@ -10,10 +10,6 @@ COMMENT= PC-BSD SysAdm API server LICENSE= BSD3CLAUSE -RUN_DEPENDS= sipcalc:${PORTSDIR}/net-mgmt/sipcalc \ - eject:${PORTSDIR}/sysutils/eject \ - unzip:${PORTSDIR}/archivers/unzip - WRKSRC_SUBDIR= src USE_QT5= core network buildtools qmake USES= pkgconfig tar:xz qmake diff --git a/port-files/distinfo b/src/port-files/distinfo similarity index 100% rename from port-files/distinfo rename to src/port-files/distinfo diff --git a/src/port-files/pkg-descr b/src/port-files/pkg-descr new file mode 100644 index 0000000..12325af --- /dev/null +++ b/src/port-files/pkg-descr @@ -0,0 +1,3 @@ +Sysadm API server and websocket daemon + +WWW: https://github.com/pcbsd/sysadm diff --git a/port-files/pkg-plist b/src/port-files/pkg-plist similarity index 57% rename from port-files/pkg-plist rename to src/port-files/pkg-plist index 87ca073..e8926b5 100644 --- a/port-files/pkg-plist +++ b/src/port-files/pkg-plist @@ -1,10 +1,17 @@ bin/sysadm bin/sysadm-server -etc/rc.d/sysadm +etc/rc.d/sysadm-restserver +etc/rc.d/sysadm-websocket +include/sysadm-firewall.h include/sysadm-general.h include/sysadm-global.h +include/sysadm-iocage.h include/sysadm-lifepreserver.h include/sysadm-network.h +include/sysadm-servicemanager.h +include/sysadm-systeminfo.h +include/sysadm-update.h +include/sysadm-usermanager.h %%QT_LIBDIR%%/%%QT_LIBDIR%%sysadm.so %%QT_LIBDIR%%/%%QT_LIBDIR%%sysadm.so.1 %%QT_LIBDIR%%/%%QT_LIBDIR%%sysadm.so.1.0 diff --git a/src/rc.d/sysadm-restserver b/src/rc.d/sysadm-restserver index 2433234..4d5ddae 100755 --- a/src/rc.d/sysadm-restserver +++ b/src/rc.d/sysadm-restserver @@ -15,9 +15,8 @@ name="sysadm_restserver" rcvar=sysadm_restserver_enable -command="/usr/local/bin/sysadm-server" -start_cmd="sysadm_start" -stop_cmd="sysadm_stop" +start_cmd="sysadm_restserver_start" +stop_cmd="sysadm_restserver_stop" flags="" [ -z "$sysadm_restserver_enable" ] && sysadm_restserver_enable="NO" @@ -35,19 +34,20 @@ ssl_keygen() -subj "/C=US/ST=MY/L=NULL/O=SysAdm/OU=SysAdm/CN=SysAdm/emailAddress=none@example.org" 2>/dev/null } -sysadm_stop() +sysadm_restserver_stop() { if [ -e "/var/run/sysadm-rest.pid" ] ; then pkill -9 -F /var/run/sysadm-rest.pid fi } -sysadm_start() +sysadm_restserver_start() { export PATH="${PATH}:/usr/local/bin:/usr/local/sbin" - sysadm_stop + sysadm_restserver_stop ssl_keygen echo "Starting sysadm (REST)..." + command="/usr/local/bin/sysadm-server" daemon -p /var/run/sysadm-rest.pid $command $flags >/dev/null 2>/dev/null chmod 744 /var/run/sysadm-rest.pid >/dev/null 2>/dev/null } diff --git a/src/rc.d/sysadm-websocket b/src/rc.d/sysadm-websocket index 9ddae20..1e59a65 100755 --- a/src/rc.d/sysadm-websocket +++ b/src/rc.d/sysadm-websocket @@ -15,9 +15,8 @@ name="sysadm_websocket" rcvar=sysadm_websocket_enable -command="/usr/local/bin/sysadm-server" -start_cmd="sysadm_start" -stop_cmd="sysadm_stop" +start_cmd="sysadm_websocket_start" +stop_cmd="sysadm_websocket_stop" flags="-ws" [ -z "$sysadm_websocket_enable" ] && sysadm_websocket_enable="NO" @@ -35,19 +34,20 @@ ssl_keygen() -subj "/C=US/ST=MY/L=NULL/O=SysAdm/OU=SysAdm/CN=SysAdm/emailAddress=none@example.org" 2>/dev/null } -sysadm_stop() +sysadm_websocket_stop() { if [ -e "/var/run/sysadm-websocket.pid" ] ; then pkill -9 -F /var/run/sysadm-websocket.pid fi } -sysadm_start() +sysadm_websocket_start() { export PATH="${PATH}:/usr/local/bin:/usr/local/sbin" - sysadm_stop + sysadm_websocket_stop ssl_keygen echo "Starting sysadm (WebSocket)..." + command="/usr/local/bin/sysadm-server" daemon -p /var/run/sysadm-websocket.pid $command $flags >/dev/null 2>/dev/null chmod 744 /var/run/sysadm-websocket.pid >/dev/null 2>/dev/null } diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index c5e870a..352c67c 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -10,6 +10,7 @@ //sysadm library interface classes #include "sysadm-general.h" +#include "sysadm-iocage.h" #include "sysadm-lifepreserver.h" #include "sysadm-network.h" #include "sysadm-systeminfo.h" @@ -45,7 +46,20 @@ RestOutputStruct::ExitCode WebSocket::AvailableSubsystems(bool allaccess, QJsonO if(QFile::exists("/usr/local/bin/lpreserver")){ out->insert("sysadm/lifepreserver", "read/write"); } + + // - iocage + if(QFile::exists("/usr/local/sbin/iocage")){ + out->insert("sysadm/iocage", "read/write"); + } + // - Generic system information + out->insert("sysadm/systeminfo","read/write"); + + // - PC-BSD Updater + if(QFile::exists("/usr/local/bin/pc-updatemanager")){ + out->insert("sysadm/update", "read/write"); + } + return RestOutputStruct::OK; } @@ -60,14 +74,16 @@ RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(const RestInputStru //Go through and forward this request to the appropriate sub-system if(namesp=="rpc" && name=="query"){ return AvailableSubsystems(IN.fullaccess, out); - }else if(namesp=="rpc" && name=="syscache"){ - return EvaluateSyscacheRequest(IN.args, out); }else if(namesp=="rpc" && name=="dispatcher"){ return EvaluateDispatcherRequest(IN.args, out); - }else if(namesp=="sysadm" && name=="network"){ - return EvaluateSysadmNetworkRequest(IN.args, out); + }else if(namesp=="sysadm" && name=="iocage"){ + return EvaluateSysadmIocageRequest(IN.args, out); }else if(namesp=="sysadm" && name=="lifepreserver"){ return EvaluateSysadmLifePreserverRequest(IN.args, out); + }else if(namesp=="sysadm" && name=="network"){ + return EvaluateSysadmNetworkRequest(IN.args, out); + }else if(namesp=="rpc" && name=="syscache"){ + return EvaluateSyscacheRequest(IN.args, out); }else if(namesp=="sysadm" && name=="systeminfo"){ return EvaluateSysadmSystemInfoRequest(IN.args, out); }else if(namesp=="sysadm" && name=="update"){ @@ -271,9 +287,13 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmSystemInfoRequest(const QJso ok = true; out->insert("externalmounts", sysadm::SysInfo::externalDevicePaths()); } - if(act=="memorypercentage"){ + if(act=="memorystats"){ ok = true; - out->insert("memorypercentage", sysadm::SysInfo::memoryPercentage()); + out->insert("memorystats", sysadm::SysInfo::memoryStats()); + } + if(act=="systeminfo"){ + ok = true; + out->insert("systeminfo", sysadm::SysInfo::systemInfo()); } } //end of "action" key usage @@ -297,9 +317,35 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmUpdateRequest(const QJsonVal QString act = JsonValueToString(in_args.toObject().value("action")); if(act=="checkupdates"){ ok = true; - qDebug() << " - Starting update check"; out->insert("checkupdates", sysadm::Update::checkUpdates()); - qDebug() << " - Finished update check"; + } + if(act=="listbranches"){ + ok = true; + out->insert("listbranches", sysadm::Update::listBranches()); + } + + } //end of "action" key usage + + //If nothing done - return the proper code + if(!ok){ + return RestOutputStruct::BADREQUEST; + } + }else{ // if(in_args.isArray()){ + return RestOutputStruct::BADREQUEST; + } + return RestOutputStruct::OK; +} + +//==== SYSADM -- iocage ==== +RestOutputStruct::ExitCode WebSocket::EvaluateSysadmIocageRequest(const QJsonValue in_args, QJsonObject *out){ + if(in_args.isObject()){ + QStringList keys = in_args.toObject().keys(); + bool ok = false; + if(keys.contains("action")){ + QString act = JsonValueToString(in_args.toObject().value("action")); + if(act=="listjails"){ + ok = true; + out->insert("listjails", sysadm::Iocage::listJails()); } } //end of "action" key usage diff --git a/src/server/WebSocket.h b/src/server/WebSocket.h index db1725a..e1ec81c 100644 --- a/src/server/WebSocket.h +++ b/src/server/WebSocket.h @@ -46,6 +46,8 @@ private: // -- Individual subsystems RestOutputStruct::ExitCode EvaluateSyscacheRequest(const QJsonValue in_args, QJsonObject *out); RestOutputStruct::ExitCode EvaluateDispatcherRequest(const QJsonValue in_args, QJsonObject *out); + // -- sysadm iocage API + RestOutputStruct::ExitCode EvaluateSysadmIocageRequest(const QJsonValue in_args, QJsonObject *out); // -- sysadm Network API RestOutputStruct::ExitCode EvaluateSysadmNetworkRequest(const QJsonValue in_args, QJsonObject *out); // -- sysadm LifePreserver API