diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index ed313bd..89c98af 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -18,6 +18,7 @@ #include "library/sysadm-systemmanager.h" #include "library/sysadm-update.h" #include "library/sysadm-zfs.h" +#include "library/sysadm-pkg.h" #include "syscache-client.h" @@ -67,10 +68,16 @@ RestOutputStruct::ExitCode WebSocket::AvailableSubsystems(bool allaccess, QJsonO out->insert("sysadm/iohyve", "read/write"); } + // - zfs if(QFile::exists("/sbin/zfs") && QFile::exists("/sbin/zpool")){ out->insert("sysadm/zfs", allaccess ? "read/write" : "read"); } + // - pkg + if(QFile::exists("/usr/local/sbin/pkg")){ + out->insert("sysadm/pkg", "read/write"); + } + // - Generic system information out->insert("sysadm/systemmanager","read/write"); @@ -123,6 +130,8 @@ RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(const RestInputStru return EvaluateSysadmUpdateRequest(IN.args, out); }else if(namesp=="sysadm" && name=="zfs"){ return EvaluateSysadmZfsRequest(IN.args, out); + }else if(namesp=="sysadm" && name=="pkg"){ + return EvaluateSysadmPkgRequest(IN.args, out); }else{ return RestOutputStruct::BADREQUEST; } @@ -681,3 +690,29 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmZfsRequest(const QJsonValue return RestOutputStruct::OK; } + +// ==== SYSADM PKG API ==== +RestOutputStruct::ExitCode WebSocket::EvaluateSysadmPkgRequest(const QJsonValue in_args, QJsonObject *out){ + if(!in_args.isObject() || !in_args.toObject().contains("action") ){ return RestOutputStruct::BADREQUEST; } + //REQUIRED: "action" + QString act = in_args.toObject().value("action").toString(); + //OPTIONAL: "repo" (uses local repo database by default) + QString repo = "local"; + if(in_args.toObject().contains("repo")){ repo = in_args.toObject().value("repo").toString(); } + //OPTIONAL: "pkg_origins" (defaults to everything for listing functions) + QStringList pkgs; + if(in_args.toObject().contains("pkg_origins")){ + if(in_args.toObject().value("pkg_origins").isString()){ pkgs << in_args.toObject().value("pkg_origins").toString(); } + else if(in_args.toObject().value("pkg_origins").isArray()){ pkgs = JsonArrayToStringList(in_args.toObject().value("pkg_origins").toArray()); } + } + //Parse + if(act=="pkg_info"){ + QJsonObject info = sysadm::PKG::pkg_info(pkgs, repo); + if(!pkgs.isEmpty()){ out->insert("pkg_info",info); } + }else{ + //unknown action + return RestOutputStruct::BADREQUEST; + } + + return RestOutputStruct::OK; +} \ No newline at end of file diff --git a/src/server/WebSocket.h b/src/server/WebSocket.h index 0c149eb..d127ef8 100644 --- a/src/server/WebSocket.h +++ b/src/server/WebSocket.h @@ -70,6 +70,8 @@ private: RestOutputStruct::ExitCode EvaluateSysadmUpdateRequest(const QJsonValue in_args, QJsonObject *out); // -- sysadm ZFS API RestOutputStruct::ExitCode EvaluateSysadmZfsRequest(const QJsonValue in_args, QJsonObject *out); + // -- sysadm PKG API + RestOutputStruct::ExitCode EvaluateSysadmPkgRequest(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 97e1da8..1b0fc54 100644 --- a/src/server/library/library.pri +++ b/src/server/library/library.pri @@ -13,7 +13,8 @@ HEADERS += $${PWD}/sysadm-global.h \ $${PWD}/sysadm-systemmanager.h\ $${PWD}/sysadm-update.h \ $${PWD}/sysadm-usermanager.h \ - $${PWD}/sysadm-zfs.h + $${PWD}/sysadm-zfs.h \ + $${PWD}/sysadm-pkg.h SOURCES += $${PWD}/NetDevice.cpp \ $${PWD}/sysadm-general.cpp \ @@ -27,5 +28,6 @@ SOURCES += $${PWD}/NetDevice.cpp \ $${PWD}/sysadm-systemmanager.cpp \ $${PWD}/sysadm-update.cpp \ $${PWD}/sysadm-usermanager.cpp \ - $${PWD}/sysadm-zfs.cpp + $${PWD}/sysadm-zfs.cpp \ + $${PWD}/sysadm-pkg.cpp diff --git a/src/server/library/sysadm-pkg.cpp b/src/server/library/sysadm-pkg.cpp new file mode 100644 index 0000000..5aa7882 --- /dev/null +++ b/src/server/library/sysadm-pkg.cpp @@ -0,0 +1,139 @@ +//=========================================== +// 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-pkg.h" +#include "sysadm-global.h" +#include "globals.h" + +using namespace sysadm; + +// ================== +// INLINE FUNCTIONS +// ================== +//Get Option Name +inline QString option_from_id(QString id){ + QSqlQuery q("SELECT option FROM option WHERE option_id = '"+id+"'"); + while(q.next()){ + return q.value("option").toString(); + } + return ""; //nothing found +} +//Get Annotation (name/value - both use ID's) +inline QString anno_from_id(QString id){ + QSqlQuery q("SELECT annotation FROM annotation WHERE annotation_id = '"+id+"'"); + while(q.next()){ + return q.value("annotation").toString(); + } + return ""; //nothing found +} +//Get origin from package_id (for reverse lookups) +inline QStringList origins_from_package_ids(QStringList ids){ + QSqlQuery q("SELECT origin FROM packages WHERE id = '"+ids.join("' OR id = '")+"'"); + QStringList out; + while(q.next()){ out << q.value("origin").toString(); } + return out; +} +//Generic ID's -> Names function (known databases: users, groups, licenses, shlibs, categories ) +inline QStringList names_from_ids(QStringList ids, QString db){ + QSqlQuery q("SELECT name FROM "+db+" WHERE id = '"+ids.join("' OR id = '")+"'"); + QStringList out; + while(q.next()){ out << q.value("name").toString(); } + return out; +} + +// ================= +// MAIN FUNCTIONS +// ================= +QJsonObject PKG::pkg_info(QStringList origins, QString repo){ + QJsonObject retObj; + //Open the local database + QSqlDatabase DB = QSqlDatabase::addDatabase("QSQLITE"); + DB.setHostName("localhost"); + if(repo=="local"){ DB.setDatabaseName( "/var/db/pkg/local.sqlite"); } + else{ DB.setDatabaseName( "/var/db/pkg/repo-"+repo+".sqlite"); } + DB.setConnectOptions("QSQLITE_OPEN_READONLY=1"); + if( !DB.open() ){ return retObj; } //cannot open database + //Now do all the pkg info, one pkg origin at a time + QSqlQuery query("SELECT * FROM packages" +(origins.isEmpty() ? "" : " WHERE origin = '"+origins.join("' OR origin = '")+"'") ); + //int id = query.record().indexOf("origin"); + while(query.next()){ + QJsonObject info; + QString id = query.value("id").toString(); //need this pkg id for later + QString origin = query.value("origin").toString(); //need the origin for later + //General info + for(int i=0; i +#include "sysadm-global.h" +#include +#include +#include +#include +#include +namespace sysadm{ + +class PKG{ +public: + static QJsonObject pkg_info(QStringList origins, QString repo); +}; + +} //end of sysadm namespace + +#endif \ No newline at end of file diff --git a/src/server/server.pro b/src/server/server.pro index 34259a9..1fabc91 100644 --- a/src/server/server.pro +++ b/src/server/server.pro @@ -2,7 +2,7 @@ TEMPLATE = app LANGUAGE = C++ CONFIG += qt warn_off release -QT = core network websockets concurrent +QT = core network websockets concurrent sql HEADERS += globals.h globals-qt.h \ WebServer.h \