From f59095dbb0936d5916f8ea7a5920e62d3d3a8693 Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Wed, 15 Mar 2017 02:31:25 +0300 Subject: [PATCH] add task helper --- .../queued/include/queued/QueuedCoreAdaptor.h | 2 +- .../include/queued/QueuedCoreInterface.h | 8 +- sources/queued/src/QueuedCoreInterface.cpp | 29 ++--- sources/queuedctl/src/QueuedctlCommon.cpp | 115 ++++++++++++++---- sources/queuedctl/src/QueuedctlCommon.h | 32 ++++- sources/queuedctl/src/QueuedctlTask.cpp | 46 ++++--- sources/queuedctl/src/QueuedctlTask.h | 4 +- sources/queuedctl/src/main.cpp | 14 ++- 8 files changed, 186 insertions(+), 64 deletions(-) diff --git a/sources/queued/include/queued/QueuedCoreAdaptor.h b/sources/queued/include/queued/QueuedCoreAdaptor.h index 17acf6a..41d712a 100644 --- a/sources/queued/include/queued/QueuedCoreAdaptor.h +++ b/sources/queued/include/queued/QueuedCoreAdaptor.h @@ -90,7 +90,7 @@ bool sendPluginRemove(const QString &_plugin, const QString &_token); * process definitions * @param _token * auth user token - * @return task ID or -1 if no task found + * @return task ID or {0, -1} if no task added */ long long sendTaskAdd(const QueuedProcess::QueuedProcessDefinitions &_definitions, diff --git a/sources/queued/include/queued/QueuedCoreInterface.h b/sources/queued/include/queued/QueuedCoreInterface.h index 8a0cc55..f7ed1bd 100644 --- a/sources/queued/include/queued/QueuedCoreInterface.h +++ b/sources/queued/include/queued/QueuedCoreInterface.h @@ -119,8 +119,8 @@ public slots: qlonglong TaskAdd(const QString &command, const QStringList &arguments, const QString &workingDirectory, const qlonglong user, 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 task * @param id @@ -157,8 +157,8 @@ public slots: const QStringList &arguments, const QString &directory, const uint nice, const uint uid, const uint gid, const qlonglong user, const qlonglong cpu, - const qlonglong gpu, const QString &memory, - const QString &gpumemory, const QString &storage, + const qlonglong gpu, const qlonglong memory, + const qlonglong gpumemory, const qlonglong storage, const QString &token); /** * @brief force start task diff --git a/sources/queued/src/QueuedCoreInterface.cpp b/sources/queued/src/QueuedCoreInterface.cpp index 817234e..5c64b11 100644 --- a/sources/queued/src/QueuedCoreInterface.cpp +++ b/sources/queued/src/QueuedCoreInterface.cpp @@ -100,32 +100,27 @@ bool QueuedCoreInterface::PluginRemove(const QString &plugin, qlonglong QueuedCoreInterface::TaskAdd( const QString &command, const QStringList &arguments, const QString &workingDirectory, const qlonglong user, 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) << "Add new task with parameters" << command << arguments << workingDirectory << "from user" << user; return m_core->addTask( command, arguments, workingDirectory, user, - QueuedLimits::Limits(cpu, gpu, QueuedLimits::convertMemory(memory), - QueuedLimits::convertMemory(gpumemory), - QueuedLimits::convertMemory(storage)), - token); + QueuedLimits::Limits(cpu, gpu, memory, gpumemory, storage), token); } /** * @fn TaskEdit */ -bool QueuedCoreInterface::TaskEdit(const qlonglong id, const QString &command, - const QStringList &arguments, - const QString &directory, const uint nice, - const uint uid, const uint gid, - const qlonglong user, const qlonglong cpu, - const qlonglong gpu, const QString &memory, - const QString &gpumemory, - const QString &storage, const QString &token) +bool QueuedCoreInterface::TaskEdit( + const qlonglong id, const QString &command, const QStringList &arguments, + const QString &directory, const uint nice, const uint uid, const uint gid, + const qlonglong user, const qlonglong cpu, const qlonglong gpu, + const qlonglong memory, const qlonglong gpumemory, const qlonglong storage, + const QString &token) { qCDebug(LOG_DBUS) << "Edit task" << id << command << arguments << directory << nice << uid << gid << cpu << gpu << memory << gpumemory @@ -160,11 +155,11 @@ bool QueuedCoreInterface::TaskEdit(const qlonglong id, const QString &command, 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->editTask(id, data, token); diff --git a/sources/queuedctl/src/QueuedctlCommon.cpp b/sources/queuedctl/src/QueuedctlCommon.cpp index 15f9380..cc67330 100644 --- a/sources/queuedctl/src/QueuedctlCommon.cpp +++ b/sources/queuedctl/src/QueuedctlCommon.cpp @@ -35,6 +35,21 @@ void QueuedctlCommon::checkArgs(const QStringList &_args, const int _count, } +QString QueuedctlCommon::commandsHelp() +{ + QStringList cmdList = {"Commands:"}; + + QStringList commands = QueuedctlArguments.keys(); + commands.sort(); + for (auto &cmd : commands) + // align like default help message + cmdList += QString(" %1%2").arg(cmd, -21).arg( + QueuedctlArguments[cmd].description); + + return cmdList.join('\n'); +} + + void QueuedctlCommon::preprocess(const QStringList &_args, QCommandLineParser &_parser) { @@ -42,29 +57,49 @@ void QueuedctlCommon::preprocess(const QStringList &_args, QString command = _args.isEmpty() ? QString() : _args.first(); // HACK: workaround to show valid help message - _parser.addPositionalArgument(command, "Command to execute."); + auto id = QueuedctlArguments.contains(command) + ? QueuedctlArguments[command].id + : QueuedctlArgument::Invalid; + _parser.addPositionalArgument(id == QueuedctlArgument::Invalid ? "command" + : command, + "Command to execute."); - if (command == "auth") + if (command.isEmpty()) + return; + + switch (id) { + case QueuedctlArgument::Auth: QueuedctlAuth::parser(_parser); - else if (command == "option-get") + break; + case QueuedctlArgument::OptionGet: QueuedctlOption::parserGet(_parser); - else if (command == "option-set") + break; + case QueuedctlArgument::OptionSet: QueuedctlOption::parserSet(_parser); - else if (command == "task-add") + break; + case QueuedctlArgument::TaskAdd: QueuedctlTask::parserAdd(_parser); - else if (command == "task-get") + break; + case QueuedctlArgument::TaskGet: QueuedctlTask::parserGet(_parser); - else if (command == "task-set") + break; + case QueuedctlArgument::TaskSet: QueuedctlTask::parserSet(_parser); - else if (command == "user-add") { - } else if (command == "user-get") { - } else if (command == "user-set") { - } else if (!command.isEmpty()) + break; + case QueuedctlArgument::UserAdd: + break; + case QueuedctlArgument::UserGet: + break; + case QueuedctlArgument::UserSet: + break; + case QueuedctlArgument::Invalid: checkArgs(_args, -1, _parser); + break; + } } -void QueuedctlCommon::print(QueuedctlResult &_result) +void QueuedctlCommon::print(const QueuedctlResult &_result) { if (!_result.status) qInfo() << "Subprocess returns error"; @@ -84,19 +119,26 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, QStringList args = _parser.positionalArguments(); QString command = args.isEmpty() ? QString() : args.first(); - if (command == "auth") { - checkArgs(args, 1, _parser); + auto id = QueuedctlArguments.contains(command) + ? QueuedctlArguments[command].id + : QueuedctlArgument::Invalid; + checkArgs(args, QueuedctlArguments[command].positionalArgsCount, _parser); + + switch (id) { + case QueuedctlArgument::Auth: { QString token = QueuedctlAuth::auth(_user); result.status = !token.isEmpty(); if (result.status) QueuedctlAuth::setToken(token, _cache); - } else if (command == "option-get") { - checkArgs(args, 2, _parser); + break; + } + case QueuedctlArgument::OptionGet: { QVariant value = QueuedctlOption::getOption(args.at(1)); result.status = value.isValid(); result.output = value.toString(); - } else if (command == "option-set") { - checkArgs(args, 3, _parser); + break; + } + case QueuedctlArgument::OptionSet: { QString token = QueuedctlAuth::getToken(_cache, _user); result.status = QueuedctlOption::editOption(args.at(1), args.at(2), token); @@ -106,18 +148,45 @@ QueuedctlCommon::process(QCommandLineParser &_parser, const QString &_cache, else result.output = QString("Could not set option %1 to %2") .arg(args.at(1), args.at(2)); - } else if (command == "task-get") { - checkArgs(args, 3, _parser); + break; + } + case QueuedctlArgument::TaskAdd: { + QString token = QueuedctlAuth::getToken(_cache, _user); + auto definitions = QueuedctlTask::getDefinitions(_parser, false); + long long id = QueuedctlTask::addTask(definitions, token); + result.status = (id > 0); + if (result.status) + result.output = QString("Task %1 added").arg(id); + else + result.output = QString("Could not add task"); + break; + } + case QueuedctlArgument::TaskGet: { QVariant value = QueuedctlTask::getTask(args.at(1).toLongLong(), args.at(2)); result.status = value.isValid(); result.output = value.toString(); - } else if (command == "task-set") { - checkArgs(args, 2, _parser); + break; + } + case QueuedctlArgument::TaskSet: { QString token = QueuedctlAuth::getToken(_cache, _user); - auto definitions = QueuedctlTask::getDefinitions(_parser); + auto definitions = QueuedctlTask::getDefinitions(_parser, true); result.status = QueuedctlTask::setTask(args.at(1).toLongLong(), definitions, token); + break; + } + case QueuedctlArgument::UserAdd: { + break; + } + case QueuedctlArgument::UserGet: { + break; + } + case QueuedctlArgument::UserSet: { + break; + } + case QueuedctlArgument::Invalid: { + break; + } } return result; diff --git a/sources/queuedctl/src/QueuedctlCommon.h b/sources/queuedctl/src/QueuedctlCommon.h index 8b58afa..7dfc7ec 100644 --- a/sources/queuedctl/src/QueuedctlCommon.h +++ b/sources/queuedctl/src/QueuedctlCommon.h @@ -22,14 +22,44 @@ namespace QueuedctlCommon { +// types and constants +enum class QueuedctlArgument { + Invalid, + Auth, + OptionGet, + OptionSet, + TaskAdd, + TaskGet, + TaskSet, + UserAdd, + UserGet, + UserSet +}; typedef struct { bool status = false; QString output; } QueuedctlResult; +typedef struct { + QueuedctlArgument id; + 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."}}}; +// methods void checkArgs(const QStringList &_args, const int _count, QCommandLineParser &_parser); +QString commandsHelp(); void preprocess(const QStringList &_args, QCommandLineParser &_parser); -void print(QueuedctlResult &_result); +void print(const QueuedctlResult &_result); QueuedctlResult process(QCommandLineParser &_parser, const QString &_cache, const QString &_user); }; diff --git a/sources/queuedctl/src/QueuedctlTask.cpp b/sources/queuedctl/src/QueuedctlTask.cpp index 09e6d31..f5b525c 100644 --- a/sources/queuedctl/src/QueuedctlTask.cpp +++ b/sources/queuedctl/src/QueuedctlTask.cpp @@ -21,25 +21,33 @@ #include -QueuedProcess::QueuedProcessDefinitions -QueuedctlTask::getDefinitions(const QCommandLineParser &_parser) +long long QueuedctlTask::addTask( + const QueuedProcess::QueuedProcessDefinitions &_definitions, + const QString &_token) { + qCDebug(LOG_APP) << "Add task" << _definitions.command; + + return QueuedCoreAdaptor::sendTaskAdd(_definitions, _token); +} + + +QueuedProcess::QueuedProcessDefinitions +QueuedctlTask::getDefinitions(const QCommandLineParser &_parser, + const bool _expandAll) +{ + qCDebug(LOG_APP) << "Parse task definitions from parser, expand all" + << _expandAll; + QueuedProcess::QueuedProcessDefinitions definitions; - definitions.command = _parser.value("program"); std::for_each(_parser.values("argument").cbegin(), _parser.values("argument").cend(), [&definitions](const QString &arg) { if (!arg.isEmpty()) definitions.arguments += arg; }); - definitions.endTime - = QDateTime::fromString(_parser.value("stop"), Qt::ISODate); - definitions.gid = _parser.value("gid").toUInt(); + definitions.nice = _parser.value("nice").toUInt(); - definitions.startTime - = QDateTime::fromString(_parser.value("start"), Qt::ISODate); - definitions.uid = _parser.value("uid").toUInt(); definitions.user = _parser.value("task-user").toLongLong(); definitions.workingDirectory = _parser.value("directory"); // limits now @@ -51,6 +59,17 @@ QueuedctlTask::getDefinitions(const QCommandLineParser &_parser) QueuedLimits::convertMemory(_parser.value("limit-storage"))); definitions.limits = limits.toString(); + // all options + if (_expandAll) { + definitions.command = _parser.value("program"); + definitions.endTime + = QDateTime::fromString(_parser.value("stop"), Qt::ISODate); + definitions.gid = _parser.value("gid").toUInt(); + definitions.startTime + = QDateTime::fromString(_parser.value("start"), Qt::ISODate); + definitions.uid = _parser.value("uid").toUInt(); + } + return definitions; } @@ -73,8 +92,7 @@ void QueuedctlTask::parserAdd(QCommandLineParser &_parser) "Command line argument.", "argument", ""); _parser.addOption(argumentOption); // working directory - QCommandLineOption directoryOption(QStringList() << "d" - << "directory", + QCommandLineOption directoryOption("directory", "Command working directory.", "directory", QDir::currentPath()); _parser.addOption(directoryOption); @@ -131,10 +149,8 @@ void QueuedctlTask::parserSet(QCommandLineParser &_parser) "Command line argument.", "argument", ""); _parser.addOption(argumentOption); // working directory - QCommandLineOption directoryOption(QStringList() << "d" - << "directory", - "Command working directory.", - "directory", ""); + QCommandLineOption directoryOption( + "directory", "Command working directory.", "directory", ""); _parser.addOption(directoryOption); // user QCommandLineOption userOption("task-user", "Task user.", "task-user", "0"); diff --git a/sources/queuedctl/src/QueuedctlTask.h b/sources/queuedctl/src/QueuedctlTask.h index 1001f08..5bb95ec 100644 --- a/sources/queuedctl/src/QueuedctlTask.h +++ b/sources/queuedctl/src/QueuedctlTask.h @@ -24,8 +24,10 @@ namespace QueuedctlTask { +long long addTask(const QueuedProcess::QueuedProcessDefinitions &_definitions, + const QString &_token); QueuedProcess::QueuedProcessDefinitions -getDefinitions(const QCommandLineParser &_parser); +getDefinitions(const QCommandLineParser &_parser, const bool _expandAll); QVariant getTask(const long long _id, const QString &_property); void parserAdd(QCommandLineParser &_parser); void parserGet(QCommandLineParser &_parser); diff --git a/sources/queuedctl/src/main.cpp b/sources/queuedctl/src/main.cpp index 2640072..b5a9838 100644 --- a/sources/queuedctl/src/main.cpp +++ b/sources/queuedctl/src/main.cpp @@ -42,13 +42,13 @@ int main(int argc, char *argv[]) // info QCommandLineOption infoOption(QStringList() << "i" << "info", - "Show additional info."); + "Shows additional info."); parser.addOption(infoOption); // debug mode QCommandLineOption debugOption(QStringList() << "d" << "debug", - "Print debug information."); + "Prints debug information."); parser.addOption(debugOption); // configuration option @@ -63,6 +63,10 @@ int main(int argc, char *argv[]) "user", ::getlogin()); parser.addOption(userOption); + // additional help option + QCommandLineOption commandsOption("commands", "Lists available commands."); + parser.addOption(commandsOption); + parser.addPositionalArgument("command", "Command to execute.", ""); // pre-parse @@ -80,6 +84,12 @@ int main(int argc, char *argv[]) QDebug(QtMsgType::QtInfoMsg).noquote() << string; return 0; } + if (parser.isSet(commandsOption)) { + QDebug(QtMsgType::QtInfoMsg).noquote() << parser.helpText(); + QDebug(QtMsgType::QtInfoMsg).noquote() + << QueuedctlCommon::commandsHelp(); + return 0; + } // enable debug if (parser.isSet(debugOption))