diff --git a/sources/queued-server/src/QueuedServer.cpp b/sources/queued-server/src/QueuedServer.cpp index a0fb50f..200453a 100644 --- a/sources/queued-server/src/QueuedServer.cpp +++ b/sources/queued-server/src/QueuedServer.cpp @@ -50,12 +50,22 @@ void QueuedServer::init() { deinit(); - m_server = new QueuedTcpServer(this); - m_server->listen( - QHostAddress(QueuedCoreAdaptor::getOption("ServerAddress").toString()), - QueuedCoreAdaptor::getOption("ServerPort").toUInt()); + m_server + = new QueuedTcpServer(QueuedCoreAdaptor::getOption( + QueuedConfig::QueuedSettings::ServerTimeout) + .toInt(), + this); + QString address = QueuedCoreAdaptor::getOption( + QueuedConfig::QueuedSettings::ServerAddress) + .toString(); + ushort port + = QueuedCoreAdaptor::getOption(QueuedConfig::QueuedSettings::ServerPort) + .toUInt(); + m_server->listen(QHostAddress(address), port); m_server->setMaxPendingConnections( - QueuedCoreAdaptor::getOption("ServerMaxConnections").toInt()); + QueuedCoreAdaptor::getOption( + QueuedConfig::QueuedSettings::ServerMaxConnections) + .toInt()); qCInfo(LOG_SERV) << "Server listen on" << m_server->serverAddress() << m_server->serverPort(); diff --git a/sources/queued-server/src/QueuedTcpServer.cpp b/sources/queued-server/src/QueuedTcpServer.cpp index d26c09b..ab974b9 100644 --- a/sources/queued-server/src/QueuedTcpServer.cpp +++ b/sources/queued-server/src/QueuedTcpServer.cpp @@ -21,8 +21,9 @@ #include "QueuedTcpServerThread.h" -QueuedTcpServer::QueuedTcpServer(QObject *parent) +QueuedTcpServer::QueuedTcpServer(const int timeout, QObject *parent) : QTcpServer(parent) + , m_timeout(timeout) { qCDebug(LOG_SERV) << __PRETTY_FUNCTION__; } @@ -50,7 +51,7 @@ void QueuedTcpServer::init() void QueuedTcpServer::incomingConnection(qintptr socketDescriptor) { QueuedTcpServerThread *thread - = new QueuedTcpServerThread(socketDescriptor, this); + = new QueuedTcpServerThread(socketDescriptor, m_timeout, this); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); } diff --git a/sources/queued-server/src/QueuedTcpServer.h b/sources/queued-server/src/QueuedTcpServer.h index c34acdb..5fc2d97 100644 --- a/sources/queued-server/src/QueuedTcpServer.h +++ b/sources/queued-server/src/QueuedTcpServer.h @@ -25,7 +25,7 @@ class QueuedTcpServer : public QTcpServer Q_OBJECT public: - explicit QueuedTcpServer(QObject *parent); + explicit QueuedTcpServer(const int timeout, QObject *parent); virtual ~QueuedTcpServer(); void deinit(); void init(); @@ -34,6 +34,7 @@ protected: void incomingConnection(qintptr socketDescriptor) override; private: + int m_timeout = -1; }; diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelper.cpp b/sources/queued-server/src/QueuedTcpServerResponseHelper.cpp index d468a64..4b0d8d2 100644 --- a/sources/queued-server/src/QueuedTcpServerResponseHelper.cpp +++ b/sources/queued-server/src/QueuedTcpServerResponseHelper.cpp @@ -88,10 +88,16 @@ QueuedTcpServerResponseHelper::pathToEnum(const QString &_path) return RequestPath::Plugins; else if (_path == "reports") return RequestPath::Reports; + else if (_path == "status") + return RequestPath::Status; else if (_path == "task") return RequestPath::Task; + else if (_path == "tasks") + return RequestPath::Tasks; else if (_path == "user") return RequestPath::User; + else if (_path == "users") + return RequestPath::Users; return RequestPath::Unknown; } diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelper.h b/sources/queued-server/src/QueuedTcpServerResponseHelper.h index 37e0c4e..3760725 100644 --- a/sources/queued-server/src/QueuedTcpServerResponseHelper.h +++ b/sources/queued-server/src/QueuedTcpServerResponseHelper.h @@ -29,8 +29,11 @@ enum class RequestPath { Permissions, Plugins, Reports, + Status, Task, - User + Tasks, + User, + Users }; typedef struct { int apiVersion; diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelperApi1.cpp b/sources/queued-server/src/QueuedTcpServerResponseHelperApi1.cpp index 46fe232..5aa13ce 100644 --- a/sources/queued-server/src/QueuedTcpServerResponseHelperApi1.cpp +++ b/sources/queued-server/src/QueuedTcpServerResponseHelperApi1.cpp @@ -22,6 +22,8 @@ #include "QueuedTcpServerResponseHelperOption.h" #include "QueuedTcpServerResponseHelperPermissions.h" #include "QueuedTcpServerResponseHelperPlugins.h" +#include "QueuedTcpServerResponseHelperTask.h" +#include "QueuedTcpServerResponseHelperUser.h" QVariantHash QueuedTcpServerResponseHelperApi1::getData( @@ -77,6 +79,78 @@ QVariantHash QueuedTcpServerResponseHelperApi1::getData( else output = {{"code", 405}}; break; + case QueuedTcpServerResponseHelper::RequestPath::Reports: + if (_type == "GET") + output + = QueuedTcpServerResponseHelperUser::getReport(_data, _token); + else + output = {{"code", 405}}; + break; + case QueuedTcpServerResponseHelper::RequestPath::Status: + if (_type == "GET") + output = getStatus(); + else + output = {{"code", 405}}; + break; + case QueuedTcpServerResponseHelper::RequestPath::Task: + if (_type == "GET") + output = QueuedTcpServerResponseHelperTask::getTask( + _arg.toLongLong(), _data); + else if (_type == "POST") + output = QueuedTcpServerResponseHelperTask::addOrEditTask( + _arg.toLongLong(), _data, _token); + else if (_type == "PUT") + output = QueuedTcpServerResponseHelperTask::startOrStopTask( + _arg.toLongLong(), _token); + else + output = {{"code", 405}}; + break; + case QueuedTcpServerResponseHelper::RequestPath::Tasks: + if (_type == "GET") + output = QueuedTcpServerResponseHelperTask::getTasks(_data, _token); + else + output = {{"code", 405}}; + break; + break; + case QueuedTcpServerResponseHelper::RequestPath::User: + if (_type == "GET") + output = QueuedTcpServerResponseHelperUser::getUser(_arg, _data); + else if (_type == "POST") + output = QueuedTcpServerResponseHelperUser::addOrEditUser( + _arg, _data, _token); + else + output = {{"code", 405}}; + break; + case QueuedTcpServerResponseHelper::RequestPath::Users: + if (_type == "GET") + output = QueuedTcpServerResponseHelperUser::getUsers(_data, _token); + else + output = {{"code", 405}}; + break; + case QueuedTcpServerResponseHelper::RequestPath::Unknown: + output = {{"code", 404}}; + break; + } + + return output; +} + + +QVariantHash QueuedTcpServerResponseHelperApi1::getStatus() +{ + QVariantHash output = {{"code", 200}}; + + auto data = QueuedCoreAdaptor::getStatus(); + auto sections = data.keys(); + sections.sort(); + for (auto §ion : sections) { + QVariantHash sectionData; + auto keys = data[section].keys(); + keys.sort(); + for (auto &key : keys) + sectionData[key] = data[section][key]; + // append output + output[section] = sectionData; } return output; diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelperApi1.h b/sources/queued-server/src/QueuedTcpServerResponseHelperApi1.h index dcae4ab..2412167 100644 --- a/sources/queued-server/src/QueuedTcpServerResponseHelperApi1.h +++ b/sources/queued-server/src/QueuedTcpServerResponseHelperApi1.h @@ -27,6 +27,7 @@ namespace QueuedTcpServerResponseHelperApi1 QVariantHash getData(const QueuedTcpServerResponseHelper::RequestPath _request, const QString &_arg, const QString &_type, const QVariantHash &_data, const QString &_token); +QVariantHash getStatus(); }; diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelperPlugins.cpp b/sources/queued-server/src/QueuedTcpServerResponseHelperPlugins.cpp index bdf590b..63bd6f1 100644 --- a/sources/queued-server/src/QueuedTcpServerResponseHelperPlugins.cpp +++ b/sources/queued-server/src/QueuedTcpServerResponseHelperPlugins.cpp @@ -33,9 +33,8 @@ QueuedTcpServerResponseHelperPlugins::addPlugin(const QString &_name, QVariantHash QueuedTcpServerResponseHelperPlugins::listPlugins() { return {{"code", 200}, - {"plugins", - QueuedCoreAdaptor::getOption(QueuedAdvancedSettings::internalId( - QueuedConfig::QueuedSettings::Plugins))}}; + {"plugins", QueuedCoreAdaptor::getOption( + QueuedConfig::QueuedSettings::Plugins)}}; } diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelperTask.cpp b/sources/queued-server/src/QueuedTcpServerResponseHelperTask.cpp new file mode 100644 index 0000000..bfaf891 --- /dev/null +++ b/sources/queued-server/src/QueuedTcpServerResponseHelperTask.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2017 Evgeniy Alekseev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + + +#include "QueuedTcpServerResponseHelperTask.h" + +#include + + +QVariantHash QueuedTcpServerResponseHelperTask::addOrEditTask( + const long long _id, const QVariantHash &_data, const QString &_token) +{ + qCDebug(LOG_SERV) << "Add or edit task" << _id << "with data" << _data; + + auto defs = getDefinitions(_data); + if (_id > 0) { + // edit existing task + bool status = QueuedCoreAdaptor::sendTaskEdit(_id, defs, _token); + return {{"code", status ? 200 : 400}}; + } else { + // add new task + auto id = QueuedCoreAdaptor::sendTaskAdd(defs, _token); + return {{"code", id > 0 ? 200 : 400}, {"id", id}}; + } +} + + +QueuedProcess::QueuedProcessDefinitions +QueuedTcpServerResponseHelperTask::getDefinitions(const QVariantHash &_data) +{ + qCDebug(LOG_SERV) << "Get definitions from" << _data; + + QueuedProcess::QueuedProcessDefinitions defs; + auto args = _data["arguments"].toList(); + for (auto &arg : args) + defs.arguments.append(arg.toString()); + defs.command = _data["command"].toString(); + defs.endTime + = QDateTime::fromString(_data["end"].toString(), Qt::ISODateWithMs); + defs.gid = _data["gid"].toUInt(); + defs.nice = _data["nice"].toUInt(); + defs.startTime + = QDateTime::fromString(_data["start"].toString(), Qt::ISODateWithMs); + defs.uid = _data["uid"].toUInt(); + defs.user = _data["user"].toLongLong(); + defs.workingDirectory = _data["workingDirectory"].toString(); + // limits + QueuedLimits::Limits limits; + limits.cpu = _data["limitCpu"].toLongLong(); + limits.gpu = _data["limitGpu"].toLongLong(); + limits.memory = _data["limitMemory"].toLongLong(); + limits.gpumemory = _data["limitGpumemory"].toLongLong(); + limits.storage = _data["limitStorage"].toLongLong(); + defs.limits = limits.toString(); + + return defs; +} + + +QVariantHash +QueuedTcpServerResponseHelperTask::getTask(const long long _id, + const QVariantHash &_data) +{ + qCDebug(LOG_SERV) << "Get task" << _id << _data; + + auto property = _data["property"].toString(); + + QVariantHash output = {{"code", 200}}; + if (property.isEmpty()) + output["properties"] = QueuedCoreAdaptor::getTask(_id); + else + output["properties"] = QVariantHash( + {{property, QueuedCoreAdaptor::getTask(_id, property)}}); + + return output; +} + + +QVariantHash +QueuedTcpServerResponseHelperTask::getTasks(const QVariantHash &_data, + const QString &_token) +{ + qCDebug(LOG_SERV) << "Get tasks" << _data; + + long long user = _data.value("userId").toLongLong(); + QDateTime start + = QDateTime::fromString(_data["start"].toString(), Qt::ISODateWithMs); + QDateTime stop + = QDateTime::fromString(_data["stop"].toString(), Qt::ISODateWithMs); + + QVariantHash output = {{"code", 200}}; + // some conversion magic + QVariantList outputReport; + auto report = QueuedCoreAdaptor::getTasks(user, start, stop, _token); + for (auto &user : report) + outputReport.append(user); + output["report"] = outputReport; + + return output; +} + + +QVariantHash +QueuedTcpServerResponseHelperTask::startOrStopTask(const long long _id, + const QString &_token) +{ + qCDebug(LOG_SERV) << "Change task state" << _id; + + QVariantHash task = QueuedCoreAdaptor::getTask(_id); + if (task.isEmpty()) + return {{"code", 400}, {"message", "No task found"}}; + + if (task["startTime"].toString().isEmpty() + || !task["endTime"].toString().isEmpty()) + return {{"code", + QueuedCoreAdaptor::sendTaskStart(_id, _token) ? 200 : 400}}; + else + return { + {"code", QueuedCoreAdaptor::sendTaskStop(_id, _token) ? 200 : 400}}; +} diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelperTask.h b/sources/queued-server/src/QueuedTcpServerResponseHelperTask.h new file mode 100644 index 0000000..c1b50de --- /dev/null +++ b/sources/queued-server/src/QueuedTcpServerResponseHelperTask.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Evgeniy Alekseev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + + +#ifndef QUEUEDTCPSERVERRESPONSEHELTASK_H +#define QUEUEDTCPSERVERRESPONSEHELTASK_H + +#include + +#include + + +namespace QueuedTcpServerResponseHelperTask +{ +QVariantHash addOrEditTask(const long long _id, const QVariantHash &_data, + const QString &_token); +QueuedProcess::QueuedProcessDefinitions +getDefinitions(const QVariantHash &_data); +QVariantHash getTask(const long long _id, const QVariantHash &_data); +QVariantHash getTasks(const QVariantHash &_data, const QString &_token); +QVariantHash startOrStopTask(const long long _id, const QString &_token); +}; + + +#endif /* QUEUEDTCPSERVERRESPONSEHELTASK_H */ diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelperUser.cpp b/sources/queued-server/src/QueuedTcpServerResponseHelperUser.cpp new file mode 100644 index 0000000..71f669d --- /dev/null +++ b/sources/queued-server/src/QueuedTcpServerResponseHelperUser.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017 Evgeniy Alekseev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + + +#include "QueuedTcpServerResponseHelperUser.h" + +#include + + +QVariantHash QueuedTcpServerResponseHelperUser::addOrEditUser( + const QString &_user, const QVariantHash &_data, const QString &_token) +{ + qCDebug(LOG_SERV) << "Add user" << _user << "with data" << _data; + + // try define if user exists first + auto userId = QueuedCoreAdaptor::getUserId(_user); + + auto defs = getDefinitions(_data); + defs.name = _user; + if (userId > 0) { + // edit existing user + bool status = QueuedCoreAdaptor::sendUserEdit(userId, defs, _token); + return {{"code", status ? 200 : 400}}; + } else { + // add new user + auto id = QueuedCoreAdaptor::sendUserAdd(defs, _token); + return {{"code", id > 0 ? 200 : 400}, {"id", id}}; + } +} + + +QueuedUser::QueuedUserDefinitions +QueuedTcpServerResponseHelperUser::getDefinitions(const QVariantHash &_data) +{ + qCDebug(LOG_SERV) << "Generate definitions from" << _data; + + QueuedUser::QueuedUserDefinitions defs; + defs.email = _data["email"].toString(); + defs.password = QueuedUser::hashFromPassword(_data["password"].toString()); + defs.permissions = _data["permissions"].toUInt(); + // limits + QueuedLimits::Limits limits; + limits.cpu = _data["limitCpu"].toLongLong(); + limits.gpu = _data["limitGpu"].toLongLong(); + limits.memory = _data["limitMemory"].toLongLong(); + limits.gpumemory = _data["limitGpumemory"].toLongLong(); + limits.storage = _data["limitStorage"].toLongLong(); + defs.limits = limits.toString(); + + return defs; +} + + +QVariantHash +QueuedTcpServerResponseHelperUser::getReport(const QVariantHash &_data, + const QString &_token) +{ + qCDebug(LOG_SERV) << "Get report using payload" << _data; + + QDateTime stop + = QDateTime::fromString(_data["stop"].toString(), Qt::ISODateWithMs); + QDateTime start + = QDateTime::fromString(_data["start"].toString(), Qt::ISODateWithMs); + + QVariantHash output = {{"code", 200}}; + // some conversion magic + QVariantList outputReport; + auto report = QueuedCoreAdaptor::getPerformance(start, stop, _token); + for (auto &user : report) + outputReport.append(user); + output["report"] = outputReport; + + return output; +} + + +QVariantHash +QueuedTcpServerResponseHelperUser::getUser(const QString &_user, + const QVariantHash &_data) +{ + qCDebug(LOG_SERV) << "Get user data for" << _user << _data; + + auto userId = QueuedCoreAdaptor::getUserId(_user); + auto property = _data["property"].toString(); + + QVariantHash output = {{"code", 200}}; + if (property.isEmpty()) + output["properties"] = QueuedCoreAdaptor::getUser(userId); + else + output["properties"] = QVariantHash( + {{property, QueuedCoreAdaptor::getUser(userId, property)}}); + + return output; +} + + +QVariantHash +QueuedTcpServerResponseHelperUser::getUsers(const QVariantHash &_data, + const QString &_token) +{ + qCDebug(LOG_SERV) << "Get users" << _data; + + QDateTime lastLogin = QDateTime::fromString(_data["lastLogged"].toString(), + Qt::ISODateWithMs); + auto permission + = QueuedEnums::stringToPermission(_data["permission"].toString()); + + QVariantHash output = {{"code", 200}}; + // some conversion magic + QVariantList outputReport; + auto report = QueuedCoreAdaptor::getUsers(lastLogin, permission, _token); + for (auto &user : report) + outputReport.append(user); + output["report"] = outputReport; + + return output; +} diff --git a/sources/queued-server/src/QueuedTcpServerResponseHelperUser.h b/sources/queued-server/src/QueuedTcpServerResponseHelperUser.h new file mode 100644 index 0000000..200d580 --- /dev/null +++ b/sources/queued-server/src/QueuedTcpServerResponseHelperUser.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Evgeniy Alekseev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + + +#ifndef QUEUEDTCPSERVERRESPONSEHELUSER_H +#define QUEUEDTCPSERVERRESPONSEHELUSER_H + +#include + +#include + + +namespace QueuedTcpServerResponseHelperUser +{ +QVariantHash addOrEditUser(const QString &_user, const QVariantHash &_data, + const QString &_token); +QueuedUser::QueuedUserDefinitions getDefinitions(const QVariantHash &_data); +QVariantHash getReport(const QVariantHash &_data, const QString &_token); +QVariantHash getUser(const QString &_user, const QVariantHash &_data); +QVariantHash getUsers(const QVariantHash &_data, const QString &_token); +}; + + +#endif /* QUEUEDTCPSERVERRESPONSEHELUSER_H */ diff --git a/sources/queued-server/src/QueuedTcpServerThread.cpp b/sources/queued-server/src/QueuedTcpServerThread.cpp index 3c242e1..eab8a34 100644 --- a/sources/queued-server/src/QueuedTcpServerThread.cpp +++ b/sources/queued-server/src/QueuedTcpServerThread.cpp @@ -28,9 +28,10 @@ QueuedTcpServerThread::QueuedTcpServerThread(int socketDescriptor, - QObject *parent) + const int timeout, QObject *parent) : QThread(parent) , m_socketDescriptor(socketDescriptor) + , m_timeout(timeout) { qCDebug(LOG_SERV) << __PRETTY_FUNCTION__; } @@ -39,6 +40,9 @@ QueuedTcpServerThread::QueuedTcpServerThread(int socketDescriptor, QueuedTcpServerThread::~QueuedTcpServerThread() { qCDebug(LOG_SERV) << __PRETTY_FUNCTION__; + + if (m_socket) + m_socket->deleteLater(); } @@ -133,7 +137,7 @@ QueuedTcpServerThread::QueuedTcpServerRequest QueuedTcpServerThread::getRequest( values = QVariantList({request.data[key]}); break; } - values.append(key); + values.append(value); request.data[key] = values.count() == 1 ? values.first() : values; } @@ -182,7 +186,7 @@ QueuedTcpServerThread::response(const QueuedTcpServerRequest &request) const void QueuedTcpServerThread::run() { - m_socket = new QTcpSocket(this); + m_socket = new QTcpSocket(nullptr); if (!m_socket->setSocketDescriptor(m_socketDescriptor)) { qCWarning(LOG_SERV) << "Socket error" << m_socket->error(); return; @@ -190,20 +194,11 @@ void QueuedTcpServerThread::run() connect(m_socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection); - connect(m_socket, SIGNAL(disconnected()), this, SLOT(disconnected()), - Qt::DirectConnection); exec(); } -void QueuedTcpServerThread::disconnected() -{ - m_socket->deleteLater(); - exit(0); -} - - void QueuedTcpServerThread::readyRead() { QStringList headers; @@ -222,8 +217,12 @@ void QueuedTcpServerThread::readyRead() m_socket->write(resp); m_socket->flush(); - m_socket->waitForBytesWritten(3000); + // TODO use timeouts? + if (m_socket->state() != QAbstractSocket::UnconnectedState) + m_socket->waitForBytesWritten(m_timeout); m_socket->disconnectFromHost(); if (m_socket->state() != QAbstractSocket::UnconnectedState) m_socket->waitForDisconnected(); + + exit(0); } diff --git a/sources/queued-server/src/QueuedTcpServerThread.h b/sources/queued-server/src/QueuedTcpServerThread.h index 4dadff3..14cfd12 100644 --- a/sources/queued-server/src/QueuedTcpServerThread.h +++ b/sources/queued-server/src/QueuedTcpServerThread.h @@ -44,7 +44,8 @@ public: QVariantHash data; } QueuedTcpServerResponse; - explicit QueuedTcpServerThread(int socketDescriptor, QObject *parent); + explicit QueuedTcpServerThread(int socketDescriptor, const int timeout, + QObject *parent); virtual ~QueuedTcpServerThread(); static QByteArrayList defaultResponse(const int code, const QVariantHash &json); @@ -56,12 +57,12 @@ public: void run() override; private slots: - void disconnected(); void readyRead(); private: QTcpSocket *m_socket = nullptr; int m_socketDescriptor; + int m_timeout = -1; }; diff --git a/sources/queued/include/queued/QueuedCoreAdaptor.h b/sources/queued/include/queued/QueuedCoreAdaptor.h index 1f297f6..515e58f 100644 --- a/sources/queued/include/queued/QueuedCoreAdaptor.h +++ b/sources/queued/include/queued/QueuedCoreAdaptor.h @@ -28,6 +28,7 @@ #include #include "QueuedProcess.h" +#include "QueuedStaticConfig.h" #include "QueuedUser.h" @@ -183,6 +184,13 @@ bool sendUserPermissionRemove(const long long _id, * @return option value */ QVariant getOption(const QString &_property); +/** + * @brief get option + * @param _property + * option name + * @return option value + */ +QVariant getOption(const QueuedConfig::QueuedSettings _property); /** * @brief performance report * @param _from @@ -195,6 +203,18 @@ QVariant getOption(const QString &_property); */ QList getPerformance(const QDateTime &_from, const QDateTime &_to, const QString &_token); +/** + * @brief server status + * @return server status information + */ +QHash> getStatus(); +/** + * @brief get all task properties + * @param _id + * task ID + * @return task properties + */ +QVariantHash getTask(const long long _id); /** * @brief get task property * @param _id @@ -218,6 +238,13 @@ QVariant getTask(const long long _id, const QString &_property); */ QList getTasks(const long long _user, const QDateTime &_from, const QDateTime &_to, const QString &_token); +/** + * @brief get user properties + * @param _id + * user id + * @return user properties + */ +QVariantHash getUser(const long long _id); /** * @brief get user property * @param _id @@ -227,6 +254,14 @@ QList getTasks(const long long _user, const QDateTime &_from, * @return user property value */ QVariant getUser(const long long _id, const QString &_property); +/** + * @brief get user ID + * @param _name + * user name + * @return user ID or {0, -1} if no user found. If _name is numeric value it + * returns converted one + */ +long long getUserId(const QString &_name); /** * @brief get users list * @param _lastLogged @@ -240,13 +275,6 @@ QVariant getUser(const long long _id, const QString &_property); QList getUsers(const QDateTime &_lastLogged, const QueuedEnums::Permission _permission, const QString &_token); -/** - * @brief get user ID - * @param _name - * user name - * @return user ID or {0, -1} if no user found - */ -long long getUserId(const QString &_name); // common methods /** * @brief common DBus request diff --git a/sources/queued/include/queued/QueuedDebug.h b/sources/queued/include/queued/QueuedDebug.h index afc8cb3..06277b0 100644 --- a/sources/queued/include/queued/QueuedDebug.h +++ b/sources/queued/include/queued/QueuedDebug.h @@ -24,6 +24,7 @@ #ifndef QUEUEDDEBUG_H #define QUEUEDDEBUG_H +#include #include @@ -78,6 +79,10 @@ void enableDebug(); * @brief additional method to get build details declared in version.h */ QStringList getBuildData(); +/** + * @brief additional method to get build details declared in version.h + */ +QHash> getBuildMetaData(); } diff --git a/sources/queued/include/queued/QueuedReportInterface.h b/sources/queued/include/queued/QueuedReportInterface.h index 0d74df9..3a2d76f 100644 --- a/sources/queued/include/queued/QueuedReportInterface.h +++ b/sources/queued/include/queued/QueuedReportInterface.h @@ -65,6 +65,11 @@ public slots: */ QDBusVariant Performance(const QString &from, const QString &to, const QString &token); + /** + * @brief server status + * @return server status + */ + QDBusVariant Status(); /** * @brief tasks list * @param user diff --git a/sources/queued/include/queued/QueuedStaticConfig.h b/sources/queued/include/queued/QueuedStaticConfig.h index 844ab39..740d276 100644 --- a/sources/queued/include/queued/QueuedStaticConfig.h +++ b/sources/queued/include/queued/QueuedStaticConfig.h @@ -98,10 +98,12 @@ typedef struct { * plugin list * @var QueuedSettings::ServerAddress * queued server bind address - * @var QueuedSettings::ServerPort - * queued server bind port * @var QueuedSettings::ServerMaxConnections * queued server max connections + * @var QueuedSettings::ServerPort + * queued server bind port + * @var QueuedSettings::ServerTimeout + * server thread timeout */ enum class QueuedSettings { Invalid, @@ -115,8 +117,9 @@ enum class QueuedSettings { ProcessCommandLine, Plugins, ServerAddress, + ServerMaxConnections, ServerPort, - ServerMaxConnections + ServerTimeout }; /** * @struct QueuedSettingsField @@ -138,24 +141,26 @@ typedef QHash QueuedSettingsDefaultMap; /** * @brief default settings map */ -const QueuedSettingsDefaultMap QueuedSettingsDefaults - = {{"", {QueuedSettings::Invalid, QVariant()}}, - {"DatabaseInterval", {QueuedSettings::DatabaseInterval, 86400000}}, - {"DefaultLimits", {QueuedSettings::DefaultLimits, "0\n0\n0\n0\n0"}}, - {"KeepTasks", {QueuedSettings::KeepTasks, 0}}, - {"KeepUsers", {QueuedSettings::KeepUsers, 0}}, - {"OnExitAction", {QueuedSettings::OnExitAction, 2}}, - {"TokenExpiration", {QueuedSettings::TokenExpiration, 30}}, - {"DatabaseVersion", - {QueuedSettings::DatabaseVersion, QueuedConfig::DATABASE_VERSION}}, - {"ProcessCommandLine", - {QueuedSettings::ProcessCommandLine, - "systemd-run\n--scope\n--unit={name}\n--uid={uid}\n--gid={gid}" - "\n-p\nCPUQuota={cpu}%\n-p\nMemoryHigh={memory}\n{application}"}}, - {"Plugins", {QueuedSettings::Plugins, ""}}, - {"ServerAddress", {QueuedSettings::ServerAddress, ""}}, - {"ServerPort", {QueuedSettings::ServerPort, 8080}}, - {"ServerMaxConnections", {QueuedSettings::ServerMaxConnections, 30}}}; +const QueuedSettingsDefaultMap QueuedSettingsDefaults = { + {"", {QueuedSettings::Invalid, QVariant()}}, + {"DatabaseInterval", {QueuedSettings::DatabaseInterval, 86400000}}, + {"DefaultLimits", {QueuedSettings::DefaultLimits, "0\n0\n0\n0\n0"}}, + {"KeepTasks", {QueuedSettings::KeepTasks, 0}}, + {"KeepUsers", {QueuedSettings::KeepUsers, 0}}, + {"OnExitAction", {QueuedSettings::OnExitAction, 2}}, + {"TokenExpiration", {QueuedSettings::TokenExpiration, 30}}, + {"DatabaseVersion", + {QueuedSettings::DatabaseVersion, QueuedConfig::DATABASE_VERSION}}, + {"ProcessCommandLine", + {QueuedSettings::ProcessCommandLine, + "systemd-run\n--scope\n--unit={name}\n--uid={uid}\n--gid={gid}" + "\n-p\nCPUQuota={cpu}%\n-p\nMemoryHigh={memory}\n{application}"}}, + {"Plugins", {QueuedSettings::Plugins, ""}}, + {"ServerAddress", {QueuedSettings::ServerAddress, ""}}, + {"ServerMaxConnections", {QueuedSettings::ServerMaxConnections, 30}}, + {"ServerPort", {QueuedSettings::ServerPort, 8080}}, + {"ServerTimeout", {QueuedSettings::ServerTimeout, -1}}, +}; }; #endif /* QUEUEDCONFIGURATION_H */ diff --git a/sources/queued/src/QueuedCore.cpp b/sources/queued/src/QueuedCore.cpp index 2439bc4..e8a81ac 100644 --- a/sources/queued/src/QueuedCore.cpp +++ b/sources/queued/src/QueuedCore.cpp @@ -667,8 +667,9 @@ void QueuedCore::updateSettings(const QueuedConfig::QueuedSettings _id, m_processes->setProcessLine(_value.toString()); break; case QueuedConfig::QueuedSettings::ServerAddress: - case QueuedConfig::QueuedSettings::ServerPort: case QueuedConfig::QueuedSettings::ServerMaxConnections: + case QueuedConfig::QueuedSettings::ServerPort: + case QueuedConfig::QueuedSettings::ServerTimeout: // do nothing here break; case QueuedConfig::QueuedSettings::TokenExpiration: @@ -958,12 +959,11 @@ long long QueuedCore::addUserPrivate(const QString &_name, qCDebug(LOG_LIB) << "Add user" << _name << "with email" << _email << "and permissions" << _permissions; // add to database - QVariantHash properties - = {{"name", _name}, - {"password", QueuedUser::hashFromPassword(_password)}, - {"email", _email}, - {"permissions", _permissions}, - {"limits", _limits.toString()}}; + QVariantHash properties = {{"name", _name}, + {"password", _password}, + {"email", _email}, + {"permissions", _permissions}, + {"limits", _limits.toString()}}; auto id = m_database->add(QueuedDB::USERS_TABLE, properties); if (id == -1) { qCWarning(LOG_LIB) << "Could not add user" << _name; diff --git a/sources/queued/src/QueuedCoreAdaptor.cpp b/sources/queued/src/QueuedCoreAdaptor.cpp index cee073e..6604fc7 100644 --- a/sources/queued/src/QueuedCoreAdaptor.cpp +++ b/sources/queued/src/QueuedCoreAdaptor.cpp @@ -313,6 +313,18 @@ QVariant QueuedCoreAdaptor::getOption(const QString &_property) } +/** + * @fn getOption + */ +QVariant +QueuedCoreAdaptor::getOption(const QueuedConfig::QueuedSettings _property) +{ + qCDebug(LOG_DBUS) << "Get option" << static_cast(_property); + + return getOption(QueuedAdvancedSettings::internalId(_property)); +} + + /** * @fn getPerformance */ @@ -324,13 +336,33 @@ QList QueuedCoreAdaptor::getPerformance(const QDateTime &_from, QVariantList args = {_from.toString(Qt::ISODateWithMs), _to.toString(Qt::ISODateWithMs), _token}; - return qdbus_cast>( - toNativeType(sendRequest(QueuedConfig::DBUS_SERVICE, - QueuedConfig::DBUS_REPORTS_PATH, - QueuedConfig::DBUS_SERVICE, "Performance", - args) - .first()) - .value()); + return qdbus_cast>(toNativeType( + sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_REPORTS_PATH, + QueuedConfig::DBUS_SERVICE, "Performance", args) + .first())); +} + + +/** + * @fn getStatus + */ +QHash> QueuedCoreAdaptor::getStatus() +{ + return qdbus_cast>>(toNativeType( + sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_REPORTS_PATH, + QueuedConfig::DBUS_SERVICE, "Status", {}) + .first())); +} + + +/** + * @fn getTask + */ +QVariantHash QueuedCoreAdaptor::getTask(const long long _id) +{ + qCDebug(LOG_DBUS) << "Get task properties" << _id; + + return qdbus_cast(getTask(_id, "")); } @@ -362,12 +394,21 @@ QList QueuedCoreAdaptor::getTasks(const long long _user, QVariantList args = {_user, _from.toString(Qt::ISODateWithMs), _to.toString(Qt::ISODateWithMs), _token}; - return qdbus_cast>( - toNativeType(sendRequest(QueuedConfig::DBUS_SERVICE, - QueuedConfig::DBUS_REPORTS_PATH, - QueuedConfig::DBUS_SERVICE, "Tasks", args) - .first()) - .value()); + return qdbus_cast>(toNativeType( + sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_REPORTS_PATH, + QueuedConfig::DBUS_SERVICE, "Tasks", args) + .first())); +} + + +/** + * @fn getUser + */ +QVariantHash QueuedCoreAdaptor::getUser(const long long _id) +{ + qCDebug(LOG_DBUS) << "Get user property" << _id; + + return qdbus_cast(getUser(_id, "")); } @@ -387,6 +428,27 @@ QVariant QueuedCoreAdaptor::getUser(const long long _id, } +/** + * @fn getUserId + */ +long long QueuedCoreAdaptor::getUserId(const QString &_name) +{ + qCDebug(LOG_DBUS) << "Get user ID for" << _name; + + bool status = false; + long long stringToLong = _name.toLongLong(&status); + if (status) + return stringToLong; + + QVariantList args = {_name}; + return sendRequest(QueuedConfig::DBUS_SERVICE, + QueuedConfig::DBUS_PROPERTY_PATH, + QueuedConfig::DBUS_SERVICE, "UserIdByName", args) + .first() + .toLongLong(); +} + + /** * @fn getUsers */ @@ -400,28 +462,10 @@ QueuedCoreAdaptor::getUsers(const QDateTime &_lastLogged, QVariantList args = {_lastLogged.toString(Qt::ISODateWithMs), static_cast(_permission), _token}; - return qdbus_cast>( - toNativeType(sendRequest(QueuedConfig::DBUS_SERVICE, - QueuedConfig::DBUS_REPORTS_PATH, - QueuedConfig::DBUS_SERVICE, "Users", args) - .first()) - .value()); -} - - -/** - * @fn getUserId - */ -long long QueuedCoreAdaptor::getUserId(const QString &_name) -{ - qCDebug(LOG_DBUS) << "Get user ID for" << _name; - - QVariantList args = {_name}; - return sendRequest(QueuedConfig::DBUS_SERVICE, - QueuedConfig::DBUS_PROPERTY_PATH, - QueuedConfig::DBUS_SERVICE, "UserIdByName", args) - .first() - .toLongLong(); + return qdbus_cast>(toNativeType( + sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_REPORTS_PATH, + QueuedConfig::DBUS_SERVICE, "Users", args) + .first())); } diff --git a/sources/queued/src/QueuedDebug.cpp b/sources/queued/src/QueuedDebug.cpp index eae3b24..540a1c0 100644 --- a/sources/queued/src/QueuedDebug.cpp +++ b/sources/queued/src/QueuedDebug.cpp @@ -59,81 +59,102 @@ QStringList QueuedDebug::getBuildData() { QStringList metadata; - // general information - metadata += "Build details"; - metadata += QString("\tVERSION: %1").arg(VERSION); - metadata += QString("\tCOMMIT_SHA: %1").arg(COMMIT_SHA); - metadata += QString("\tBUILD_DATE: %1").arg(BUILD_DATE); - - // api - metadata += "API"; - metadata += QString("\tDATABASE_VERSION: %1") - .arg(QueuedConfig::DATABASE_VERSION); - metadata += QString("\tPLUGIN_INTERFACE: %1") - .arg(QueuedConfig::PLUGIN_INTERFACE); - - // paths - metadata += "Paths"; - metadata - += QString("\tBIN_INSTALL_DIR: %1").arg(QueuedConfig::BIN_INSTALL_DIR); - metadata += QString("\tDATA_INSTALL_DIR: %1") - .arg(QueuedConfig::DATA_INSTALL_DIR); - metadata += QString("\tINCLUDE_INSTALL_DIR: %1") - .arg(QueuedConfig::INCLUDE_INSTALL_DIR); - metadata - += QString("\tLIB_INSTALL_DIR: %1").arg(QueuedConfig::LIB_INSTALL_DIR); - metadata += QString("\tROOT_INSTALL_DIR: %1") - .arg(QueuedConfig::ROOT_INSTALL_DIR); - metadata += QString("\tHOME_PATH: %1").arg(QueuedConfig::HOME_PATH); - metadata += QString("\tPLUGIN_PATH: %1").arg(QueuedConfig::PLUGIN_PATH); - - // dbus - metadata += "DBus"; - metadata += QString("\tDBUS_SERVICE: %1").arg(QueuedConfig::DBUS_SERVICE); - metadata += QString("\tDBUS_APPLICATION_PATH: %1") - .arg(QueuedConfig::DBUS_APPLICATION_PATH); - metadata += QString("\tDBUS_OBJECT_PATH: %1") - .arg(QueuedConfig::DBUS_OBJECT_PATH); - metadata += QString("\tDBUS_PROPERTY_PATH: %1") - .arg(QueuedConfig::DBUS_PROPERTY_PATH); - - // cmake build information - metadata += "Cmake properties"; - metadata += QString("\tCMAKE_BUILD_TYPE: %1").arg(CMAKE_BUILD_TYPE); - metadata += QString("\tCMAKE_CXX_COMPILER: %1").arg(CMAKE_CXX_COMPILER); - metadata += QString("\tCMAKE_CXX_FLAGS: %1").arg(CMAKE_CXX_FLAGS); - metadata - += QString("\tCMAKE_CXX_FLAGS_DEBUG: %1").arg(CMAKE_CXX_FLAGS_DEBUG); - metadata += QString("\tCMAKE_CXX_FLAGS_RELEASE: %1") - .arg(CMAKE_CXX_FLAGS_RELEASE); - metadata += QString("\tCMAKE_CXX_FLAGS_OPTIMIZATION: %1") - .arg(CMAKE_CXX_FLAGS_OPTIMIZATION); - metadata += QString("\tCMAKE_DEFINITIONS: %1").arg(CMAKE_DEFINITIONS); - metadata += QString("\tCMAKE_INSTALL_PREFIX: %1").arg(CMAKE_INSTALL_PREFIX); - metadata += QString("\tCMAKE_MODULE_LINKER_FLAGS: %1") - .arg(CMAKE_MODULE_LINKER_FLAGS); - metadata += QString("\tCMAKE_SHARED_LINKER_FLAGS: %1") - .arg(CMAKE_SHARED_LINKER_FLAGS); - - // components - metadata += "Components"; - metadata += QString("\tBUILD_DEB_PACKAGE: %1").arg(BUILD_DEB_PACKAGE); - metadata += QString("\tBUILD_RPM_PACKAGE: %1").arg(BUILD_RPM_PACKAGE); - metadata - += QString("\tCLANGFORMAT_EXECUTABLE: %1").arg(CLANGFORMAT_EXECUTABLE); - metadata += QString("\tCOVERITY_COMMENT: %1").arg(COVERITY_COMMENT); - metadata += QString("\tCOVERITY_DIRECTORY: %1").arg(COVERITY_DIRECTORY); - metadata += QString("\tCOVERITY_EMAIL: %1").arg(COVERITY_EMAIL); - metadata += QString("\tCOVERITY_EXECUTABLE: %1").arg(COVERITY_EXECUTABLE); - metadata += QString("\tCOVERITY_URL: %1").arg(COVERITY_URL); - metadata += QString("\tCPPCHECK_EXECUTABLE: %1").arg(CPPCHECK_EXECUTABLE); - - // additional properties - metadata += "Additional properties"; - metadata += QString("\tPROP_DOCS: %1").arg(PROP_DOCS); - metadata += QString("\tPROP_FUTURE: %1").arg(PROP_FUTURE); - metadata += QString("\tPROP_LOAD: %1").arg(PROP_LOAD); - metadata += QString("\tPROP_TEST: %1").arg(PROP_TEST); + auto data = getBuildMetaData(); + auto sections = data.keys(); + sections.sort(); + for (auto §ion : sections) { + metadata += section; + auto keys = data[section].keys(); + keys.sort(); + for (auto &key : keys) + metadata += QString("\t%1: %2").arg(key).arg(data[section][key]); + } return metadata; } + + +/** + * @fn getBuildMetaData + */ +QHash> QueuedDebug::getBuildMetaData() +{ + return {// general information + {"Build details", + { + {"VERSION", VERSION}, + {"COMMIT_SHA", COMMIT_SHA}, + {"BUILD_DATE", BUILD_DATE}, + {"QT_VERSION", qVersion()}, + }}, + // api + {"API", + { + {"DATABASE_VERSION", + QString::number(QueuedConfig::DATABASE_VERSION)}, + {"PLUGIN_INTERFACE", QueuedConfig::PLUGIN_INTERFACE}, + {"WEBAPI_TOKEN_HEADER", QueuedConfig::WEBAPI_TOKEN_HEADER}, + {"WEBAPI_VERSIONS", + std::accumulate( + std::next(std::begin(QueuedConfig::WEBAPI_VERSIONS)), + std::end(QueuedConfig::WEBAPI_VERSIONS), + QString::number(QueuedConfig::WEBAPI_VERSIONS[0]), + [](const QString str, const int version) { + return QString("%1,%2").arg(str).arg(version); + })}, + }}, + // paths + {"Paths", + { + {"BIN_INSTALL_DIR", QueuedConfig::BIN_INSTALL_DIR}, + {"DATA_INSTALL_DIR", QueuedConfig::DATA_INSTALL_DIR}, + {"INCLUDE_INSTALL_DIR", QueuedConfig::INCLUDE_INSTALL_DIR}, + {"LIB_INSTALL_DIR", QueuedConfig::LIB_INSTALL_DIR}, + {"ROOT_INSTALL_DIR", QueuedConfig::ROOT_INSTALL_DIR}, + {"HOME_PATH", QueuedConfig::HOME_PATH}, + {"PLUGIN_PATH", QueuedConfig::PLUGIN_PATH}, + }}, + // dbus + {"DBus", + { + {"DBUS_SERVICE", QueuedConfig::DBUS_SERVICE}, + {"DBUS_APPLICATION_PATH", QueuedConfig::DBUS_APPLICATION_PATH}, + {"DBUS_OBJECT_PATH", QueuedConfig::DBUS_OBJECT_PATH}, + {"DBUS_PROPERTY_PATH", QueuedConfig::DBUS_PROPERTY_PATH}, + }}, + // cmake build information + {"Cmake properties", + { + {"CMAKE_BUILD_TYPE", CMAKE_BUILD_TYPE}, + {"CMAKE_CXX_COMPILER", CMAKE_CXX_COMPILER}, + {"CMAKE_CXX_FLAGS", CMAKE_CXX_FLAGS}, + {"CMAKE_CXX_FLAGS_DEBUG", CMAKE_CXX_FLAGS_DEBUG}, + {"CMAKE_CXX_FLAGS_RELEASE", CMAKE_CXX_FLAGS_RELEASE}, + {"CMAKE_CXX_FLAGS_OPTIMIZATION", CMAKE_CXX_FLAGS_OPTIMIZATION}, + {"CMAKE_DEFINITIONS", CMAKE_DEFINITIONS}, + {"CMAKE_INSTALL_PREFIX", CMAKE_INSTALL_PREFIX}, + {"CMAKE_MODULE_LINKER_FLAGS", CMAKE_MODULE_LINKER_FLAGS}, + {"CMAKE_SHARED_LINKER_FLAGS", CMAKE_SHARED_LINKER_FLAGS}, + }}, + // components + {"Components", + { + {"BUILD_DEB_PACKAGE", BUILD_DEB_PACKAGE}, + {"BUILD_RPM_PACKAGE", BUILD_RPM_PACKAGE}, + {"CLANGFORMAT_EXECUTABLE", CLANGFORMAT_EXECUTABLE}, + {"COVERITY_COMMENT", COVERITY_COMMENT}, + {"COVERITY_DIRECTORY", COVERITY_DIRECTORY}, + {"COVERITY_EMAIL", COVERITY_EMAIL}, + {"COVERITY_EXECUTABLE", COVERITY_EXECUTABLE}, + {"COVERITY_URL", COVERITY_URL}, + {"CPPCHECK_EXECUTABLE", CPPCHECK_EXECUTABLE}, + }}, + // additional properties + {"Additional properties", + { + {"PROP_DOCS", PROP_DOCS}, + {"PROP_FUTURE", PROP_FUTURE}, + {"PROP_LOAD", PROP_LOAD}, + {"PROP_TEST", PROP_TEST}, + }}}; +} diff --git a/sources/queued/src/QueuedProcess.cpp b/sources/queued/src/QueuedProcess.cpp index d15d42b..8c10945 100644 --- a/sources/queued/src/QueuedProcess.cpp +++ b/sources/queued/src/QueuedProcess.cpp @@ -24,6 +24,9 @@ #include #include +#include + +#include /** @@ -385,10 +388,14 @@ void QueuedProcess::setWorkDirectory(const QString &_workDirectory) { qCDebug(LOG_LIB) << "Set working directory to" << _workDirectory; - m_definitions.workingDirectory = _workDirectory; + m_definitions.workingDirectory + = _workDirectory.isEmpty() + ? QStandardPaths::writableLocation( + QStandardPaths::StandardLocation::TempLocation) + : _workDirectory; setLogError(""); setLogOutput(""); - setWorkingDirectory(_workDirectory); + setWorkingDirectory(m_definitions.workingDirectory); } diff --git a/sources/queued/src/QueuedProcessManager.cpp b/sources/queued/src/QueuedProcessManager.cpp index 147a318..6fed78a 100644 --- a/sources/queued/src/QueuedProcessManager.cpp +++ b/sources/queued/src/QueuedProcessManager.cpp @@ -315,29 +315,21 @@ QueuedLimits::Limits QueuedProcessManager::usedLimits() long long cpu = std::accumulate( tasks.cbegin(), tasks.cend(), 0, [](long long value, QueuedProcess *process) { + auto limit = process->nativeLimits().cpu == 0 + ? QueuedSystemInfo::cpuCount() + : process->nativeLimits().cpu; return process->state() == QProcess::ProcessState::Running - ? value + process->nativeLimits().cpu - : value; - }); - long long gpu = std::accumulate( - tasks.cbegin(), tasks.cend(), 0, - [](long long value, QueuedProcess *process) { - return process->state() == QProcess::ProcessState::Running - ? value + process->nativeLimits().gpu + ? value + limit : value; }); long long memory = std::accumulate( tasks.cbegin(), tasks.cend(), 0, [](long long value, QueuedProcess *process) { + auto limit = process->nativeLimits().memory == 0 + ? QueuedSystemInfo::memoryCount() + : process->nativeLimits().memory; return process->state() == QProcess::ProcessState::Running - ? value + process->nativeLimits().memory - : value; - }); - long long gpumemory = std::accumulate( - tasks.cbegin(), tasks.cend(), 0, - [](long long value, QueuedProcess *process) { - return process->state() == QProcess::ProcessState::Running - ? value + process->nativeLimits().gpumemory + ? value + limit : value; }); long long storage = std::accumulate( @@ -348,7 +340,7 @@ QueuedLimits::Limits QueuedProcessManager::usedLimits() : value; }); - return QueuedLimits::Limits(cpu, gpu, memory, gpumemory, storage); + return QueuedLimits::Limits(cpu, 0, memory, 0, storage); } diff --git a/sources/queued/src/QueuedPropertyInterface.cpp b/sources/queued/src/QueuedPropertyInterface.cpp index 9d53a2c..a1d7c5b 100644 --- a/sources/queued/src/QueuedPropertyInterface.cpp +++ b/sources/queued/src/QueuedPropertyInterface.cpp @@ -56,7 +56,8 @@ QDBusVariant QueuedPropertyInterface::Option(const QString &property) { qCDebug(LOG_DBUS) << "Get property" << property; - return QDBusVariant(m_core->option(property)); + auto response = m_core->option(property); + return QDBusVariant(response.isValid() ? response : ""); } @@ -71,14 +72,18 @@ QDBusVariant QueuedPropertyInterface::Task(const long long id, auto task = m_core->task(id); if (!task) { qCWarning(LOG_DBUS) << "Could not find task" << id; - return QDBusVariant(); + return QDBusVariant(""); } - if (property.isEmpty()) - return QDBusVariant( - QVariant::fromValue(getProperties(task))); - else - return QDBusVariant(task->property(qPrintable(property))); + if (property.isEmpty()) { + auto response = QVariant::fromValue(getProperties(task)); + return QDBusVariant(response); + } else { + auto response = task->property(qPrintable(property)); + if (response.type() == QVariant::DateTime) + response = response.toDateTime().toString(Qt::ISODateWithMs); + return QDBusVariant(response.isValid() ? response : ""); + } } @@ -93,14 +98,18 @@ QDBusVariant QueuedPropertyInterface::User(const long long id, auto user = m_core->user(id); if (!user) { qCWarning(LOG_DBUS) << "Could not find user" << id; - return QDBusVariant(); + return QDBusVariant(""); } - if (property.isEmpty()) - return QDBusVariant( - QVariant::fromValue(getProperties(user))); - else - return QDBusVariant(user->property(qPrintable(property))); + if (property.isEmpty()) { + auto response = QVariant::fromValue(getProperties(user)); + return QDBusVariant(response); + } else { + auto response = user->property(qPrintable(property)); + if (response.type() == QVariant::DateTime) + response = response.toDateTime().toString(Qt::ISODateWithMs); + return QDBusVariant(response.isValid() ? response : ""); + } } @@ -138,6 +147,9 @@ QVariantHash QueuedPropertyInterface::getProperties(const QObject *_object) if (QString(name) == "objectName") continue; result[name] = _object->property(name); + if (result[name].type() == QVariant::DateTime) + result[name] + = result[name].toDateTime().toString(Qt::ISODateWithMs); } return result; diff --git a/sources/queued/src/QueuedReportInterface.cpp b/sources/queued/src/QueuedReportInterface.cpp index 068c9aa..d5b9e75 100644 --- a/sources/queued/src/QueuedReportInterface.cpp +++ b/sources/queued/src/QueuedReportInterface.cpp @@ -38,8 +38,16 @@ QueuedReportInterface::QueuedReportInterface(QueuedCore *parent) { qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__; + // QList qRegisterMetaType>("QList"); qDBusRegisterMetaType>(); + // QHash + qRegisterMetaType>("QHash"); + qDBusRegisterMetaType>(); + // QHash> + qRegisterMetaType>>( + "QHash>"); + qDBusRegisterMetaType>>(); } @@ -68,6 +76,19 @@ QDBusVariant QueuedReportInterface::Performance(const QString &from, } +/** + * @fn Status + */ +QDBusVariant QueuedReportInterface::Status() +{ + auto metadata = QueuedDebug::getBuildMetaData(); + // append metadata here + + return QDBusVariant( + QVariant::fromValue>>(metadata)); +} + + /** * @fn Tasks */ diff --git a/sources/queued/src/QueuedReportManager.cpp b/sources/queued/src/QueuedReportManager.cpp index a4c137a..2a9b800 100644 --- a/sources/queued/src/QueuedReportManager.cpp +++ b/sources/queued/src/QueuedReportManager.cpp @@ -143,7 +143,7 @@ QList QueuedReportManager::tasks(const long long _user, qCDebug(LOG_LIB) << "Search for tasks in" << _user << _from << _to; QStringList conditions; - if (_user != -1) + if (_user > 0) conditions += QString("(user = %1)").arg(_user); if (_from.isValid()) conditions += QString("((datetime(startTime) > datetime('%1')) OR " diff --git a/sources/queuedctl/src/QueuedctlCommon.cpp b/sources/queuedctl/src/QueuedctlCommon.cpp index 2d6e0ed..468bd8a 100644 --- a/sources/queuedctl/src/QueuedctlCommon.cpp +++ b/sources/queuedctl/src/QueuedctlCommon.cpp @@ -55,6 +55,27 @@ QString QueuedctlCommon::commandsHelp() } +QString QueuedctlCommon::hashHashToString( + const QHash> &_hash) +{ + qCDebug(LOG_APP) << "Convert hash to string" << _hash; + + QStringList output; + + QStringList groups = _hash.keys(); + groups.sort(); + for (auto &group : groups) { + output += group; + QStringList keys = _hash[group].keys(); + keys.sort(); + for (auto &key : keys) + output += QString("\t%1: %2").arg(key).arg(_hash[group][key]); + } + + return output.join('\n'); +} + + QString QueuedctlCommon::hashToString(const QVariantHash &_hash) { qCDebug(LOG_APP) << "Convert hash to string" << _hash; @@ -136,6 +157,8 @@ void QueuedctlCommon::preprocess(const QStringList &_args, case QueuedctlArgument::Report: QueuedctlUser::parserReport(_parser); break; + case QueuedctlArgument::Status: + break; case QueuedctlArgument::TaskAdd: QueuedctlTask::parserAdd(_parser); break; @@ -223,7 +246,7 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, break; } case QueuedctlArgument::PermissionAdd: { - auto userId = QueuedctlUser::getUserId(args.at(1)); + auto userId = QueuedCoreAdaptor::getUserId(args.at(1)); QString token = QueuedctlAuth::getToken(_cache, _user); result.status = QueuedctlPermissions::addPermission(userId, args.at(2), token); @@ -238,7 +261,7 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, break; } case QueuedctlArgument::PermissionRemove: { - auto userId = QueuedctlUser::getUserId(args.at(1)); + auto userId = QueuedCoreAdaptor::getUserId(args.at(1)); QString token = QueuedctlAuth::getToken(_cache, _user); result.status = QueuedctlPermissions::removePermission(userId, args.at(2), token); @@ -284,6 +307,12 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, = hashListToString(QueuedctlUser::getReport(_parser, token)); break; } + case QueuedctlArgument::Status: { + auto status = QueuedCoreAdaptor::getStatus(); + result.status = !status.isEmpty(); + result.output = hashHashToString(status); + break; + } case QueuedctlArgument::TaskAdd: { QString token = QueuedctlAuth::getToken(_cache, _user); auto definitions = QueuedctlTask::getDefinitions(_parser, false); @@ -340,7 +369,7 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, break; } case QueuedctlArgument::UserGet: { - auto userId = QueuedctlUser::getUserId(args.at(1)); + auto userId = QueuedCoreAdaptor::getUserId(args.at(1)); QVariant value = QueuedctlUser::getUser(userId, args.at(2)); result.status = value.isValid(); result.output = args.at(2).isEmpty() ? hashToString(value.toHash()) @@ -355,7 +384,7 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, break; } case QueuedctlArgument::UserSet: { - auto userId = QueuedctlUser::getUserId(args.at(1)); + auto userId = QueuedCoreAdaptor::getUserId(args.at(1)); QString token = QueuedctlAuth::getToken(_cache, _user); auto definitions = QueuedctlUser::getDefinitions(_parser, true); result.status = QueuedctlUser::setUser(userId, definitions, token); diff --git a/sources/queuedctl/src/QueuedctlCommon.h b/sources/queuedctl/src/QueuedctlCommon.h index 101104f..2721777 100644 --- a/sources/queuedctl/src/QueuedctlCommon.h +++ b/sources/queuedctl/src/QueuedctlCommon.h @@ -34,6 +34,7 @@ enum class QueuedctlArgument { PluginList, PluginRemove, Report, + Status, TaskAdd, TaskGet, TaskList, @@ -68,6 +69,7 @@ const QHash QueuedctlArguments = { {"plugin-remove", {QueuedctlArgument::PluginRemove, "Removes plugin to load.", 2}}, {"report", {QueuedctlArgument::Report, "Shows usage report.", 1}}, + {"status", {QueuedctlArgument::Status, "Server status.", 1}}, {"task-add", {QueuedctlArgument::TaskAdd, "Adds new task.", 2}}, {"task-get", {QueuedctlArgument::TaskGet, "Gets task properties.", 3}}, {"task-list", {QueuedctlArgument::TaskList, "Gets tasks list.", 1}}, @@ -82,6 +84,7 @@ const QHash QueuedctlArguments = { void checkArgs(const QStringList &_args, const int _count, QCommandLineParser &_parser); QString commandsHelp(); +QString hashHashToString(const QHash> &_hash); QString hashToString(const QVariantHash &_hash); QString hashListToString(const QList &_list); void preprocess(const QStringList &_args, QCommandLineParser &_parser); diff --git a/sources/queuedctl/src/QueuedctlPlugins.cpp b/sources/queuedctl/src/QueuedctlPlugins.cpp index 325695d..49c58a2 100644 --- a/sources/queuedctl/src/QueuedctlPlugins.cpp +++ b/sources/queuedctl/src/QueuedctlPlugins.cpp @@ -29,9 +29,7 @@ bool QueuedctlPlugins::addPlugin(const QString &_plugin, const QString &_token) QStringList QueuedctlPlugins::listPlugins() { - return QueuedCoreAdaptor::getOption( - QueuedAdvancedSettings::internalId( - QueuedConfig::QueuedSettings::Plugins)) + return QueuedCoreAdaptor::getOption(QueuedConfig::QueuedSettings::Plugins) .toString() .split('\n'); } diff --git a/sources/queuedctl/src/QueuedctlTask.cpp b/sources/queuedctl/src/QueuedctlTask.cpp index 4dc0f3a..c169dbd 100644 --- a/sources/queuedctl/src/QueuedctlTask.cpp +++ b/sources/queuedctl/src/QueuedctlTask.cpp @@ -57,7 +57,7 @@ QueuedctlTask::getDefinitions(const QCommandLineParser &_parser, definitions.user = _parser.value("task-user").isEmpty() ? 0 - : QueuedctlUser::getUserId(_parser.value("task-user")); + : QueuedCoreAdaptor::getUserId(_parser.value("task-user")); definitions.workingDirectory = QFileInfo(_parser.value("directory")).absoluteFilePath(); // limits now @@ -93,20 +93,20 @@ QVariant QueuedctlTask::getTask(const long long _id, const QString &_property) { qCDebug(LOG_APP) << "Get property" << _property << "from task" << _id; - auto value = QueuedCoreAdaptor::getTask(_id, _property); if (_property.isEmpty()) - return qdbus_cast(value.value()); + return QueuedCoreAdaptor::getTask(_id); else - return value; + return QueuedCoreAdaptor::getTask(_id, _property); } QList QueuedctlTask::getTasks(const QCommandLineParser &_parser, const QString &_token) { - long long user = _parser.value("task-user").isEmpty() - ? -1 - : QueuedctlUser::getUserId(_parser.value("task-user")); + long long user + = _parser.value("task-user").isEmpty() + ? -1 + : QueuedCoreAdaptor::getUserId(_parser.value("task-user")); QDateTime stop = QDateTime::fromString(_parser.value("stop"), Qt::ISODateWithMs); QDateTime start diff --git a/sources/queuedctl/src/QueuedctlUser.cpp b/sources/queuedctl/src/QueuedctlUser.cpp index b86f93f..c9b8a1a 100644 --- a/sources/queuedctl/src/QueuedctlUser.cpp +++ b/sources/queuedctl/src/QueuedctlUser.cpp @@ -111,11 +111,10 @@ QVariant QueuedctlUser::getUser(const long long _id, const QString &_property) { qCDebug(LOG_APP) << "Get property" << _property << "from user" << _id; - auto value = QueuedCoreAdaptor::getUser(_id, _property); if (_property.isEmpty()) - return qdbus_cast(value.value()); + return QueuedCoreAdaptor::getUser(_id); else - return value; + return QueuedCoreAdaptor::getUser(_id, _property); } @@ -133,19 +132,6 @@ QList QueuedctlUser::getUsers(const QCommandLineParser &_parser, } -long long QueuedctlUser::getUserId(const QString &_name) -{ - qCDebug(LOG_APP) << "Get user ID for" << _name; - - bool status = false; - long long stringToLong = _name.toLongLong(&status); - if (status) - return stringToLong; - else - return QueuedCoreAdaptor::getUserId(_name); -} - - void QueuedctlUser::parserAdd(QCommandLineParser &_parser) { _parser.addPositionalArgument("name", "User name.", ""); diff --git a/sources/queuedctl/src/QueuedctlUser.h b/sources/queuedctl/src/QueuedctlUser.h index 089f7b0..1291e92 100644 --- a/sources/queuedctl/src/QueuedctlUser.h +++ b/sources/queuedctl/src/QueuedctlUser.h @@ -34,7 +34,6 @@ QString getPassword(); QVariant getUser(const long long _id, const QString &_property); QList getUsers(const QCommandLineParser &_parser, const QString &_token); -long long getUserId(const QString &_name); void parserAdd(QCommandLineParser &_parser); void parserGet(QCommandLineParser &_parser); void parserList(QCommandLineParser &_parser);