diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index 65dea7b..f05ad0a 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -24,6 +24,7 @@ #include "library/sysadm-servicemanager.h" #include "library/sysadm-firewall.h" #include "library/sysadm-moused.h" +#include "library/sysadm-powerd.h" #define DEBUG 0 //#define SCLISTDELIM QString("::::") //SysCache List Delimiter @@ -99,6 +100,10 @@ RestOutputStruct::ExitCode WebSocket::AvailableSubsystems(bool allaccess, QJsonO if(QFile::exists("/usr/sbin/moused")){ out->insert("sysadm/moused", "read/write"); } + // - powerd + if(QFile::exists("/usr/sbin/powerd")){ + out->insert("sysadm/powerd", "read/write"); + } return RestOutputStruct::OK; } @@ -157,6 +162,8 @@ RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(const RestInputStru return EvaluateSysadmFirewallRequest(IN.args, out); }else if(namesp=="sysadm" && name=="moused"){ return EvaluateSysadmMousedRequest(IN.args, out); + }else if(namesp=="sysadm" && name=="powerd"){ + return EvaluateSysadmPowerdRequest(IN.args, out); }else{ return RestOutputStruct::BADREQUEST; } @@ -1248,3 +1255,33 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmMousedRequest(const QJsonVal } } + +RestOutputStruct::ExitCode WebSocket::EvaluateSysadmPowerdRequest(const QJsonValue in_args, QJsonObject *out){ + QString action = in_args.toObject().value("action").toString(); + QJsonObject outobj; + if(action == "list_options"){ + outobj = sysadm::powerd::listOptions(); + }else if(action == "read_options"){ + outobj = sysadm::powerd::readOptions(); + }else if(action == "set_options"){ + outobj = sysadm::powerd::setOptions(in_args.toObject()); + }else if(action == "list_status"){ + outobj = sysadm::powerd::listStatus(); + }else if(action == "set_active"){ + outobj = sysadm::powerd::enableService(); + }else if(action == "set_inactive"){ + outobj = sysadm::powerd::disableService(); + }else if(action == "start"){ + outobj = sysadm::powerd::startService(); + }else if(action == "stop"){ + outobj = sysadm::powerd::stopService(); + } + + //check return structure for validity + if(!outobj.keys().isEmpty()){ + out->insert(action, outobj); + return RestOutputStruct::OK; + }else{ + return RestOutputStruct::BADREQUEST; + } +} diff --git a/src/server/WebSocket.h b/src/server/WebSocket.h index c39e29a..e0f0673 100644 --- a/src/server/WebSocket.h +++ b/src/server/WebSocket.h @@ -98,6 +98,8 @@ private: RestOutputStruct::ExitCode EvaluateSysadmFirewallRequest(const QJsonValue in_args, QJsonObject *out); // -- sysadm moused API RestOutputStruct::ExitCode EvaluateSysadmMousedRequest(const QJsonValue in_args, QJsonObject *out); + // -- sysadm powerd API + RestOutputStruct::ExitCode EvaluateSysadmPowerdRequest(const QJsonValue in_args, QJsonObject *out); private slots: void sendReply(QString msg); diff --git a/src/server/library/library.pri b/src/server/library/library.pri index 63c1ac5..ef6042a 100644 --- a/src/server/library/library.pri +++ b/src/server/library/library.pri @@ -16,7 +16,8 @@ HEADERS += $${PWD}/sysadm-global.h \ $${PWD}/sysadm-users.h \ $${PWD}/sysadm-zfs.h \ $${PWD}/sysadm-pkg.h \ - $${PWD}/sysadm-moused.h + $${PWD}/sysadm-moused.h \ + $${PWD}/sysadm-powerd.h SOURCES += $${PWD}/NetDevice.cpp \ $${PWD}/sysadm-general.cpp \ @@ -33,4 +34,5 @@ SOURCES += $${PWD}/NetDevice.cpp \ $${PWD}/sysadm-users.cpp \ $${PWD}/sysadm-zfs.cpp \ $${PWD}/sysadm-pkg.cpp \ - $${PWD}/sysadm-moused.cpp + $${PWD}/sysadm-moused.cpp \ + $${PWD}/sysadm-powerd.cpp diff --git a/src/server/library/sysadm-powerd.cpp b/src/server/library/sysadm-powerd.cpp new file mode 100644 index 0000000..88c954f --- /dev/null +++ b/src/server/library/sysadm-powerd.cpp @@ -0,0 +1,177 @@ +//=========================================== +// TrueOS source code +// Copyright (c) 2017, TrueOS Software/iXsystems +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "sysadm-general.h" +#include "sysadm-powerd.h" +#include "sysadm-global.h" +#include "globals.h" + +#include "sysadm-servicemanager.h" + +#define _POWERD_CONF QString("/etc/conf.d/powerd") +#define _POWERD_SYS_CONF QString("/etc/rc.conf") +#define _POWERD_DEFAULT_CONF QString("/etc/defaults/rc.conf") + +using namespace sysadm; + +//Service options for individual devices +QJsonObject powerd::listOptions(){ + QJsonObject out; + out.insert("ac_power_mode", QJsonArray() << "maximum" << "hiadaptive" << "adaptive" << "minumum"); // "-a" flag + out.insert("battery_power_mode", QJsonArray() << "maximum" << "hiadaptive" << "adaptive" << "minumum"); // "-b" flag + out.insert("unknown_power_mode", QJsonArray() << "maximum" << "hiadaptive" << "adaptive" << "minumum"); // "-n" flag + out.insert("adaptive_lower_threshold_percent", "int min=1 max=100"); // "-i" flag + out.insert("adaptive_raise_threshold_percent", "int min=1 max=100"); // "-r" flag + out.insert("min_cpu_freq", "int frequency(hz)>0"); // "-m" flag + out.insert("max_cpu_freq", "int frequency(hz)>0"); // "-M" flag + out.insert("polling_interval_ms", "int milliseconds>0"); // "-p" flag + return out; +} + +QJsonObject powerd::readOptions(){ + + QString val = General::getConfFileValue(_POWERD_CONF, "powerd_args=" ); + if(val.isEmpty()){ General::getConfFileValue(_POWERD_SYS_CONF, "powerd_args=" ); } + if(val.isEmpty()){ General::getConfFileValue(_POWERD_DEFAULT_CONF, "powerd_args=" ); } + val = val.simplified(); + if(val.startsWith("\"")){ val.remove(0,1); } + if(val.endsWith("\"")){ val.chop(1); } + QStringList args = val.split(" "); + //qDebug() << " - Arguments:" << args; + QJsonObject out; + //Now parse the arguments and list them in the output object + int index = args.indexOf("-a"); + if(index>=0 && index < (args.length()-1) ){ + out.insert("ac_power_mode", args[index+1] ); + }else{ + QString ac = General::getConfFileValue(_POWERD_CONF, "powerd_ac_mode=" ); + if(ac.isEmpty()){ ac = "adaptive"; } + out.insert("ac_power_mode",ac); + } + index = args.indexOf("-b"); + if(index>=0 && index < (args.length()-1) ){ + out.insert("battery_power_mode", args[index+1] ); + }else{ + QString bat = General::getConfFileValue(_POWERD_CONF, "powerd_battery_mode=" ); + if(bat.isEmpty()){ bat = "adaptive"; } + out.insert("battery_power_mode",bat); + } + index = args.indexOf("-n"); + if(index>=0 && index < (args.length()-1) ){ + out.insert("unknown_power_mode", args[index+1] ); + }else{ + out.insert("unknown_power_mode", "adaptive"); + } + index = args.indexOf("-i"); + if(index>=0 && index < (args.length()-1) ){ + out.insert("adaptive_lower_threshold_percent", args[index+1] ); + }else{ + out.insert("adaptive_lower_threshold_percent", "50"); + } + index = args.indexOf("-r"); + if(index>=0 && index < (args.length()-1) ){ + out.insert("adaptive_raise_threshold_percent", args[index+1] ); + }else{ + out.insert("adaptive_raise_threshold_percent", "75"); + } + index = args.indexOf("-m"); + if(index>=0 && index < (args.length()-1) ){ + out.insert("min_cpu_freq", args[index+1] ); + }else{ + out.insert("min_cpu_freq", "-1"); + } + index = args.indexOf("-M"); + if(index>=0 && index < (args.length()-1) ){ + out.insert("max_cpu_freq", args[index+1] ); + }else{ + out.insert("max_cpu_freq", "-1"); + } + index = args.indexOf("-p"); + if(index>=0 && index < (args.length()-1) ){ + out.insert("polling_interval_ms", args[index+1] ); + }else{ + out.insert("polling_interval_ms", "250"); + } + return out; +} + +QJsonObject powerd::setOptions(QJsonObject obj){ + QJsonObject Cobj = readOptions(); + + //Overlay the user's settings on top of the current settings + QStringList keys = Cobj.keys(); + bool foundchange = false; + for(int i=0; i=0){ args << "-m" << val; } + else if(keys[i]=="max_cpu_freq" && val.toInt()>=0){ args << "-M" << val; } + else if(keys[i]=="polling_interval_ms"){ args << "-p" << val; } + } + //Save the arguments into the settings file + QString device = obj.value("device").toString(); + General::setConfFileValue(_POWERD_CONF, "powerd_args=", "powerd_args=\""+args.join(" ")+"\"" ); + //Restart the moused daemon for this device + General::RunQuickCommand("service moused."+device+" restart"); + return Cobj; //return the object for the settings we just used +} + +//Service status for devices (enable/disable device) +QJsonObject powerd::listStatus(){ + ServiceManager SMGR; + Service serv = SMGR.GetService("powerd"); + QJsonObject out; + out.insert("running", SMGR.isRunning(serv) ? "true" : "false" ); + out.insert("enabled", SMGR.isEnabled(serv) ? "true" : "false" ); + return out; +} + +QJsonObject powerd::startService(){ + ServiceManager SMGR; + Service serv = SMGR.GetService("powerd"); + bool ok = SMGR.Start(serv); + QJsonObject out; + out.insert("started", ok ? "true" : "false"); + return out; +} + +QJsonObject powerd::stopService(){ + ServiceManager SMGR; + Service serv = SMGR.GetService("powerd"); + bool ok = SMGR.Stop(serv); + QJsonObject out; + out.insert("stopped", ok ? "true" : "false"); + return out; +} + +QJsonObject powerd::enableService(){ + ServiceManager SMGR; + Service serv = SMGR.GetService("powerd"); + bool ok = SMGR.Enable(serv); + QJsonObject out; + out.insert("enabled", ok ? "true" : "false"); + return out; +} + +QJsonObject powerd::disableService(){ + ServiceManager SMGR; + Service serv = SMGR.GetService("powerd"); + bool ok = SMGR.Disable(serv); + QJsonObject out; + out.insert("disabled", ok ? "true" : "false"); + return out; +} diff --git a/src/server/library/sysadm-powerd.h b/src/server/library/sysadm-powerd.h new file mode 100644 index 0000000..3b79086 --- /dev/null +++ b/src/server/library/sysadm-powerd.h @@ -0,0 +1,34 @@ +//=========================================== +// TrueOS source code +// Copyright (c) 2017, TrueOS Software/iXsystems +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef __TRUEOS_SYSADM_UTILS_POWERD_H +#define __TRUEOS_SYSADM_UTILS_POWERD_H + +#include +#include "sysadm-global.h" + +namespace sysadm{ + +class powerd{ +public: + + //Service options for individual devices + static QJsonObject listOptions(); //list all the options and possible values + static QJsonObject readOptions(); //current values for device + static QJsonObject setOptions(QJsonObject); //change values for device + + //Service status for devices (enable/disable device) + static QJsonObject listStatus(); + static QJsonObject startService(); + static QJsonObject stopService(); + static QJsonObject enableService(); + static QJsonObject disableService(); + +}; + +} //end of namespace + +#endif