more improvements of queuedctl

This commit is contained in:
Evgenii Alekseev 2017-03-16 01:58:50 +03:00
parent f59095dbb0
commit 69fbab45b2
27 changed files with 925 additions and 132 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
};

View File

@ -24,6 +24,8 @@
#ifndef QUEUEDENUMS_H
#define QUEUEDENUMS_H
#include <QHash>
/**
* @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<QString, Permission> 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

View File

@ -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

View File

@ -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

View File

@ -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<int>(_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<uint>(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;
}

View File

@ -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();
}

View File

@ -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);

View File

@ -23,6 +23,8 @@
#include "queued/Queued.h"
#include <QMetaProperty>
/**
* @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<QVariantHash>(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<QVariantHash>(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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -22,7 +22,10 @@
#include "queued/Queued.h"
#include <queued/Queued.h>
extern "C" {
#include <unistd.h>
}
/**
@ -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));

View File

@ -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<uint>(_permission);
setPermissions(
static_cast<QueuedEnums::Permissions>(m_definitions.permissions)
& _permissions);
| _permission);
return static_cast<QueuedEnums::Permissions>(m_definitions.permissions);
}
@ -108,7 +108,7 @@ QPair<uint, uint> QueuedUser::ids()
{
QPair<uint, uint> 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<uint>(_permission);
setPermissions(
static_cast<QueuedEnums::Permissions>(m_definitions.permissions)
& ~_permissions);
if (hasPermission(_permission))
setPermissions(
static_cast<QueuedEnums::Permissions>(m_definitions.permissions)
^ _permission);
return static_cast<QueuedEnums::Permissions>(m_definitions.permissions);
}

View File

@ -20,29 +20,14 @@
#include <queued/Queued.h>
extern "C" {
#include <termios.h>
#include <unistd.h>
}
#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();

View File

@ -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);
};

View File

@ -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: {

View File

@ -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<QString, QueuedctlArgumentInfo> 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<QString, QueuedctlArgumentInfo> 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,

View File

@ -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 <queued/Queued.h>
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.", "<user>");
_parser.addPositionalArgument("permission", "Permission name.",
"<permission>");
}

View File

@ -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 <QCommandLineParser>
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 */

View File

@ -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 <queued/Queued.h>
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.", "<plugin>");
}

View File

@ -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 <QCommandLineParser>
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 */

View File

@ -20,6 +20,12 @@
#include <queued/Queued.h>
#include "QueuedctlUser.h"
extern "C" {
#include <unistd.h>
}
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<QVariantHash>(value.value<QDBusArgument>());
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.", "<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);
}

View File

@ -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);
};

View File

@ -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 <queued/Queued.h>
extern "C" {
#include <termios.h>
#include <unistd.h>
}
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<QVariantHash>(value.value<QDBusArgument>());
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.", "<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.", "<id>");
_parser.addPositionalArgument("property", "User property name.",
"<property>");
}
void QueuedctlUser::parserSet(QCommandLineParser &_parser)
{
_parser.addPositionalArgument("id", "User ID.", "<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);
}

View File

@ -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 <QCommandLineParser>
#include <queued/QueuedUser.h>
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 */