From 69fbab45b249c8f0c4f432f1c32d5bd9c01fb195 Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Thu, 16 Mar 2017 01:58:50 +0300 Subject: [PATCH] more improvements of queuedctl --- sources/queued/include/queued/QueuedCore.h | 7 + .../queued/include/queued/QueuedCoreAdaptor.h | 7 + .../include/queued/QueuedCoreInterface.h | 8 +- .../queued/QueuedCorePropertiesInterface.h | 16 ++ sources/queued/include/queued/QueuedEnums.h | 30 ++- sources/queued/include/queued/QueuedProcess.h | 21 +- sources/queued/include/queued/QueuedUser.h | 13 +- sources/queued/src/QueuedCore.cpp | 59 ++--- sources/queued/src/QueuedCoreAdaptor.cpp | 48 ++-- sources/queued/src/QueuedCoreInterface.cpp | 22 +- .../src/QueuedCorePropertiesInterface.cpp | 55 ++++- sources/queued/src/QueuedPluginManager.cpp | 4 + sources/queued/src/QueuedProcess.cpp | 46 +++- sources/queued/src/QueuedProcessManager.cpp | 9 +- sources/queued/src/QueuedUser.cpp | 20 +- sources/queuedctl/src/QueuedctlAuth.cpp | 36 +-- sources/queuedctl/src/QueuedctlAuth.h | 5 +- sources/queuedctl/src/QueuedctlCommon.cpp | 123 +++++++++- sources/queuedctl/src/QueuedctlCommon.h | 39 +++- .../queuedctl/src/QueuedctlPermissions.cpp | 59 +++++ sources/queuedctl/src/QueuedctlPermissions.h | 33 +++ sources/queuedctl/src/QueuedctlPlugins.cpp | 52 +++++ sources/queuedctl/src/QueuedctlPlugins.h | 32 +++ sources/queuedctl/src/QueuedctlTask.cpp | 48 +++- sources/queuedctl/src/QueuedctlTask.h | 3 + sources/queuedctl/src/QueuedctlUser.cpp | 219 ++++++++++++++++++ sources/queuedctl/src/QueuedctlUser.h | 43 ++++ 27 files changed, 925 insertions(+), 132 deletions(-) create mode 100644 sources/queuedctl/src/QueuedctlPermissions.cpp create mode 100644 sources/queuedctl/src/QueuedctlPermissions.h create mode 100644 sources/queuedctl/src/QueuedctlPlugins.cpp create mode 100644 sources/queuedctl/src/QueuedctlPlugins.h create mode 100644 sources/queuedctl/src/QueuedctlUser.cpp create mode 100644 sources/queuedctl/src/QueuedctlUser.h diff --git a/sources/queued/include/queued/QueuedCore.h b/sources/queued/include/queued/QueuedCore.h index 25414fc..525a65e 100644 --- a/sources/queued/include/queued/QueuedCore.h +++ b/sources/queued/include/queued/QueuedCore.h @@ -235,6 +235,13 @@ public: * @return user object or nullptr if no user found */ const QueuedUser *user(const long long _id); + /** + * @brief get user by name + * @param _name + * user name + * @return user object or nullptr if no user found + */ + const QueuedUser *user(const QString &_name); // control methods /** * @brief deinit subclasses diff --git a/sources/queued/include/queued/QueuedCoreAdaptor.h b/sources/queued/include/queued/QueuedCoreAdaptor.h index 41d712a..5a2aa56 100644 --- a/sources/queued/include/queued/QueuedCoreAdaptor.h +++ b/sources/queued/include/queued/QueuedCoreAdaptor.h @@ -201,6 +201,13 @@ QVariant getTask(const long long _id, const QString &_property); * @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 + */ +long long getUserId(const QString &_name); // common methods /** * @brief common DBus request diff --git a/sources/queued/include/queued/QueuedCoreInterface.h b/sources/queued/include/queued/QueuedCoreInterface.h index f7ed1bd..d140d3b 100644 --- a/sources/queued/include/queued/QueuedCoreInterface.h +++ b/sources/queued/include/queued/QueuedCoreInterface.h @@ -212,8 +212,8 @@ public slots: qlonglong UserAdd(const QString &name, const QString &email, const QString &password, const uint permissions, const qlonglong cpu, const qlonglong gpu, - const QString &memory, const QString &gpumemory, - const QString &storage, const QString &token); + const qlonglong memory, const qlonglong gpumemory, + const qlonglong storage, const QString &token); /** * @brief edit user * @param id @@ -241,8 +241,8 @@ public slots: bool UserEdit(const qlonglong id, const QString &name, const QString &password, const QString &email, const qlonglong cpu, const qlonglong gpu, - const QString &memory, const QString &gpumemory, - const QString &storage, const QString &token); + const qlonglong memory, const qlonglong gpumemory, + const qlonglong storage, const QString &token); /** * @brief add permission to user * @param id diff --git a/sources/queued/include/queued/QueuedCorePropertiesInterface.h b/sources/queued/include/queued/QueuedCorePropertiesInterface.h index 1f6b458..6bcd754 100644 --- a/sources/queued/include/queued/QueuedCorePropertiesInterface.h +++ b/sources/queued/include/queued/QueuedCorePropertiesInterface.h @@ -66,6 +66,7 @@ public slots: * task ID * @param property * property name + * @remark if property is empty it return map of all properties * @return property value or empty if task or property not found */ QDBusVariant Task(const long long id, const QString &property); @@ -75,15 +76,30 @@ public slots: * user ID * @param property * property name + * @remark if property is empty it return map of all properties * @return property value or empty if user or property not found */ QDBusVariant User(const long long id, const QString &property); + /** + * @brief get user ID by name + * @param name + * user name + * @return user ID or -1 if no user found + */ + qlonglong UserIdByName(const QString &name); private: /** * @brief pointer to database object */ QueuedCore *m_core = nullptr; + /** + * @brief get all properties + * @param _object + * pointer to object + * @return map of properties + */ + QVariantHash getProperties(const QObject *_object); }; diff --git a/sources/queued/include/queued/QueuedEnums.h b/sources/queued/include/queued/QueuedEnums.h index a032bd6..9caf5e2 100644 --- a/sources/queued/include/queued/QueuedEnums.h +++ b/sources/queued/include/queued/QueuedEnums.h @@ -24,6 +24,8 @@ #ifndef QUEUEDENUMS_H #define QUEUEDENUMS_H +#include + /** * @addtogroup QueuedEnums @@ -34,26 +36,48 @@ namespace QueuedEnums /** * @enum Permission * @brief available user permissions + * @var Permission::Invalid + * invalid permission * @var Permission::SuperAdmin * "allow all" permissions * @var Permission::Admin * administrative permissions - * @var Permission::JobOwner - * owner job related permissions + * @var Permission::Job + * job related permissions * @var Permission::Web * web server access * @var Permission::Reports * access to reports */ enum class Permission { + Invalid = 1 << 0, SuperAdmin = 1 << 1, Admin = 1 << 2, - JobOwner = 1 << 3, + Job = 1 << 3, Web = 1 << 4, Reports = 1 << 5 }; Q_DECLARE_FLAGS(Permissions, Permission) Q_DECLARE_OPERATORS_FOR_FLAGS(Permissions) +const QHash PermissionMap = { + {"superadmin", Permission::SuperAdmin}, + {"admin", Permission::Admin}, + {"job", Permission::Job}, + {"web", Permission::Web}, + {"reports", Permission::Reports}, +}; +/** + * @brief converts string to permission enum + * @param _permission + * permission string + * @return related Permission value + */ +inline Permission stringToPermission(const QString &_permission) +{ + return PermissionMap.contains(_permission.toLower()) + ? PermissionMap[_permission.toLower()] + : Permission::Invalid; +}; /** * @enum ExitAction * @brief action with child process on destruction diff --git a/sources/queued/include/queued/QueuedProcess.h b/sources/queued/include/queued/QueuedProcess.h index 6b5d25b..c82bc78 100644 --- a/sources/queued/include/queued/QueuedProcess.h +++ b/sources/queued/include/queued/QueuedProcess.h @@ -45,7 +45,8 @@ class QueuedProcess : public QProcess Q_PROPERTY(QDateTime endTime READ endTime WRITE setEndTime) Q_PROPERTY(uint gid READ uid WRITE setGid) Q_PROPERTY(QString limits READ limits WRITE setLimits) - Q_PROPERTY(QueuedLimits::Limits nativeLimtis READ nativeLimits) + Q_PROPERTY(QString logError READ logError WRITE setLogError) + Q_PROPERTY(QString logOutput READ logOutput WRITE setLogOutput) Q_PROPERTY(uint nice READ nice WRITE setNice) Q_PROPERTY(QString processLine READ processLine WRITE setProcessLine) Q_PROPERTY(QDateTime startTime READ startTime WRITE setStartTime) @@ -148,6 +149,16 @@ public: * @return process defined limits */ QString limits() const; + /** + * @brief process error log + * @return path to process error log + */ + QString logError() const; + /** + * @brief process output log + * @return path to process output log + */ + QString logOutput() const; /** * @brief process limits * @return process defined limits in native format @@ -212,6 +223,14 @@ public: * new process limits */ void setLimits(const QString &_limits); + /** + * @brief set process error log + */ + void setLogError(const QString &); + /** + * @brief set process output log + */ + void setLogOutput(const QString &); /** * @brief set process nice * @param _nice diff --git a/sources/queued/include/queued/QueuedUser.h b/sources/queued/include/queued/QueuedUser.h index a1f6559..53a9321 100644 --- a/sources/queued/include/queued/QueuedUser.h +++ b/sources/queued/include/queued/QueuedUser.h @@ -45,7 +45,6 @@ class QueuedUser : public QObject Q_PROPERTY(uint permissions READ permissions WRITE setPermissions) // limits Q_PROPERTY(QString limits READ limits WRITE setLimits) - Q_PROPERTY(QueuedLimits::Limits nativeLimtis READ nativeLimits) public: /** @@ -89,12 +88,12 @@ public: // methods /** * @brief add permissions to user - * @param _permissions - * new user permissions + * @param _permission + * new user permission * @return current user permissions */ QueuedEnums::Permissions - addPermissions(const QueuedEnums::Permissions _permissions); + addPermission(const QueuedEnums::Permission _permission); /** * @brief generates SHA512 hash from given password * @param _password @@ -123,12 +122,12 @@ public: bool isPasswordValid(const QString &_password) const; /** * @brief remove permissions from user - * @param _permissions - * permissions to remove + * @param _permission + * permission to remove * @return current user permissions */ QueuedEnums::Permissions - removePermissions(const QueuedEnums::Permissions _permissions); + removePermission(const QueuedEnums::Permission _permission); // main properties /** * @brief user email diff --git a/sources/queued/src/QueuedCore.cpp b/sources/queued/src/QueuedCore.cpp index cefc160..af79f59 100644 --- a/sources/queued/src/QueuedCore.cpp +++ b/sources/queued/src/QueuedCore.cpp @@ -91,7 +91,7 @@ QueuedCore::addTask(const QString &_command, const QStringList &_arguments, // check permissions bool isAdmin = m_users->authorize(_token, QueuedEnums::Permission::Admin); - bool isUser = m_users->authorize(_token, QueuedEnums::Permission::JobOwner); + bool isUser = m_users->authorize(_token, QueuedEnums::Permission::Job); if (userAuthId == actualUserId) { // it means that user places task as own one if (!isUser) { @@ -130,8 +130,8 @@ long long QueuedCore::addUser(const QString &_name, const QString &_email, } // check if already exists - auto user = m_users->user(_name, false); - if (user) { + auto userObj = user(_name); + if (userObj) { qCWarning(LOG_LIB) << "User" << _name << "already exists"; return -1; } @@ -214,7 +214,7 @@ bool QueuedCore::editTask(const long long _id, const QVariantHash &_taskData, } long long userAuthId = authUser->index(); bool isAdmin = m_users->authorize(_token, QueuedEnums::Permission::Admin); - bool isUser = m_users->authorize(_token, QueuedEnums::Permission::JobOwner); + bool isUser = m_users->authorize(_token, QueuedEnums::Permission::Job); if (userAuthId == task->user()) { // it means that user edits own task if (!isUser) { @@ -254,8 +254,8 @@ bool QueuedCore::editUser(const long long _id, const QVariantHash &_userData, { qCDebug(LOG_LIB) << "Edit user with ID" << _id; - auto user = m_users->user(_id); - if (!user) { + auto userObj = user(_id); + if (!userObj) { qCWarning(LOG_LIB) << "Could not find user with ID" << _id; return false; } @@ -411,7 +411,7 @@ bool QueuedCore::stopTask(const long long _id, const QString &_token) } long long userAuthId = authUser->index(); bool isAdmin = m_users->authorize(_token, QueuedEnums::Permission::Admin); - bool isUser = m_users->authorize(_token, QueuedEnums::Permission::JobOwner); + bool isUser = m_users->authorize(_token, QueuedEnums::Permission::Job); if (userAuthId == task->user()) { // it means that user edits own task if (!isUser) { @@ -454,6 +454,17 @@ const QueuedUser *QueuedCore::user(const long long _id) } +/** + * @fn user + */ +const QueuedUser *QueuedCore::user(const QString &_name) +{ + qCDebug(LOG_LIB) << "Get user by name" << _name; + + return m_users->user(_name, false); +} + + /** * @fn deinit */ @@ -789,13 +800,13 @@ long long QueuedCore::addTaskPrivate(const QString &_command, // add to database auto ids = m_users->ids(_userId); - auto user = m_users->user(_userId); - if (!user) { + auto userObj = user(_userId); + if (!userObj) { qCWarning(LOG_LIB) << "Could not find task user" << _userId; return false; } auto taskLimits = QueuedLimits::minimalLimits( - _limits, user->nativeLimits(), + _limits, userObj->nativeLimits(), QueuedLimits::Limits( m_advancedSettings->get(QueuedConfig::QueuedSettings::DefaultLimits) .toString())); @@ -929,8 +940,7 @@ bool QueuedCore::editTaskPrivate(const long long _id, // modify values stored in memory for (auto &property : _taskData.keys()) - task->setProperty(property.toLocal8Bit().constData(), - _taskData[property]); + task->setProperty(qPrintable(property), _taskData[property]); return true; } @@ -944,8 +954,8 @@ bool QueuedCore::editUserPrivate(const long long _id, { qCDebug(LOG_LIB) << "Edit user with ID" << _id; - auto user = m_users->user(_id); - if (!user) { + auto userObj = m_users->user(_id); + if (!userObj) { qCWarning(LOG_LIB) << "Could not find user with ID" << _id; return false; }; @@ -960,8 +970,7 @@ bool QueuedCore::editUserPrivate(const long long _id, // modify values stored in memory for (auto &property : _userData.keys()) - user->setProperty(property.toLocal8Bit().constData(), - _userData[property]); + userObj->setProperty(qPrintable(property), _userData[property]); return true; } @@ -977,19 +986,17 @@ bool QueuedCore::editUserPermissionPrivate( qCDebug(LOG_LIB) << "Edit permissions" << static_cast(_permission) << "for user" << _id << "add" << _add; - auto user = m_users->user(_id); - if (!user) { + auto userObj = m_users->user(_id); + if (!userObj) { qCWarning(LOG_LIB) << "Could not find user with ID" << _id; return false; } // edit runtime permissions to get value - if (_add) - user->addPermissions(_permission); - else - user->removePermissions(_permission); - uint permissions = user->permissions(); - qCInfo(LOG_LIB) << "New user permissions"; + auto perms = _add ? userObj->addPermission(_permission) + : userObj->removePermission(_permission); + uint permissions = static_cast(perms); + qCInfo(LOG_LIB) << "New user permissions" << perms << permissions; // modify in database now QVariantHash payload = {{"permissions", permissions}}; @@ -999,9 +1006,9 @@ bool QueuedCore::editUserPermissionPrivate( << "in database, do not edit it in memory"; // rollback in-memory values if (_add) - user->removePermissions(_permission); + userObj->removePermission(_permission); else - user->addPermissions(_permission); + userObj->addPermission(_permission); return false; } diff --git a/sources/queued/src/QueuedCoreAdaptor.cpp b/sources/queued/src/QueuedCoreAdaptor.cpp index c5435b3..0f815a0 100644 --- a/sources/queued/src/QueuedCoreAdaptor.cpp +++ b/sources/queued/src/QueuedCoreAdaptor.cpp @@ -36,7 +36,7 @@ bool QueuedCoreAdaptor::auth(const QString &_token) return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "TryAuth", args) - .at(0) + .first() .toBool(); } @@ -52,7 +52,7 @@ QString QueuedCoreAdaptor::auth(const QString &_name, const QString &_password) return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "Auth", args) - .at(0) + .first() .toString(); } @@ -71,7 +71,7 @@ bool QueuedCoreAdaptor::sendOptionEdit(const QString &_key, return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "OptionEdit", args) - .at(0) + .first() .toBool(); } @@ -88,7 +88,7 @@ bool QueuedCoreAdaptor::sendPluginAdd(const QString &_plugin, return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "PluginAdd", args) - .at(0) + .first() .toBool(); } @@ -105,7 +105,7 @@ bool QueuedCoreAdaptor::sendPluginRemove(const QString &_plugin, return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "PluginRemove", args) - .at(0) + .first() .toBool(); } @@ -133,7 +133,7 @@ long long QueuedCoreAdaptor::sendTaskAdd( return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "TaskAdd", args) - .at(0) + .first() .toLongLong(); } @@ -166,7 +166,7 @@ bool QueuedCoreAdaptor::sendTaskEdit( return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "TaskEdit", args) - .at(0) + .first() .toBool(); } @@ -183,7 +183,7 @@ bool QueuedCoreAdaptor::sendTaskStart(const long long _id, return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "TaskStart", args) - .at(0) + .first() .toBool(); } @@ -199,7 +199,7 @@ bool QueuedCoreAdaptor::sendTaskStop(const long long _id, const QString &_token) return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "TaskStop", args) - .at(0) + .first() .toBool(); } @@ -227,7 +227,7 @@ long long QueuedCoreAdaptor::sendUserAdd( return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "UserAdd", args) - .at(0) + .first() .toLongLong(); } @@ -255,7 +255,7 @@ bool QueuedCoreAdaptor::sendUserEdit( return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "UserEdit", args) - .at(0) + .first() .toBool(); } @@ -274,7 +274,7 @@ bool QueuedCoreAdaptor::sendUserPermissionAdd( return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "UserPermissionAdd", args) - .at(0) + .first() .toBool(); } @@ -293,7 +293,7 @@ bool QueuedCoreAdaptor::sendUserPermissionRemove( return sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_OBJECT_PATH, QueuedConfig::DBUS_SERVICE, "UserPermissionRemove", args) - .at(0) + .first() .toBool(); } @@ -309,7 +309,7 @@ QVariant QueuedCoreAdaptor::getOption(const QString &_property) return toNativeType(sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_PROPERTY_PATH, QueuedConfig::DBUS_SERVICE, "Option", args) - .at(0)); + .first()); } @@ -325,7 +325,7 @@ QVariant QueuedCoreAdaptor::getTask(const long long _id, return toNativeType(sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_PROPERTY_PATH, QueuedConfig::DBUS_SERVICE, "Task", args) - .at(0)); + .first()); } @@ -341,7 +341,23 @@ QVariant QueuedCoreAdaptor::getUser(const long long _id, return toNativeType(sendRequest(QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_PROPERTY_PATH, QueuedConfig::DBUS_SERVICE, "User", args) - .at(0)); + .first()); +} + + +/** + * @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(); } diff --git a/sources/queued/src/QueuedCoreInterface.cpp b/sources/queued/src/QueuedCoreInterface.cpp index 5c64b11..fc4d61c 100644 --- a/sources/queued/src/QueuedCoreInterface.cpp +++ b/sources/queued/src/QueuedCoreInterface.cpp @@ -204,18 +204,15 @@ qlonglong QueuedCoreInterface::UserAdd(const QString &name, const QString &email, const QString &password, const uint permissions, const qlonglong cpu, const qlonglong gpu, - const QString &memory, const QString &gpumemory, - const QString &storage, const QString &token) + const qlonglong memory, const qlonglong gpumemory, + const qlonglong storage, const QString &token) { qCDebug(LOG_DBUS) << "Add new user with paramaters" << name << email << permissions; return m_core->addUser( name, email, password, permissions, - QueuedLimits::Limits(cpu, gpu, QueuedLimits::convertMemory(memory), - QueuedLimits::convertMemory(gpumemory), - QueuedLimits::convertMemory(storage)), - token); + QueuedLimits::Limits(cpu, gpu, memory, gpumemory, storage), token); } @@ -225,9 +222,10 @@ QueuedCoreInterface::UserAdd(const QString &name, const QString &email, bool QueuedCoreInterface::UserEdit(const qlonglong id, const QString &name, const QString &password, const QString &email, const qlonglong cpu, - const qlonglong gpu, const QString &memory, - const QString &gpumemory, - const QString &storage, const QString &token) + const qlonglong gpu, const qlonglong memory, + const qlonglong gpumemory, + const qlonglong storage, + const QString &token) { qCDebug(LOG_DBUS) << "Edit user" << id << name << email << cpu << gpu << memory << gpumemory << storage; @@ -254,11 +252,11 @@ bool QueuedCoreInterface::UserEdit(const qlonglong id, const QString &name, if (gpu > -1) limits.gpu = gpu; if (memory > -1) - limits.memory = QueuedLimits::convertMemory(memory); + limits.memory = memory; if (gpumemory > -1) - limits.gpumemory = QueuedLimits::convertMemory(gpumemory); + limits.gpumemory = gpumemory; if (storage > -1) - limits.storage = QueuedLimits::convertMemory(storage); + limits.storage = storage; data[QString("limits")] = limits.toString(); return m_core->editUser(id, data, token); diff --git a/sources/queued/src/QueuedCorePropertiesInterface.cpp b/sources/queued/src/QueuedCorePropertiesInterface.cpp index e10a054..c68b547 100644 --- a/sources/queued/src/QueuedCorePropertiesInterface.cpp +++ b/sources/queued/src/QueuedCorePropertiesInterface.cpp @@ -23,6 +23,8 @@ #include "queued/Queued.h" +#include + /** * @class QueuedCorePropertiesInterface @@ -72,7 +74,11 @@ QDBusVariant QueuedCorePropertiesInterface::Task(const long long id, return QDBusVariant(); } - return QDBusVariant(task->property(property.toLocal8Bit().constData())); + if (property.isEmpty()) + return QDBusVariant( + QVariant::fromValue(getProperties(task))); + else + return QDBusVariant(task->property(qPrintable(property))); } @@ -90,5 +96,50 @@ QDBusVariant QueuedCorePropertiesInterface::User(const long long id, return QDBusVariant(); } - return QDBusVariant(user->property(property.toLocal8Bit().constData())); + if (property.isEmpty()) + return QDBusVariant( + QVariant::fromValue(getProperties(user))); + else + return QDBusVariant(user->property(qPrintable(property))); +} + + +/** + * @fn UserIdByName + */ +qlonglong QueuedCorePropertiesInterface::UserIdByName(const QString &name) +{ + qCDebug(LOG_DBUS) << "Look for user ID" << name; + + auto user = m_core->user(name); + if (!user) { + qCWarning(LOG_DBUS) << "Could not find user" << name; + return -1; + } + + return user->index(); +} + + +/** + * @fn getProperties + */ +QVariantHash +QueuedCorePropertiesInterface::getProperties(const QObject *_object) +{ + qCDebug(LOG_DBUS) << "Get all properties from" << _object->objectName(); + + QVariantHash result; + + auto meta = _object->metaObject(); + int count = meta->propertyCount(); + for (int i = 0; i < count; i++) { + QMetaProperty prop = meta->property(i); + auto name = prop.name(); + if (QString(name) == "objectName") + continue; + result[name] = _object->property(name); + } + + return result; } diff --git a/sources/queued/src/QueuedPluginManager.cpp b/sources/queued/src/QueuedPluginManager.cpp index 2a448dd..937767d 100644 --- a/sources/queued/src/QueuedPluginManager.cpp +++ b/sources/queued/src/QueuedPluginManager.cpp @@ -67,6 +67,10 @@ QueuedPluginManager::convertOptionName(const QString &_key) qCDebug(LOG_PL) << "Convert option name" << _key; QStringList fields = _key.split('.'); + if (fields.count() < 3) { + qCWarning(LOG_PL) << "Invalid option name" << _key; + return {"", ""}; + } // Plugin. fields.takeFirst(); // plugin name diff --git a/sources/queued/src/QueuedProcess.cpp b/sources/queued/src/QueuedProcess.cpp index 10537d9..d15d42b 100644 --- a/sources/queued/src/QueuedProcess.cpp +++ b/sources/queued/src/QueuedProcess.cpp @@ -163,6 +163,24 @@ QString QueuedProcess::limits() const } +/** + * @fn logError + */ +QString QueuedProcess::logError() const +{ + return QString("%1/%2-err.log").arg(workDirectory()).arg(name()); +} + + +/** + * @fn logOutput + */ +QString QueuedProcess::logOutput() const +{ + return QString("%1/%2-out.log").arg(workDirectory()).arg(name()); +} + + /** * @fn nativeLimits */ @@ -274,7 +292,7 @@ void QueuedProcess::setGid(const uint _gid) /** - * setLimits + * @fn setLimits */ void QueuedProcess::setLimits(const QString &_limits) { @@ -285,6 +303,24 @@ void QueuedProcess::setLimits(const QString &_limits) } +/** + * @fn setLogError + */ +void QueuedProcess::setLogError(const QString &) +{ + setStandardErrorFile(logError(), QIODevice::Append); +} + + +/** + * @fn setLogOutput + */ +void QueuedProcess::setLogOutput(const QString &) +{ + setStandardOutputFile(logOutput(), QIODevice::Append); +} + + /** * @fn setNice */ @@ -350,12 +386,8 @@ void QueuedProcess::setWorkDirectory(const QString &_workDirectory) qCDebug(LOG_LIB) << "Set working directory to" << _workDirectory; m_definitions.workingDirectory = _workDirectory; - setStandardErrorFile( - QString("%1/%2-err.log").arg(_workDirectory).arg(name()), - QIODevice::Append); - setStandardOutputFile( - QString("%1/%2-out.log").arg(_workDirectory).arg(name()), - QIODevice::Append); + setLogError(""); + setLogOutput(""); setWorkingDirectory(_workDirectory); } diff --git a/sources/queued/src/QueuedProcessManager.cpp b/sources/queued/src/QueuedProcessManager.cpp index 75d791f..e665e38 100644 --- a/sources/queued/src/QueuedProcessManager.cpp +++ b/sources/queued/src/QueuedProcessManager.cpp @@ -22,7 +22,10 @@ #include "queued/Queued.h" -#include + +extern "C" { +#include +} /** @@ -361,6 +364,10 @@ void QueuedProcessManager::taskFinished(const int _exitCode, auto pr = process(_index); if (pr) { + // change log rights to valid one + ::chown(qPrintable(pr->logError()), pr->uid(), pr->gid()); + ::chown(qPrintable(pr->logOutput()), pr->uid(), pr->gid()); + // remove task auto endTime = QDateTime::currentDateTimeUtc(); remove(_index); emit(taskStopTimeReceived(_index, endTime)); diff --git a/sources/queued/src/QueuedUser.cpp b/sources/queued/src/QueuedUser.cpp index 46ca8ec..98c41e6 100644 --- a/sources/queued/src/QueuedUser.cpp +++ b/sources/queued/src/QueuedUser.cpp @@ -62,13 +62,13 @@ QueuedUser::~QueuedUser() * @fn addPermissions */ QueuedEnums::Permissions -QueuedUser::addPermissions(const QueuedEnums::Permissions _permissions) +QueuedUser::addPermission(const QueuedEnums::Permission _permission) { - qCDebug(LOG_LIB) << "Add user permission" << _permissions; + qCDebug(LOG_LIB) << "Add user permission" << static_cast(_permission); setPermissions( static_cast(m_definitions.permissions) - & _permissions); + | _permission); return static_cast(m_definitions.permissions); } @@ -108,7 +108,7 @@ QPair QueuedUser::ids() { QPair system = {1, 1}; - auto pwd = ::getpwnam(name().toLocal8Bit().constData()); + auto pwd = ::getpwnam(qPrintable(name())); if (!pwd) { qCWarning(LOG_LIB) << "No user found by name" << name(); return system; @@ -129,13 +129,15 @@ bool QueuedUser::isPasswordValid(const QString &_password) const QueuedEnums::Permissions -QueuedUser::removePermissions(const QueuedEnums::Permissions _permissions) +QueuedUser::removePermission(const QueuedEnums::Permission _permission) { - qCDebug(LOG_LIB) << "Remove user permission" << _permissions; + qCDebug(LOG_LIB) << "Remove user permission" + << static_cast(_permission); - setPermissions( - static_cast(m_definitions.permissions) - & ~_permissions); + if (hasPermission(_permission)) + setPermissions( + static_cast(m_definitions.permissions) + ^ _permission); return static_cast(m_definitions.permissions); } diff --git a/sources/queuedctl/src/QueuedctlAuth.cpp b/sources/queuedctl/src/QueuedctlAuth.cpp index 349b8a7..3dfc5ed 100644 --- a/sources/queuedctl/src/QueuedctlAuth.cpp +++ b/sources/queuedctl/src/QueuedctlAuth.cpp @@ -20,29 +20,14 @@ #include -extern "C" { -#include -#include -} +#include "QueuedctlUser.h" QString QueuedctlAuth::auth(const QString &_user) { qCDebug(LOG_APP) << "Auth as user" << _user; - // read password - // do not show input characters - struct termios tty; - ::tcgetattr(STDIN_FILENO, &tty); - tty.c_lflag &= ~ECHO; - tcsetattr(STDIN_FILENO, TCSANOW, &tty); - - qInfo() << "Password for" << _user; - QTextStream stream(stdin); - QString password; - stream >> password; - - return QueuedCoreAdaptor::auth(_user, password); + return QueuedCoreAdaptor::auth(_user, QueuedctlUser::getPassword()); } @@ -51,12 +36,12 @@ QString QueuedctlAuth::getToken(const QString &_cache, const QString &_user) qCDebug(LOG_APP) << "Get token using cache" << _cache << "and user" << _user; - QString tokenId = token(_cache); + QString tokenId = token(_user, _cache); if (tryAuth(tokenId)) { return tokenId; } else { tokenId = auth(_user); - setToken(tokenId, _cache); + setToken(tokenId, _user, _cache); return getToken(_cache, _user); } } @@ -67,12 +52,13 @@ void QueuedctlAuth::parser(QCommandLineParser &_parser) } -void QueuedctlAuth::setToken(const QString &_token, const QString &_cache) +void QueuedctlAuth::setToken(const QString &_token, const QString &_user, + const QString &_cache) { - qCDebug(LOG_APP) << "Save token to" << _cache; + qCDebug(LOG_APP) << "Save token to" << _cache << "from user" << _user; QSettings settings(_cache, QSettings::IniFormat); - settings.beginGroup("queuedctl"); + settings.beginGroup(QString("queuedctl/%1").arg(_user)); settings.setValue("Token", _token); settings.endGroup(); @@ -80,14 +66,14 @@ void QueuedctlAuth::setToken(const QString &_token, const QString &_cache) } -QString QueuedctlAuth::token(const QString &_cache) +QString QueuedctlAuth::token(const QString &_user, const QString &_cache) { - qCDebug(LOG_APP) << "Load token from" << _cache; + qCDebug(LOG_APP) << "Load token from" << _cache << "for user" << _user; QString token; QSettings settings(_cache, QSettings::IniFormat); - settings.beginGroup("queuedctl"); + settings.beginGroup(QString("queuedctl/%1").arg(_user)); token = settings.value("Token").toString(); settings.endGroup(); diff --git a/sources/queuedctl/src/QueuedctlAuth.h b/sources/queuedctl/src/QueuedctlAuth.h index b2f205a..6f8ade2 100644 --- a/sources/queuedctl/src/QueuedctlAuth.h +++ b/sources/queuedctl/src/QueuedctlAuth.h @@ -25,8 +25,9 @@ namespace QueuedctlAuth QString auth(const QString &_user); QString getToken(const QString &_cache, const QString &_user); void parser(QCommandLineParser &_parser); -void setToken(const QString &_token, const QString &_cache); -QString token(const QString &_cache); +void setToken(const QString &_token, const QString &_user, + const QString &_cache); +QString token(const QString &_user, const QString &_cache); bool tryAuth(const QString &_token); }; diff --git a/sources/queuedctl/src/QueuedctlCommon.cpp b/sources/queuedctl/src/QueuedctlCommon.cpp index cc67330..629a52a 100644 --- a/sources/queuedctl/src/QueuedctlCommon.cpp +++ b/sources/queuedctl/src/QueuedctlCommon.cpp @@ -20,7 +20,10 @@ #include "QueuedctlAuth.h" #include "QueuedctlOption.h" +#include "QueuedctlPermissions.h" +#include "QueuedctlPlugins.h" #include "QueuedctlTask.h" +#include "QueuedctlUser.h" void QueuedctlCommon::checkArgs(const QStringList &_args, const int _count, @@ -50,6 +53,21 @@ QString QueuedctlCommon::commandsHelp() } +QString QueuedctlCommon::hashToString(const QVariantHash &_hash) +{ + qCDebug(LOG_APP) << "Convert hash to string" << _hash; + + QStringList output; + QStringList keys = _hash.keys(); + keys.sort(); + for (auto &key : keys) + output += QString("%1: %2").arg(key).arg( + _hash[key].toString().replace('\n', ' ')); + + return output.join('\n'); +} + + void QueuedctlCommon::preprocess(const QStringList &_args, QCommandLineParser &_parser) { @@ -77,6 +95,16 @@ void QueuedctlCommon::preprocess(const QStringList &_args, case QueuedctlArgument::OptionSet: QueuedctlOption::parserSet(_parser); break; + case QueuedctlArgument::PermissionAdd: + case QueuedctlArgument::PermissionRemove: + QueuedctlPermissions::parser(_parser); + break; + case QueuedctlArgument::PluginAdd: + case QueuedctlArgument::PluginRemove: + QueuedctlPlugins::parser(_parser); + break; + case QueuedctlArgument::PluginList: + break; case QueuedctlArgument::TaskAdd: QueuedctlTask::parserAdd(_parser); break; @@ -86,11 +114,18 @@ void QueuedctlCommon::preprocess(const QStringList &_args, case QueuedctlArgument::TaskSet: QueuedctlTask::parserSet(_parser); break; + case QueuedctlArgument::TaskStart: + case QueuedctlArgument::TaskStop: + QueuedctlTask::parserStart(_parser); + break; case QueuedctlArgument::UserAdd: + QueuedctlUser::parserAdd(_parser); break; case QueuedctlArgument::UserGet: + QueuedctlUser::parserGet(_parser); break; case QueuedctlArgument::UserSet: + QueuedctlUser::parserSet(_parser); break; case QueuedctlArgument::Invalid: checkArgs(_args, -1, _parser); @@ -129,7 +164,7 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, QString token = QueuedctlAuth::auth(_user); result.status = !token.isEmpty(); if (result.status) - QueuedctlAuth::setToken(token, _cache); + QueuedctlAuth::setToken(token, _user, _cache); break; } case QueuedctlArgument::OptionGet: { @@ -150,6 +185,61 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, .arg(args.at(1), args.at(2)); break; } + case QueuedctlArgument::PermissionAdd: { + auto userId = QueuedctlUser::getUserId(args.at(1)); + QString token = QueuedctlAuth::getToken(_cache, _user); + result.status + = QueuedctlPermissions::addPermission(userId, args.at(2), token); + if (result.status) + result.output = QString("Add permission %2 to user %1") + .arg(args.at(1)) + .arg(args.at(2)); + else + result.output = QString("Could not add permission %2 to user %1") + .arg(args.at(1)) + .arg(args.at(2)); + break; + } + case QueuedctlArgument::PermissionRemove: { + auto userId = QueuedctlUser::getUserId(args.at(1)); + QString token = QueuedctlAuth::getToken(_cache, _user); + result.status + = QueuedctlPermissions::removePermission(userId, args.at(2), token); + if (result.status) + result.output = QString("Remove permission %2 from user %1") + .arg(args.at(1)) + .arg(args.at(2)); + else + result.output + = QString("Could not remove permission %2 from user %1") + .arg(args.at(1)) + .arg(args.at(2)); + break; + } + case QueuedctlArgument::PluginAdd: { + QString token = QueuedctlAuth::getToken(_cache, _user); + result.status = QueuedctlPlugins::addPlugin(args.at(1), token); + if (result.status) + result.output = QString("Add plugin %1").arg(args.at(1)); + else + result.output = QString("Could not add plugin %1").arg(args.at(1)); + break; + } + case QueuedctlArgument::PluginList: { + result.status = true; + result.output = QueuedctlPlugins::listPlugins().join('\n'); + break; + } + case QueuedctlArgument::PluginRemove: { + QString token = QueuedctlAuth::getToken(_cache, _user); + result.status = QueuedctlPlugins::removePlugin(args.at(1), token); + if (result.status) + result.output = QString("Remove plugin %1").arg(args.at(1)); + else + result.output + = QString("Could not remove plugin %1").arg(args.at(1)); + break; + } case QueuedctlArgument::TaskAdd: { QString token = QueuedctlAuth::getToken(_cache, _user); auto definitions = QueuedctlTask::getDefinitions(_parser, false); @@ -165,7 +255,8 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, QVariant value = QueuedctlTask::getTask(args.at(1).toLongLong(), args.at(2)); result.status = value.isValid(); - result.output = value.toString(); + result.output = args.at(2).isEmpty() ? hashToString(value.toHash()) + : value.toString(); break; } case QueuedctlArgument::TaskSet: { @@ -175,13 +266,41 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, definitions, token); break; } + case QueuedctlArgument::TaskStart: { + QString token = QueuedctlAuth::getToken(_cache, _user); + result.status + = QueuedctlTask::startTask(args.at(1).toLongLong(), token); + break; + } + case QueuedctlArgument::TaskStop: { + QString token = QueuedctlAuth::getToken(_cache, _user); + result.status = QueuedctlTask::stopTask(args.at(1).toLongLong(), token); + break; + } case QueuedctlArgument::UserAdd: { + QString token = QueuedctlAuth::getToken(_cache, _user); + auto definitions = QueuedctlUser::getDefinitions(_parser, false); + long long id = QueuedctlUser::addUser(definitions, token); + result.status = (id > 0); + if (result.status) + result.output = QString("User %1 added").arg(id); + else + result.output = QString("Could not add user"); break; } case QueuedctlArgument::UserGet: { + auto userId = QueuedctlUser::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()) + : value.toString(); break; } case QueuedctlArgument::UserSet: { + auto userId = QueuedctlUser::getUserId(args.at(1)); + QString token = QueuedctlAuth::getToken(_cache, _user); + auto definitions = QueuedctlUser::getDefinitions(_parser, true); + result.status = QueuedctlUser::setUser(userId, definitions, token); break; } case QueuedctlArgument::Invalid: { diff --git a/sources/queuedctl/src/QueuedctlCommon.h b/sources/queuedctl/src/QueuedctlCommon.h index 7dfc7ec..448ad07 100644 --- a/sources/queuedctl/src/QueuedctlCommon.h +++ b/sources/queuedctl/src/QueuedctlCommon.h @@ -28,9 +28,16 @@ enum class QueuedctlArgument { Auth, OptionGet, OptionSet, + PermissionAdd, + PermissionRemove, + PluginAdd, + PluginList, + PluginRemove, TaskAdd, TaskGet, TaskSet, + TaskStart, + TaskStop, UserAdd, UserGet, UserSet @@ -44,20 +51,32 @@ typedef struct { QString description; int positionalArgsCount; } QueuedctlArgumentInfo; -const QHash QueuedctlArguments - = {{"auth", {QueuedctlArgument::Auth, "Gets new auth token.", 1}}, - {"option-get", {QueuedctlArgument::OptionGet, "Gets option value.", 2}}, - {"option-set", {QueuedctlArgument::OptionSet, "Sets option value.", 3}}, - {"task-add", {QueuedctlArgument::TaskAdd, "Adds new task.", 2}}, - {"task-get", {QueuedctlArgument::TaskGet, "Gets task properties.", 3}}, - {"task-set", {QueuedctlArgument::TaskSet, "Sets task properties.", 2}}, - {"user-add", {QueuedctlArgument::UserAdd, "Adds new user."}}, - {"user-get", {QueuedctlArgument::UserGet, "Gets user properties."}}, - {"user-set", {QueuedctlArgument::UserSet, "Sets user properties."}}}; +const QHash QueuedctlArguments = { + {"auth", {QueuedctlArgument::Auth, "Gets new auth token.", 1}}, + {"option-get", {QueuedctlArgument::OptionGet, "Gets option value.", 2}}, + {"option-set", {QueuedctlArgument::OptionSet, "Sets option value.", 3}}, + {"perm-add", + {QueuedctlArgument::PermissionAdd, "Sets user permission.", 3}}, + {"perm-remove", + {QueuedctlArgument::PermissionRemove, "Removes user permission.", 3}}, + {"plugin-add", {QueuedctlArgument::PluginAdd, "Adds plugin to load.", 2}}, + {"plugin-list", + {QueuedctlArgument::PluginList, "Shows enabled plugins.", 1}}, + {"plugin-remove", + {QueuedctlArgument::PluginRemove, "Removes plugin to load.", 2}}, + {"task-add", {QueuedctlArgument::TaskAdd, "Adds new task.", 2}}, + {"task-get", {QueuedctlArgument::TaskGet, "Gets task properties.", 3}}, + {"task-set", {QueuedctlArgument::TaskSet, "Sets task properties.", 2}}, + {"task-start", {QueuedctlArgument::TaskStart, "Starts task.", 2}}, + {"task-stop", {QueuedctlArgument::TaskStop, "Stops task.", 2}}, + {"user-add", {QueuedctlArgument::UserAdd, "Adds new user.", 2}}, + {"user-get", {QueuedctlArgument::UserGet, "Gets user properties.", 3}}, + {"user-set", {QueuedctlArgument::UserSet, "Sets user properties.", 2}}}; // methods void checkArgs(const QStringList &_args, const int _count, QCommandLineParser &_parser); QString commandsHelp(); +QString hashToString(const QVariantHash &_hash); void preprocess(const QStringList &_args, QCommandLineParser &_parser); void print(const QueuedctlResult &_result); QueuedctlResult process(QCommandLineParser &_parser, const QString &_cache, diff --git a/sources/queuedctl/src/QueuedctlPermissions.cpp b/sources/queuedctl/src/QueuedctlPermissions.cpp new file mode 100644 index 0000000..7f88a09 --- /dev/null +++ b/sources/queuedctl/src/QueuedctlPermissions.cpp @@ -0,0 +1,59 @@ +/* + * 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 "QueuedctlPermissions.h" + +#include + + +bool QueuedctlPermissions::addPermission(const long long _id, + const QString &_permission, + const QString &_token) +{ + qCDebug(LOG_APP) << "Add permission" << _permission << "to" << _id; + + auto permission = QueuedEnums::stringToPermission(_permission); + + if (permission != QueuedEnums::Permission::Invalid) + return QueuedCoreAdaptor::sendUserPermissionAdd(_id, permission, + _token); + else + return false; +} + + +bool QueuedctlPermissions::removePermission(const long long _id, + const QString &_permission, + const QString &_token) +{ + qCDebug(LOG_APP) << "Remove permission" << _permission << "to" << _id; + + auto permission = QueuedEnums::stringToPermission(_permission); + + if (permission != QueuedEnums::Permission::Invalid) + return QueuedCoreAdaptor::sendUserPermissionRemove(_id, permission, + _token); + else + return false; +} + + +void QueuedctlPermissions::parser(QCommandLineParser &_parser) +{ + _parser.addPositionalArgument("user", "User ID.", ""); + _parser.addPositionalArgument("permission", "Permission name.", + ""); +} diff --git a/sources/queuedctl/src/QueuedctlPermissions.h b/sources/queuedctl/src/QueuedctlPermissions.h new file mode 100644 index 0000000..6c13925 --- /dev/null +++ b/sources/queuedctl/src/QueuedctlPermissions.h @@ -0,0 +1,33 @@ +/* + * 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 QUEUEDCTLPERMISSIONS_H +#define QUEUEDCTLPERMISSIONS_H + +#include + + +namespace QueuedctlPermissions +{ +bool addPermission(const long long _id, const QString &_permission, + const QString &_token); +bool removePermission(const long long _id, const QString &_permission, + const QString &_token); +void parser(QCommandLineParser &_parser); +}; + + +#endif /* QUEUEDCTLPERMISSIONS_H */ diff --git a/sources/queuedctl/src/QueuedctlPlugins.cpp b/sources/queuedctl/src/QueuedctlPlugins.cpp new file mode 100644 index 0000000..325695d --- /dev/null +++ b/sources/queuedctl/src/QueuedctlPlugins.cpp @@ -0,0 +1,52 @@ +/* + * 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 "QueuedctlPlugins.h" + +#include + + +bool QueuedctlPlugins::addPlugin(const QString &_plugin, const QString &_token) +{ + qCDebug(LOG_APP) << "Add plugin" << _plugin; + + return QueuedCoreAdaptor::sendPluginAdd(_plugin, _token); +} + + +QStringList QueuedctlPlugins::listPlugins() +{ + return QueuedCoreAdaptor::getOption( + QueuedAdvancedSettings::internalId( + QueuedConfig::QueuedSettings::Plugins)) + .toString() + .split('\n'); +} + + +bool QueuedctlPlugins::removePlugin(const QString &_plugin, + const QString &_token) +{ + qCDebug(LOG_APP) << "Remove plugin" << _plugin; + + return QueuedCoreAdaptor::sendPluginRemove(_plugin, _token); +} + + +void QueuedctlPlugins::parser(QCommandLineParser &_parser) +{ + _parser.addPositionalArgument("plugin", "Plugin name.", ""); +} diff --git a/sources/queuedctl/src/QueuedctlPlugins.h b/sources/queuedctl/src/QueuedctlPlugins.h new file mode 100644 index 0000000..be85542 --- /dev/null +++ b/sources/queuedctl/src/QueuedctlPlugins.h @@ -0,0 +1,32 @@ +/* + * 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 QUEUEDCTLPLUGINS_H +#define QUEUEDCTLPLUGINS_H + +#include + + +namespace QueuedctlPlugins +{ +bool addPlugin(const QString &_plugin, const QString &_token); +QStringList listPlugins(); +bool removePlugin(const QString &_plugin, const QString &_token); +void parser(QCommandLineParser &_parser); +}; + + +#endif /* QUEUEDCTLPLUGINS_H */ diff --git a/sources/queuedctl/src/QueuedctlTask.cpp b/sources/queuedctl/src/QueuedctlTask.cpp index f5b525c..4d8f68d 100644 --- a/sources/queuedctl/src/QueuedctlTask.cpp +++ b/sources/queuedctl/src/QueuedctlTask.cpp @@ -20,6 +20,12 @@ #include +#include "QueuedctlUser.h" + +extern "C" { +#include +} + long long QueuedctlTask::addTask( const QueuedProcess::QueuedProcessDefinitions &_definitions, @@ -48,7 +54,10 @@ QueuedctlTask::getDefinitions(const QCommandLineParser &_parser, }); definitions.nice = _parser.value("nice").toUInt(); - definitions.user = _parser.value("task-user").toLongLong(); + definitions.user + = _parser.value("task-user").isEmpty() + ? 0 + : QueuedctlUser::getUserId(_parser.value("task-user")); definitions.workingDirectory = _parser.value("directory"); // limits now QueuedLimits::Limits limits( @@ -68,6 +77,9 @@ QueuedctlTask::getDefinitions(const QCommandLineParser &_parser, definitions.startTime = QDateTime::fromString(_parser.value("start"), Qt::ISODate); definitions.uid = _parser.value("uid").toUInt(); + } else { + // queuedctl -- task-add /path/to/application + definitions.command = _parser.positionalArguments().at(1); } return definitions; @@ -78,7 +90,11 @@ QVariant QueuedctlTask::getTask(const long long _id, const QString &_property) { qCDebug(LOG_APP) << "Get property" << _property << "from task" << _id; - return QueuedCoreAdaptor::getTask(_id, _property); + auto value = QueuedCoreAdaptor::getTask(_id, _property); + if (_property.isEmpty()) + return qdbus_cast(value.value()); + else + return value; } @@ -97,8 +113,8 @@ void QueuedctlTask::parserAdd(QCommandLineParser &_parser) "directory", QDir::currentPath()); _parser.addOption(directoryOption); // user - // TODO grab used user ID - QCommandLineOption userOption("task-user", "Task user.", "task-user", "0"); + QCommandLineOption userOption("task-user", "Task user.", "task-user", + ::getlogin()); _parser.addOption(userOption); // nice QCommandLineOption niceOption("nice", "Task nice level.", "nice", "0"); @@ -153,7 +169,7 @@ void QueuedctlTask::parserSet(QCommandLineParser &_parser) "directory", "Command working directory.", "directory", ""); _parser.addOption(directoryOption); // user - QCommandLineOption userOption("task-user", "Task user.", "task-user", "0"); + QCommandLineOption userOption("task-user", "Task user.", "task-user", ""); _parser.addOption(userOption); // nice QCommandLineOption niceOption("nice", "Task nice level.", "nice", "0"); @@ -193,6 +209,12 @@ void QueuedctlTask::parserSet(QCommandLineParser &_parser) } +void QueuedctlTask::parserStart(QCommandLineParser &_parser) +{ + _parser.addPositionalArgument("id", "Task ID.", ""); +} + + bool QueuedctlTask::setTask( const long long _id, const QueuedProcess::QueuedProcessDefinitions &_definitions, @@ -202,3 +224,19 @@ bool QueuedctlTask::setTask( return QueuedCoreAdaptor::sendTaskEdit(_id, _definitions, _token); } + + +bool QueuedctlTask::startTask(const long long _id, const QString &_token) +{ + qCDebug(LOG_APP) << "Start task" << _id; + + return QueuedCoreAdaptor::sendTaskStart(_id, _token); +} + + +bool QueuedctlTask::stopTask(const long long _id, const QString &_token) +{ + qCDebug(LOG_APP) << "Stop task" << _id; + + return QueuedCoreAdaptor::sendTaskStop(_id, _token); +} diff --git a/sources/queuedctl/src/QueuedctlTask.h b/sources/queuedctl/src/QueuedctlTask.h index 5bb95ec..3d82932 100644 --- a/sources/queuedctl/src/QueuedctlTask.h +++ b/sources/queuedctl/src/QueuedctlTask.h @@ -32,9 +32,12 @@ QVariant getTask(const long long _id, const QString &_property); void parserAdd(QCommandLineParser &_parser); void parserGet(QCommandLineParser &_parser); void parserSet(QCommandLineParser &_parser); +void parserStart(QCommandLineParser &_parser); bool setTask(const long long _id, const QueuedProcess::QueuedProcessDefinitions &_definitions, const QString &_token); +bool startTask(const long long _id, const QString &_token); +bool stopTask(const long long _id, const QString &_token); }; diff --git a/sources/queuedctl/src/QueuedctlUser.cpp b/sources/queuedctl/src/QueuedctlUser.cpp new file mode 100644 index 0000000..4876959 --- /dev/null +++ b/sources/queuedctl/src/QueuedctlUser.cpp @@ -0,0 +1,219 @@ +/* + * 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 "QueuedctlUser.h" + +#include + +extern "C" { +#include +#include +} + + +long long +QueuedctlUser::addUser(const QueuedUser::QueuedUserDefinitions &_definitions, + const QString &_token) +{ + qCDebug(LOG_APP) << "Add user" << _definitions.name; + + return QueuedCoreAdaptor::sendUserAdd(_definitions, _token); +} + + +QueuedUser::QueuedUserDefinitions +QueuedctlUser::getDefinitions(const QCommandLineParser &_parser, + const bool _expandAll) +{ + qCDebug(LOG_APP) << "Parse user definitions from parser, expand all" + << _expandAll; + + QueuedUser::QueuedUserDefinitions definitions; + + definitions.email = _parser.value("email"); + definitions.password = _parser.isSet("stdin-password") + ? getPassword() + : _parser.value("password"); + // limits now + QueuedLimits::Limits limits( + _parser.value("limit-cpu").toLongLong(), + _parser.value("limit-gpu").toLongLong(), + QueuedLimits::convertMemory(_parser.value("limit-memory")), + QueuedLimits::convertMemory(_parser.value("limit-gpumemory")), + QueuedLimits::convertMemory(_parser.value("limit-storage"))); + definitions.limits = limits.toString(); + + // all options + if (_expandAll) { + definitions.name = _parser.value("name"); + } else { + definitions.permissions = _parser.value("access").toUInt(); + // queuedctl -- user-add username + definitions.name = _parser.positionalArguments().at(1); + } + + return definitions; +} + + +QString QueuedctlUser::getPassword() +{ + // do not show input characters + struct termios tty; + ::tcgetattr(STDIN_FILENO, &tty); + tty.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &tty); + + qInfo() << "Password"; + QTextStream stream(stdin); + QString password; + stream >> password; + + return password; +} + + +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()); + else + return value; +} + + +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.", ""); + + // permissions + QCommandLineOption accessOption(QStringList() << "a" + << "access", + "User permission.", "access", "0"); + _parser.addOption(accessOption); + // email + QCommandLineOption emailOption(QStringList() << "e" + << "email", + "User email.", "email", ""); + _parser.addOption(emailOption); + // password + QCommandLineOption passwordOption("password", "User password.", "password", + ""); + _parser.addOption(passwordOption); + // password + QCommandLineOption stdinPasswordOption("stdin-password", + "User password from stdin."); + _parser.addOption(stdinPasswordOption); + // cpu limit + QCommandLineOption cpuOption("limit-cpu", "User CPU limit.", "limit-cpu", + "0"); + _parser.addOption(cpuOption); + // gpu limit + QCommandLineOption gpuOption("limit-gpu", "User GPU limit.", "limit-gpu", + "0"); + _parser.addOption(gpuOption); + // memory limit + QCommandLineOption memoryOption("limit-memory", "User memory limit.", + "limit-memory", "0"); + _parser.addOption(memoryOption); + // gpu memory limit + QCommandLineOption gpumemoryOption( + "limit-gpumemory", "User GPU memory limit.", "limit-gpumemory", "0"); + _parser.addOption(gpumemoryOption); + // storage limit + QCommandLineOption storageOption("limit-storage", "User storage limit.", + "limit-storage", "0"); + _parser.addOption(storageOption); +} + + +void QueuedctlUser::parserGet(QCommandLineParser &_parser) +{ + _parser.addPositionalArgument("id", "User ID.", ""); + _parser.addPositionalArgument("property", "User property name.", + ""); +} + + +void QueuedctlUser::parserSet(QCommandLineParser &_parser) +{ + _parser.addPositionalArgument("id", "User ID.", ""); + + // email + QCommandLineOption emailOption(QStringList() << "e" + << "email", + "User email.", "email", ""); + _parser.addOption(emailOption); + // name + QCommandLineOption nameOption(QStringList() << "n" + << "name", + "User name.", "name", ""); + _parser.addOption(nameOption); + // password + QCommandLineOption passwordOption("password", "User password.", "password", + ""); + _parser.addOption(passwordOption); + // password + QCommandLineOption stdinPasswordOption("stdin-password", + "User password from stdin."); + _parser.addOption(stdinPasswordOption); + // cpu limit + QCommandLineOption cpuOption("limit-cpu", "User CPU limit.", "limit-cpu", + "0"); + _parser.addOption(cpuOption); + // gpu limit + QCommandLineOption gpuOption("limit-gpu", "User GPU limit.", "limit-gpu", + "0"); + _parser.addOption(gpuOption); + // memory limit + QCommandLineOption memoryOption("limit-memory", "User memory limit.", + "limit-memory", "0"); + _parser.addOption(memoryOption); + // gpu memory limit + QCommandLineOption gpumemoryOption( + "limit-gpumemory", "User GPU memory limit.", "limit-gpumemory", "0"); + _parser.addOption(gpumemoryOption); + // storage limit + QCommandLineOption storageOption("limit-storage", "User storage limit.", + "limit-storage", "0"); + _parser.addOption(storageOption); +} + + +bool QueuedctlUser::setUser( + const long long _id, const QueuedUser::QueuedUserDefinitions &_definitions, + const QString &_token) +{ + qCDebug(LOG_APP) << "Edit user" << _id; + + return QueuedCoreAdaptor::sendUserEdit(_id, _definitions, _token); +} diff --git a/sources/queuedctl/src/QueuedctlUser.h b/sources/queuedctl/src/QueuedctlUser.h new file mode 100644 index 0000000..2f3a217 --- /dev/null +++ b/sources/queuedctl/src/QueuedctlUser.h @@ -0,0 +1,43 @@ +/* + * 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 QUEUEDCTLUSER_H +#define QUEUEDCTLUSER_H + +#include + +#include + + +namespace QueuedctlUser +{ +long long addUser(const QueuedUser::QueuedUserDefinitions &_definitions, + const QString &_token); +QueuedUser::QueuedUserDefinitions +getDefinitions(const QCommandLineParser &_parser, const bool _expandAll); +QString getPassword(); +QVariant getUser(const long long _id, const QString &_property); +long long getUserId(const QString &_name); +void parserAdd(QCommandLineParser &_parser); +void parserGet(QCommandLineParser &_parser); +void parserSet(QCommandLineParser &_parser); +bool setUser(const long long _id, + const QueuedUser::QueuedUserDefinitions &_definitions, + const QString &_token); +}; + + +#endif /* QUEUEDCTLUSER_H */