From 5e9b2ad190c8165aab998e09854120ff54272c36 Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Sat, 25 Feb 2017 17:09:54 +0300 Subject: [PATCH] start working on QueuedCore --- sources/queued/include/queued/Queued.h | 3 + .../include/queued/QueuedAdvancedSettings.h | 24 ++- sources/queued/include/queued/QueuedCore.h | 93 +++++++++ .../queued/include/queued/QueuedDatabase.h | 4 +- .../include/queued/QueuedDatabaseSchema.h | 38 +++- sources/queued/include/queued/QueuedProcess.h | 26 ++- .../include/queued/QueuedProcessManager.h | 7 +- .../include/queued/QueuedReportManager.h | 59 ++++++ .../include/queued/QueuedTokenManager.h | 2 +- .../queued/include/queued/QueuedUserManager.h | 123 +++++++++++ sources/queued/src/QueuedAdvancedSettings.cpp | 30 ++- sources/queued/src/QueuedCore.cpp | 101 +++++++++ sources/queued/src/QueuedDatabase.cpp | 42 ++-- sources/queued/src/QueuedProcess.cpp | 18 +- sources/queued/src/QueuedProcessManager.cpp | 44 +++- sources/queued/src/QueuedReportManager.cpp | 48 +++++ sources/queued/src/QueuedTokenManager.cpp | 5 +- sources/queued/src/QueuedUserManager.cpp | 193 ++++++++++++++++++ 18 files changed, 807 insertions(+), 53 deletions(-) create mode 100644 sources/queued/include/queued/QueuedCore.h create mode 100644 sources/queued/include/queued/QueuedReportManager.h create mode 100644 sources/queued/include/queued/QueuedUserManager.h create mode 100644 sources/queued/src/QueuedCore.cpp create mode 100644 sources/queued/src/QueuedReportManager.cpp create mode 100644 sources/queued/src/QueuedUserManager.cpp diff --git a/sources/queued/include/queued/Queued.h b/sources/queued/include/queued/Queued.h index d365872..38b62c7 100644 --- a/sources/queued/include/queued/Queued.h +++ b/sources/queued/include/queued/Queued.h @@ -26,13 +26,16 @@ #include "QueuedAdvancedSettings.h" #include "QueuedConfiguration.h" +#include "QueuedCore.h" #include "QueuedDatabase.h" #include "QueuedDebug.h" #include "QueuedEnums.h" #include "QueuedProcess.h" #include "QueuedProcessManager.h" +#include "QueuedReportManager.h" #include "QueuedSettings.h" #include "QueuedTokenManager.h" #include "QueuedUser.h" +#include "QueuedUserManager.h" #endif /* QUEUED_H */ diff --git a/sources/queued/include/queued/QueuedAdvancedSettings.h b/sources/queued/include/queued/QueuedAdvancedSettings.h index e5b2e0e..724ac7d 100644 --- a/sources/queued/include/queued/QueuedAdvancedSettings.h +++ b/sources/queued/include/queued/QueuedAdvancedSettings.h @@ -25,8 +25,7 @@ #define QUEUEDADVANCEDSETTINGS_H #include - -#include "QueuedConfiguration.h" +#include /** @@ -46,13 +45,32 @@ public: * @brief QueuedAdvancedSettings class destructor */ virtual ~QueuedAdvancedSettings(); + /** + * @brief get value + * @param _key key to search in + * @return value by key if found + */ + QVariant get(const QString &_key) const; + /** + * @brief set value + * @param _key key to change + * @param _value value to change + */ + void set(const QString &_key, const QVariant &_value); /** * @brief upload configuration from database in to internal format * @param _value configuration values from database */ - void setValues(const QList &_values); + void set(const QList &_values); + +signals: + void valueUpdated(const QString &_key, const QVariant &_value); private: + /** + * @brief stored values + */ + QVariantHash m_values; }; diff --git a/sources/queued/include/queued/QueuedCore.h b/sources/queued/include/queued/QueuedCore.h new file mode 100644 index 0000000..684612b --- /dev/null +++ b/sources/queued/include/queued/QueuedCore.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016 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. + */ +/** + * @file QueuedCore.h + * Header of Queued library + * @author Evgeniy Alekseev + * @copyright MIT + * @bug https://github.com/arcan1s/queued/issues + */ + + +#ifndef QUEUEDCORE_H +#define QUEUEDCORE_H + +#include + + +class QueuedAdvancedSettings; +class QueuedDatabase; +class QueuedProcessManager; +class QueuedReportManager; +class QueuedSettings; +class QueuedTokenManager; +class QueuedUserManager; + +/** + * @brief aggregator of queued classes + */ +class QueuedCore : public QObject +{ + Q_OBJECT + +public: + /** + * @brief QueuedCore class constructor + * @param parent pointer to parent item + */ + explicit QueuedCore(QObject *parent); + /** + * @brief QueuedCore class destructor + */ + virtual ~QueuedCore(); + /** + * @brief deinit subclasses + */ + void deinit(); + /** + * @brief init subclasses + * @param _configuration path to configuration file + */ + void init(const QString &_configuration); + +private: + /** + * @brief pointer to advanced settings object + */ + QueuedAdvancedSettings *m_advancedSettings = nullptr; + /** + * @brief pointer to database object + */ + QueuedDatabase *m_database = nullptr; + /** + * @brief pointer to process manager + */ + QueuedProcessManager *m_processes = nullptr; + /** + * @brief pointer to report manager + */ + QueuedReportManager *m_reports = nullptr; + /** + * @brief pointer to settings object + */ + QueuedSettings *m_settings = nullptr; + /** + * @brief pointer to user manager + */ + QueuedUserManager *m_users = nullptr; +}; + + +#endif /* QUEUEDCORE_H */ diff --git a/sources/queued/include/queued/QueuedDatabase.h b/sources/queued/include/queued/QueuedDatabase.h index fa97063..bbda891 100644 --- a/sources/queued/include/queued/QueuedDatabase.h +++ b/sources/queued/include/queued/QueuedDatabase.h @@ -70,9 +70,11 @@ public: /** * @brief get all records from table * @param _table table name + * @param _condition optional condition string * @return list of records from table */ - QList get(const QString &_table); + QList get(const QString &_table, + const QString &_condition = QString()); /** * @brief get record from table with given id * @param _table table name diff --git a/sources/queued/include/queued/QueuedDatabaseSchema.h b/sources/queued/include/queued/QueuedDatabaseSchema.h index 4cc921d..7dc690e 100644 --- a/sources/queued/include/queued/QueuedDatabaseSchema.h +++ b/sources/queued/include/queued/QueuedDatabaseSchema.h @@ -34,6 +34,26 @@ */ namespace QueuedDB { +/** + * @ingroup QueuedDB + * @brief settings table name + */ +const char SETTINGS_TABLE[] = "settings"; +/** +* @ingroup QueuedDB +* @brief tasks table name +*/ +const char TASKS_TABLE[] = "tasks"; +/** +* @ingroup QueuedDB +* @brief tokens table name +*/ +const char TOKENS_TABLE[] = "tokens"; +/** +* @ingroup QueuedDB +* @brief users table name +*/ +const char USERS_TABLE[] = "users"; /** *@ingroup QueuedDB * @struct QueuedDBField @@ -61,12 +81,12 @@ typedef QHash> QueuedDBSchema; * @brief database schema */ const QueuedDBSchema DBSchema = { - {"settings", + {SETTINGS_TABLE, {{"_id", {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong}}, - {"key", {"key", "TEXT NOT NULL DEFAULT '0'", QVariant::String}}, + {"key", {"key", "TEXT NOT NULL UNIQUE DEFAULT '0'", QVariant::String}}, {"value", {"value", "TEXT", QVariant::String}}}}, - {"tasks", + {TASKS_TABLE, {{"_id", {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong}}, {"userId", {"userId", "INT NOT NULL DEFAULT 0", QVariant::LongLong}}, @@ -74,20 +94,24 @@ const QueuedDBSchema DBSchema = { {"arguments", {"arguments", "TEXT", QVariant::String}}, {"workDirectory", {"workDirectory", "TEXT", QVariant::String}}, {"nice", {"nice", "INT", QVariant::UInt}}, + {"uid", {"uid", "INT", QVariant::UInt}}, + {"gid", {"gid", "INT", QVariant::UInt}}, {"startTime", {"startTime", "INT", QVariant::LongLong}}, {"endTime", {"endTime", "INT", QVariant::LongLong}}}}, - {"tokens", + {TOKENS_TABLE, {{"_id", {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong}}, - {"token", {"token", "TEXT NOT NULL DEFAULT '0'", QVariant::String}}, + {"token", + {"token", "TEXT NOT NULL UNIQUE DEFAULT '0'", QVariant::String}}, {"validUntil", {"validUntil", "TEXT NOT NULL DEFAULT '0'", QVariant::String}}}}, - {"users", + {USERS_TABLE, {{"_id", {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong}}, - {"name", {"name", "TEXT NOT NULL DEFAULT '0'", QVariant::String}}, + {"name", {"name", "TEXT NOT NULL UNIQUE DEFAULT '0'", QVariant::String}}, {"passwordSHA512", {"passwordSHA512", "TEXT", QVariant::String}}, {"email", {"email", "TEXT", QVariant::String}}, + {"lastLogin", {"lastLogin", "TEXT", QVariant::String}}, {"cpu", {"cpu", "INT", QVariant::LongLong}}, {"gpu", {"gpu", "INT", QVariant::LongLong}}, {"memory", {"memory", "INT", QVariant::LongLong}}, diff --git a/sources/queued/include/queued/QueuedProcess.h b/sources/queued/include/queued/QueuedProcess.h index f1dbedf..0ff3348 100644 --- a/sources/queued/include/queued/QueuedProcess.h +++ b/sources/queued/include/queued/QueuedProcess.h @@ -24,6 +24,7 @@ #ifndef QUEUEDPROCESS_H #define QUEUEDPROCESS_H +#include #include #include @@ -43,9 +44,9 @@ public: /** * @struct QueuedProcessDefinition * @brief structure to define process - * @var cmd + * @var command * command line - * @var args + * @var arguments * command line arguments * @var workingDirectory * path to working directory @@ -53,13 +54,25 @@ public: * UID of process * @var gid * GID of process + * @var nice + * nice level of process + * @var startTime + * process start time + * @var endTime + * process end time + * @var user + * task owner ID */ typedef struct { - QString cmd; - QStringList args; + QString command; + QStringList arguments; QString workingDirectory; unsigned int uid; unsigned int gid; + unsigned int nice; + QDateTime startTime; + QDateTime endTime; + long long user; } QueuedProcessDefinitions; /** @@ -115,6 +128,11 @@ public slots: * @brief run process */ void run(); + /** + * @brief set end time + * @param _time process end time + */ + void setEndTime(const QDateTime &_time); private: /** diff --git a/sources/queued/include/queued/QueuedProcessManager.h b/sources/queued/include/queued/QueuedProcessManager.h index e3ff4f5..edc5461 100644 --- a/sources/queued/include/queued/QueuedProcessManager.h +++ b/sources/queued/include/queued/QueuedProcessManager.h @@ -81,6 +81,11 @@ public: QueuedProcess * add(const long long _index, const QueuedProcess::QueuedProcessDefinitions _definitions); + /** + * @brief add tasks from database + * @param _processes database stored tasks + */ + void add(const QList &_processes); /** * @brief default action on exit * @return default action from possible ones @@ -141,7 +146,7 @@ private: /** * @brief action on exit */ - OnExitAction m_onExit = OnExitAction::Kill; + OnExitAction m_onExit = OnExitAction::Terminate; /** * @brief processes list */ diff --git a/sources/queued/include/queued/QueuedReportManager.h b/sources/queued/include/queued/QueuedReportManager.h new file mode 100644 index 0000000..6a1f06f --- /dev/null +++ b/sources/queued/include/queued/QueuedReportManager.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 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. + */ +/** + * @file QueuedReportManager.h + * Header of Queued library + * @author Evgeniy Alekseev + * @copyright MIT + * @bug https://github.com/arcan1s/queued/issues + */ + + +#ifndef QUEUEDREPORTMANAGER_H +#define QUEUEDREPORTMANAGER_H + +#include + + +class QueuedDatabase; + +/** + * @brief report manager for queued + */ +class QueuedReportManager : public QObject +{ + Q_OBJECT + +public: + /** + * @brief QueuedReportManager class constructor + * @param parent pointer to parent item + * @param database pointer to database object + */ + explicit QueuedReportManager(QObject *parent, QueuedDatabase *database); + /** + * @brief QueuedReportManager class destructor + */ + virtual ~QueuedReportManager(); + +private: + /** + * @brief pointer to database object + */ + QueuedDatabase *m_database = nullptr; +}; + + +#endif /* QUEUEDREPORTMANAGER_H */ diff --git a/sources/queued/include/queued/QueuedTokenManager.h b/sources/queued/include/queued/QueuedTokenManager.h index b244489..d6b10bd 100644 --- a/sources/queued/include/queued/QueuedTokenManager.h +++ b/sources/queued/include/queued/QueuedTokenManager.h @@ -61,7 +61,7 @@ public: * @brief upload tokens from database * @param _value tokens from database */ - void setValues(const QList &_values); + void set(const QList &_values); public slots: /** diff --git a/sources/queued/include/queued/QueuedUserManager.h b/sources/queued/include/queued/QueuedUserManager.h new file mode 100644 index 0000000..923befc --- /dev/null +++ b/sources/queued/include/queued/QueuedUserManager.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016 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. + */ +/** + * @file QueuedUserManager.h + * Header of Queued library + * @author Evgeniy Alekseev + * @copyright MIT + * @bug https://github.com/arcan1s/queued/issues + */ + + +#ifndef QUEUEDUSERMANAGER_H +#define QUEUEDUSERMANAGER_H + +#include +#include + +#include "QueuedEnums.h" +#include "QueuedUser.h" + + +class QueuedTokenManager; + +/** + * @brief user manager for queued + */ +class QueuedUserManager : public QObject +{ + Q_OBJECT + Q_PROPERTY( + long long tokenExpiration READ tokenExpiration WRITE setTokenExpiration) + +public: + /** + * @brief QueuedUserManager class constructor + * @param parent pointer to parent item + */ + explicit QueuedUserManager(QObject *parent); + /** + * @brief QueuedUserManager class destructor + */ + virtual ~QueuedUserManager(); + /** + * @brief add user + * @param _definitions user definitions + * @param _id user ID + * @return pointer to created user + */ + QueuedUser *add(const QueuedUser::QueuedUserDefinitions &_definitions, + const long long _id); + /** + * @brief authorize user + * @param _user user name + * @param _password user password + * @return generated tokens 0r empty string if it is not valid + */ + QString authorize(const QString &_user, const QString &_password); + /** + * @brief authorize user for service + * @param _user user name + * @param _token token ID + * @param _service service to authorize + * @return true if user allowed to do it otherwise return false + */ + bool authorize(const QString &_user, const QString &_token, + const QueuedEnums::Permission _service); + /** + * @brief load tokens + * @param _tokens tokens list from database + */ + void loadTokens(const QList &_tokens); + /** + * @brief load users + * @param _users users list from database + */ + void loadUsers(const QList &_users); + /** + * @brief user by name + * @param _name user name for search + * @return user by name or nullptr if no user found + */ + QueuedUser *user(const QString &_name); + // properties + /** + * @brief token expiration + * @return token expiration in days + */ + long long tokenExpiration() const; + /** + * @brief set token expiration + * @param _expiry token expiration in days + */ + void setTokenExpiration(const long long &_expiry); + +private: + /** + * @brief token expiration in days + */ + long long m_tokenExpiration = 30; + /** + * @brief pointer to token manager + */ + QueuedTokenManager *m_tokens = nullptr; + /** + * @brief list of users + */ + QHash m_users; +}; + + +#endif /* QUEUEDUSERMANAGER_H */ diff --git a/sources/queued/src/QueuedAdvancedSettings.cpp b/sources/queued/src/QueuedAdvancedSettings.cpp index c1b289b..007df96 100644 --- a/sources/queued/src/QueuedAdvancedSettings.cpp +++ b/sources/queued/src/QueuedAdvancedSettings.cpp @@ -47,9 +47,35 @@ QueuedAdvancedSettings::~QueuedAdvancedSettings() /** - * @fn setValues + * @fn get */ -void QueuedAdvancedSettings::setValues(const QList &_values) +QVariant QueuedAdvancedSettings::get(const QString &_key) const +{ + qCDebug(LOG_LIB) << "Looking for key" << _key; + + return m_values[_key]; +} + + +/** + * @fn set + */ +void QueuedAdvancedSettings::set(const QString &_key, const QVariant &_value) +{ + qCDebug(LOG_LIB) << "Set value" << _value << "for key" << _key; + + m_values[_key] = _value; + emit(valueUpdated(_key, _value)); +} + + +/** + * @fn set + */ +void QueuedAdvancedSettings::set(const QList &_values) { qCDebug(LOG_LIB) << "Set values from" << _values; + + for (auto &pair : _values) + set(pair[QString("key")].toString(), pair[QString("value")]); } diff --git a/sources/queued/src/QueuedCore.cpp b/sources/queued/src/QueuedCore.cpp new file mode 100644 index 0000000..2bee29c --- /dev/null +++ b/sources/queued/src/QueuedCore.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016 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. + */ +/** + * @file QueuedCore.cpp + * Source code of queued library + * @author Evgeniy Alekseev + * @copyright GPLv3 + * @bug https://github.com/arcan1s/queued/issues + */ + + +#include "queued/Queued.h" + +#include "queued/QueuedDatabaseSchema.h" + + +/** + * @class QueuedCore + */ +/** + * @fn QueuedCore + */ +QueuedCore::QueuedCore(QObject *parent) + : QObject(parent) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} + + +/** + * @fn ~QueuedCore + */ +QueuedCore::~QueuedCore() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + deinit(); +} + + +/** + * @fn deinit + */ +void QueuedCore::deinit() +{ +} + + +/** + * @fn init + */ +void QueuedCore::init(const QString &_configuration) +{ + qCDebug(LOG_LIB) << "Load configuration from" << _configuration; + + // deinit objects if any + deinit(); + + // read configuration first + m_settings = new QueuedSettings(this, _configuration); + // init database now + auto dbSetup = m_settings->db(); + m_database = new QueuedDatabase(this, dbSetup.path, dbSetup.driver); + m_database->open(dbSetup.hostname, dbSetup.port, dbSetup.username, + dbSetup.password); + auto dbAdmin = m_settings->admin(); + m_database->createAdministrator(dbAdmin.name, dbAdmin.password); + + // and load advanced settings + m_advancedSettings = new QueuedAdvancedSettings(this); + m_advancedSettings->set(m_database->get(QueuedDB::SETTINGS_TABLE)); + + // report manager + m_reports = new QueuedReportManager(this, m_database); + + // load users and tokens + m_users = new QueuedUserManager(this); + auto expiry + = m_advancedSettings->get(QString("TokenExpiration")).toLongLong(); + m_users->setTokenExpiration(expiry); + m_users->loadTokens(m_database->get(QueuedDB::TOKENS_TABLE)); + m_users->loadUsers(m_database->get(QueuedDB::USERS_TABLE)); + + // and processes finally + auto onExitAction = static_cast( + m_advancedSettings->get(QString("OnExitAction")).toInt()); + m_processes = new QueuedProcessManager(this, onExitAction); + m_processes->add(m_database->get(QueuedDB::TASKS_TABLE)); +} diff --git a/sources/queued/src/QueuedDatabase.cpp b/sources/queued/src/QueuedDatabase.cpp index 7c714a9..7dd691f 100644 --- a/sources/queued/src/QueuedDatabase.cpp +++ b/sources/queued/src/QueuedDatabase.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include "queued/QueuedDatabaseSchema.h" @@ -129,13 +128,17 @@ void QueuedDatabase::createAdministrator(const QString &_user, /** * @fn get */ -QList QueuedDatabase::get(const QString &_table) +QList QueuedDatabase::get(const QString &_table, + const QString &_condition) { - qCDebug(LOG_LIB) << "Get records in table" << _table; + qCDebug(LOG_LIB) << "Get records in table" << _table << "with condition" + << _condition; QList output; - QSqlQuery query = m_database.exec( - QString("SELECT * FROM '%1' ORDER BY _id DESC").arg(_table)); + QSqlQuery query + = m_database.exec(QString("SELECT * FROM '%1' ORDER BY _id DESC %1") + .arg(_table) + .arg(_condition)); QSqlError error = query.lastError(); if (error.isValid()) { @@ -165,27 +168,16 @@ QVariantHash QueuedDatabase::get(const QString &_table, const long long _id) { qCDebug(LOG_LIB) << "Get record" << _id << "in table" << _table; - QVariantHash output; - QSqlQuery query = m_database.exec( - QString("SELECT * FROM '%1' WHERE _id=%2").arg(_table).arg(_id)); - - QSqlError error = query.lastError(); - if (error.isValid()) { - qCWarning(LOG_LIB) << "Could not get record" << _id << "from" << _table - << "message" << error.text(); - return output; + auto output = get(_table, QString("WHERE _id=%1").arg(_id)); + if (output.count() == 0) { + qCWarning(LOG_LIB) << "Could not find records for" << _id; + return QVariantHash(); + } else if (output.count() == 1) { + return output.at(0); + } else { + qCWarning(LOG_LIB) << "Too many records found for" << _id; + return output.at(0); } - QSqlRecord record = query.record(); - - QStringList columns = QueuedDB::DBSchema[_table].keys(); - auto dbColumns = getColumnsInRecord(columns, record); - while (query.next()) { - output.clear(); - for (auto &column : columns) - output[column] = query.value(dbColumns[column]); - } - - return output; } diff --git a/sources/queued/src/QueuedProcess.cpp b/sources/queued/src/QueuedProcess.cpp index ef208f6..393bf05 100644 --- a/sources/queued/src/QueuedProcess.cpp +++ b/sources/queued/src/QueuedProcess.cpp @@ -24,6 +24,7 @@ #include "queued/Queued.h" #include +#include /** @@ -41,8 +42,8 @@ QueuedProcess::QueuedProcess(QObject *parent, { qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; - setArguments(m_definitions.args); - setProgram(m_definitions.cmd); + setArguments(m_definitions.arguments); + setProgram(m_definitions.command); setWorkingDirectory(m_definitions.workingDirectory); } @@ -133,11 +134,22 @@ void QueuedProcess::setupChildProcess() */ void QueuedProcess::run() { - // TODO set limits to child process and etc + m_definitions.startTime = QDateTime::currentDateTimeUtc(); return start(); } +/** + * @fn setEndTime + */ + void QueuedProcess::setEndTime(const QDateTime &_time) +{ + qCDebug(LOG_LIB) << "Set end time to" << _time; + + m_definitions.endTime = _time; +} + + /** * @fn convertMemory */ diff --git a/sources/queued/src/QueuedProcessManager.cpp b/sources/queued/src/QueuedProcessManager.cpp index f785d4e..f4b229f 100644 --- a/sources/queued/src/QueuedProcessManager.cpp +++ b/sources/queued/src/QueuedProcessManager.cpp @@ -22,6 +22,7 @@ #include "queued/Queued.h" +#include /** @@ -56,8 +57,8 @@ QueuedProcess *QueuedProcessManager::add( const long long _index, const QueuedProcess::QueuedProcessDefinitions _definitions) { - qCDebug(LOG_LIB) << "Add new process" << _definitions.cmd << "with index" - << _index; + qCDebug(LOG_LIB) << "Add new process" << _definitions.command + << "with index" << _index; if (m_processes.contains(_index)) return m_processes[_index]; @@ -76,6 +77,36 @@ QueuedProcess *QueuedProcessManager::add( } +/** + * @fn add + */ +void QueuedProcessManager::add(const QList &_processes) +{ + qCDebug(LOG_LIB) << "Add tasks from" << _processes; + + for (auto &pr : _processes) { + QueuedProcess::QueuedProcessDefinitions defs; + // parameters + defs.command = pr[QString("command")].toString(); + defs.arguments + = pr[QString("arguments")].toString().split(QChar('\x01')); + defs.workingDirectory = pr[QString("workDirectory")].toString(); + defs.nice = pr[QString("nice")].toUInt(); + // user data + defs.uid = pr[QString("uid")].toUInt(); + defs.gid = pr[QString("gid")].toUInt(); + defs.user = pr[QString("user")].toLongLong(); + // metadata + defs.startTime = QDateTime::fromString( + pr[QString("startTime")].toString(), Qt::ISODate); + defs.endTime = QDateTime::fromString(pr[QString("endTime")].toString(), + Qt::ISODate); + + add(pr[QString("_id")].toLongLong(), defs); + } +} + + /** * @fn onExit */ @@ -124,6 +155,7 @@ void QueuedProcessManager::remove(const long long _index) pr->kill(); break; case OnExitAction::Terminate: + default: pr->terminate(); break; } @@ -150,6 +182,7 @@ void QueuedProcessManager::stop(const long long _index) pr->kill(); break; case OnExitAction::Terminate: + default: pr->terminate(); break; } @@ -166,7 +199,12 @@ void QueuedProcessManager::taskFinished(const int _exitCode, qCDebug(LOG_LIB) << "Process" << _index << "finished with code" << _exitCode << "and status" << _exitStatus; - emit(taskStopTimeReceived(_index, QDateTime::currentDateTimeUtc())); + auto pr = process(_index); + if (pr) { + auto endTime = QDateTime::currentDateTimeUtc(); + pr->setEndTime(endTime); + emit(taskStopTimeReceived(_index, endTime)); + } // TODO implementation // TODO emit signal for new task here // emit(taskStartTimeReceived(_index, QDateTime::currentDateTimeUtc())); diff --git a/sources/queued/src/QueuedReportManager.cpp b/sources/queued/src/QueuedReportManager.cpp new file mode 100644 index 0000000..6669f2f --- /dev/null +++ b/sources/queued/src/QueuedReportManager.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016 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. + */ +/** + * @file QueuedReportManager.cpp + * Source code of queued library + * @author Evgeniy Alekseev + * @copyright GPLv3 + * @bug https://github.com/arcan1s/queued/issues + */ + + +#include "queued/Queued.h" + + +/** + * @class QueuedReportManager + */ +/** + * @fn QueuedReportManager + */ +QueuedReportManager::QueuedReportManager(QObject *parent, + QueuedDatabase *database) + : QObject(parent) + , m_database(database) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} + + +/** + * @fn ~QueuedReportManager + */ +QueuedReportManager::~QueuedReportManager() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} diff --git a/sources/queued/src/QueuedTokenManager.cpp b/sources/queued/src/QueuedTokenManager.cpp index 01faf29..32baf67 100644 --- a/sources/queued/src/QueuedTokenManager.cpp +++ b/sources/queued/src/QueuedTokenManager.cpp @@ -81,14 +81,13 @@ QString QueuedTokenManager::registerToken(const QDateTime _validUntil) /** - * @fn setValues + * @fn set */ -void QueuedTokenManager::setValues(const QList &_values) +void QueuedTokenManager::set(const QList &_values) { qCDebug(LOG_LIB) << "Set values from" << _values; QDateTime now = QDateTime::currentDateTimeUtc(); - m_tokens.clear(); for (auto &token : _values) { QDateTime validUntil = QDateTime::fromString( token[QString("validUntil")].toString(), Qt::ISODate); diff --git a/sources/queued/src/QueuedUserManager.cpp b/sources/queued/src/QueuedUserManager.cpp new file mode 100644 index 0000000..13779fa --- /dev/null +++ b/sources/queued/src/QueuedUserManager.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2016 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. + */ +/** + * @file QueuedUserManager.cpp + * Source code of queued library + * @author Evgeniy Alekseev + * @copyright GPLv3 + * @bug https://github.com/arcan1s/queued/issues + */ + + +#include + +#include + + +/** + * @class QueuedUserManager + */ +/** + * @fn QueuedUserManager + */ +QueuedUserManager::QueuedUserManager(QObject *parent) + : QObject(parent) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + m_tokens = new QueuedTokenManager(this); +} + + +/** + * @fn ~QueuedUserManager + */ +QueuedUserManager::~QueuedUserManager() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + delete m_tokens; + m_users.clear(); +} + + +/** + * @fn add + */ +QueuedUser * +QueuedUserManager::add(const QueuedUser::QueuedUserDefinitions &_definitions, + const long long _id) +{ + qCDebug(LOG_LIB) << "Add user" << _definitions.name << "with ID" << _id; + + if (m_users.contains(_definitions.name)) { + qCWarning(LOG_LIB) << "User" << _definitions.name << "already exists"; + return nullptr; + } + + auto user = new QueuedUser(this, _definitions, _id); + m_users[user->name()] = user; + + return user; +} + + +/** + * @fn authorize + */ +QString QueuedUserManager::authorize(const QString &_user, + const QString &_password) +{ + qCDebug(LOG_LIB) << "Authorize user" << _user; + + if (!m_users.contains(_user)) { + qCInfo(LOG_LIB) << "No user found" << _user; + return QString(); + } + + bool status = m_users[_user]->isPasswordValid(_password); + if (!status) { + qCInfo(LOG_LIB) << "User password invalid for" << _user; + return QString(); + } + + QDateTime expiry + = QDateTime::currentDateTimeUtc().addDays(tokenExpiration()); + return m_tokens->registerToken(expiry); +} + + +/** + * @fn authorize + */ +bool QueuedUserManager::authorize(const QString &_user, const QString &_token, + const QueuedEnums::Permission _service) +{ + qCDebug(LOG_LIB) << "Authorize user" << _user << "for" + << static_cast(_service); + + bool status = m_tokens->isTokenValid(_token); + if (!status) { + qCInfo(LOG_LIB) << "Token invalid for user" << _user; + return false; + } + + if (!m_users.contains(_user)) { + qCInfo(LOG_LIB) << "No user found" << _user; + return false; + } + + return m_users[_user]->hasPermission(_service); +} + + +/** + * @fn loadTokens + */ +void QueuedUserManager::loadTokens(const QList &_tokens) +{ + qCDebug(LOG_LIB) << "Set tokens from" << _tokens; + + m_tokens->set(_tokens); +} + + +/** + * @fn loadUsers + */ +void QueuedUserManager::loadUsers(const QList &_users) +{ + qCDebug(LOG_LIB) << "Set users from" << _users; + + // load now + for (auto &userdata : _users) { + QueuedUser::QueuedUserDefinitions defs; + defs.name = userdata[QString("name")].toString(); + defs.email = userdata[QString("email")].toString(); + defs.passwordSHA512 = userdata[QString("passwordSHA512")].toString(); + defs.permissions = userdata[QString("permissions")].toUInt(); + // limits + defs.cpuLimit = userdata[QString("cpuLimit")].toLongLong(); + defs.gpuLimit = userdata[QString("gpuLimit")].toLongLong(); + defs.memoryLimit = userdata[QString("memoryLimit")].toLongLong(); + defs.gpumemoryLimit = userdata[QString("gpumemoryLimit")].toLongLong(); + defs.storageLimit = userdata[QString("storageLimit")].toLongLong(); + + add(defs, userdata[QString("_id")].toLongLong()); + } +} + + +/** + * @fn user + */ +QueuedUser *QueuedUserManager::user(const QString &_name) +{ + qCDebug(LOG_LIB) << "Look for user" << _name; + + return m_users.contains(_name) ? m_users[_name] : nullptr; +} + + +/* + * @fn tokenExpiration + */ +long long QueuedUserManager::tokenExpiration() const +{ + return m_tokenExpiration; +} + + +/** + * @fn setTokenExpiration + */ +void QueuedUserManager::setTokenExpiration(const long long &_expiry) +{ + qCDebug(LOG_LIB) << "Set token expiration to" << _expiry; + if (_expiry <= 0) + return; + + m_tokenExpiration = _expiry; +}