From 1a6c67e25ca040542f00b5e4d6125576230887e7 Mon Sep 17 00:00:00 2001 From: timurhai Date: Mon, 14 Oct 2024 20:55:42 +0300 Subject: [PATCH] hosts mask using simple find() function by default. Now find function is used to match hosts mask and hosts exclude mask. This is the default behaviour for user, job and branch. You can configure user, job and branch to use Regular Expressions. If a new job does not have hosts_mask_type parameter, user host mask type will be used. References #604. --- afanasy/src/cmd/cmd_regexp.cpp | 10 +- afanasy/src/libafanasy/afwork.cpp | 43 ++++-- afanasy/src/libafanasy/afwork.h | 34 +++-- afanasy/src/libafanasy/blockdata.cpp | 10 +- afanasy/src/libafanasy/blockdata.h | 3 + afanasy/src/libafanasy/job.cpp | 4 +- afanasy/src/libafanasy/pool.cpp | 3 +- afanasy/src/libafanasy/regexp.cpp | 159 ++++++++++------------- afanasy/src/libafanasy/regexp.h | 75 ++++++----- afanasy/src/project.cmake/CMakeLists.txt | 16 --- afanasy/src/server/afnodesolve.cpp | 2 +- afanasy/src/server/branchsrv.cpp | 6 +- afanasy/src/server/jobaf.cpp | 34 +++++ afanasy/src/server/jobaf.h | 3 + afanasy/src/server/solver.cpp | 2 +- afanasy/src/server/useraf.cpp | 4 +- afanasy/src/watch/itembranch.cpp | 42 +++++- afanasy/src/watch/itemjob.cpp | 42 +++++- afanasy/src/watch/itemuser.cpp | 42 +++++- afanasy/src/watch/itemwork.cpp | 1 + afanasy/src/watch/itemwork.h | 1 + afanasy/src/watch/listjobs.cpp | 21 +++ afanasy/src/watch/listjobs.h | 2 + afanasy/src/watch/listusers.cpp | 13 ++ afanasy/src/watch/listusers.h | 3 + 25 files changed, 378 insertions(+), 197 deletions(-) diff --git a/afanasy/src/cmd/cmd_regexp.cpp b/afanasy/src/cmd/cmd_regexp.cpp index e82df437f..c6c02f1c7 100644 --- a/afanasy/src/cmd/cmd_regexp.cpp +++ b/afanasy/src/cmd/cmd_regexp.cpp @@ -11,11 +11,11 @@ CmdRegExp::CmdRegExp() setCmd("rx"); setArgsCount(2); setInfo("Test a regular expression."); - setHelp("rx [string] [expression] [eci] Whether string matches specified regular expression\n" - "Optional mode [eci]: exclude, contain, case insensitive.\n" + setHelp("rx [string] [expression] [ecif] Whether string matches specified regular expression\n" + "Optional mode [ecif]: exclude, contain, case insensitive, simple find mode.\n" "Examples:\n" "afcmd rx ubuntu \"u.*\"\n" - "afcmd rx ubuntu \"UBU\" eci"); + "afcmd rx ubuntu \"UBU\" ecif"); } CmdRegExp::~CmdRegExp(){} @@ -23,6 +23,7 @@ CmdRegExp::~CmdRegExp(){} bool CmdRegExp::v_processArguments( int argc, char** argv, af::Msg & msg) { af::RegExp rx; + rx.setRegEx(); std::string str = argv[0]; std::string pattern = argv[1]; std::string str_error; @@ -40,9 +41,10 @@ bool CmdRegExp::v_processArguments( int argc, char** argv, af::Msg & msg) int pos = -1; while( mode[++pos] != '\0') { + if( mode[pos] == 'f') rx.setFind(); if( mode[pos] == 'e') rx.setExclude(); if( mode[pos] == 'c') rx.setContain(); - if( mode[pos] == 'i') rx.setCaseInsensitive(); + if( mode[pos] == 'i') rx.setCaseIns(); } } if( rx.setPattern( pattern, &str_error)) printf( rx.match( str) ? " MATCH\n" : " NOT MATCH\n"); diff --git a/afanasy/src/libafanasy/afwork.cpp b/afanasy/src/libafanasy/afwork.cpp index b0dfbbc6a..36c078016 100644 --- a/afanasy/src/libafanasy/afwork.cpp +++ b/afanasy/src/libafanasy/afwork.cpp @@ -30,20 +30,14 @@ using namespace af; Work::Work() { - m_solving_flags = 0; + m_work_flags = 0; m_max_tasks_per_second = -1; m_max_running_tasks = af::Environment::getMaxRunningTasksNumber(); m_max_running_tasks_per_host = -1; - m_hosts_mask.setCaseInsensitive(); - m_hosts_mask_exclude.setCaseInsensitive(); m_hosts_mask_exclude.setExclude(); - m_need_os.setCaseInsensitive(); - m_need_os.setContain(); - m_need_properties.setCaseSensitive(); - m_need_properties.setContain(); m_need_power = -1; m_need_memory = -1; m_need_hdd = -1; @@ -58,7 +52,7 @@ Work::~Work() void Work::readwrite(Msg *msg) { - rw_int8_t(m_solving_flags, msg); + rw_int8_t(m_work_flags, msg); rw_int32_t(m_max_tasks_per_second, msg); @@ -146,6 +140,19 @@ void Work::jsonRead(const JSON &i_object, std::string *io_changes) else setSolveTasksNum(); } + + std::string hosts_mask_type; + if (jr_string("hosts_mask_type", hosts_mask_type, i_object, io_changes)) + { + if (hosts_mask_type == "find") + { + v_setHostsMaskFind(); + } + else if (hosts_mask_type == "regex") + { + v_setHostsMaskRegEx(); + } + } } void Work::jsonWrite(std::ostringstream &o_str, int i_type) const @@ -174,10 +181,30 @@ void Work::jsonWrite(std::ostringstream &o_str, int i_type) const o_str << ",\n\"solve_method\":\"" << (isSolvePriority() ? "solve_priority" : "solve_order") << "\""; o_str << ",\n\"solve_need\":\"" << (isSolveCapacity() ? "solve_capacity" : "solve_tasksnum") << "\""; + if (isHostsMaskRegEx()) + o_str << ",\n\"hosts_mask_type\":\"regex\""; + if (isHostsMaskFind()) + o_str << ",\n\"hosts_mask_type\":\"find\""; + if (m_running_tasks_num > 0) o_str << ",\n\"running_tasks_num\":" << m_running_tasks_num; if (m_running_capacity_total > 0) o_str << ",\n\"running_capacity_total\":" << m_running_capacity_total; } +void Work::v_setHostsMaskFind() +{ + m_work_flags = m_work_flags | FHostsMask_Find; + m_work_flags = m_work_flags & (~FHostsMask_RegEx); + m_hosts_mask.setFind(); + m_hosts_mask_exclude.setFind(); +} +void Work::v_setHostsMaskRegEx() +{ + m_work_flags = m_work_flags & (~FHostsMask_Find); + m_work_flags = m_work_flags | FHostsMask_RegEx; + m_hosts_mask.setRegEx(); + m_hosts_mask_exclude.setRegEx(); +} + int Work::getPoolPriority(const std::string & i_pool, bool & o_canrunon) const { o_canrunon = true; diff --git a/afanasy/src/libafanasy/afwork.h b/afanasy/src/libafanasy/afwork.h index f145fe081..c71940ba2 100644 --- a/afanasy/src/libafanasy/afwork.h +++ b/afanasy/src/libafanasy/afwork.h @@ -32,21 +32,31 @@ class Work : public Node virtual ~Work(); - enum SolvingFlags + enum WorkFlags { - SolvePriority = 1 << 0, ///< Solve by order or prioruty - SolveCapacity = 1 << 1 ///< Solve by running tasks number or total capacity + FSolvePriority = 1 << 0, ///< Solve by order or prioruty + FSolveCapacity = 1 << 1, ///< Solve by running tasks number or total capacity + + FHostsMask_Find = 1 << 2, + FHostsMask_RegEx = 1 << 3 }; - inline void setSolvePriority() { m_solving_flags |= SolvePriority; } - inline void setSolveOrder() { m_solving_flags &=~SolvePriority; } - inline void setSolveCapacity() { m_solving_flags |= SolveCapacity; } - inline void setSolveTasksNum() { m_solving_flags &=~SolveCapacity; } + virtual void v_setHostsMaskFind(); + virtual void v_setHostsMaskRegEx(); + + inline bool isHostsMaskInherit() const {return (m_work_flags & (FHostsMask_Find | FHostsMask_RegEx)) == 0;} + inline bool isHostsMaskFind() const {return (m_work_flags & FHostsMask_Find);} + inline bool isHostsMaskRegEx() const {return (m_work_flags & FHostsMask_RegEx);} + + inline void setSolvePriority() { m_work_flags |= FSolvePriority; } + inline void setSolveOrder() { m_work_flags &=~FSolvePriority; } + inline void setSolveCapacity() { m_work_flags |= FSolveCapacity; } + inline void setSolveTasksNum() { m_work_flags &=~FSolveCapacity; } - inline bool isSolvePriority() const {return m_solving_flags & SolvePriority;} - inline bool isSolveOrder() const {return (m_solving_flags & SolvePriority) == false;} - inline bool isSolveCapacity() const {return m_solving_flags & SolveCapacity;} - inline bool isSolveTasksNum() const {return (m_solving_flags & SolveCapacity) == false;} + inline bool isSolvePriority() const {return m_work_flags & FSolvePriority;} + inline bool isSolveOrder() const {return (m_work_flags & FSolvePriority) == false;} + inline bool isSolveCapacity() const {return m_work_flags & FSolveCapacity;} + inline bool isSolveTasksNum() const {return (m_work_flags & FSolveCapacity) == false;} void generateInfoStream(std::ostringstream &o_str, bool full = false) const; /// Generate information. @@ -115,7 +125,7 @@ class Work : public Node void readwrite(Msg *msg); ///< Read or write node attributes in message protected: - int8_t m_solving_flags; + int8_t m_work_flags; int32_t m_max_tasks_per_second; diff --git a/afanasy/src/libafanasy/blockdata.cpp b/afanasy/src/libafanasy/blockdata.cpp index f9bebb515..07f3d9af0 100644 --- a/afanasy/src/libafanasy/blockdata.cpp +++ b/afanasy/src/libafanasy/blockdata.cpp @@ -144,16 +144,10 @@ void BlockData::construct() m_running_tasks_counter = 0; m_running_capacity_counter = 0; - m_depend_mask.setCaseSensitive(); - m_tasks_depend_mask.setCaseSensitive(); + m_depend_mask.setRegEx(); + m_tasks_depend_mask.setRegEx(); - m_hosts_mask.setCaseInsensitive(); - - m_hosts_mask_exclude.setCaseInsensitive(); m_hosts_mask_exclude.setExclude(); - - m_need_properties.setCaseSensitive(); - m_need_properties.setContain(); } /// Construct data from JSON: diff --git a/afanasy/src/libafanasy/blockdata.h b/afanasy/src/libafanasy/blockdata.h index 0d1718a52..080fbd3c5 100644 --- a/afanasy/src/libafanasy/blockdata.h +++ b/afanasy/src/libafanasy/blockdata.h @@ -141,6 +141,9 @@ class BlockData : public Af inline void setSequential(int64_t i_value) { m_sequential = i_value; } ///< Used in afcmd cmd_numeric inline int64_t getSequential() const { return m_sequential; } + inline void setHostsMaskFind() {m_hosts_mask.setFind(); m_hosts_mask_exclude.setFind(); } + inline void setHostsMaskRegEx() {m_hosts_mask.setRegEx(); m_hosts_mask_exclude.setRegEx();} + inline void setParserCoeff(int value) { m_parser_coeff = value; } /// Set block tasks command. Used in system job. diff --git a/afanasy/src/libafanasy/job.cpp b/afanasy/src/libafanasy/job.cpp index 007e8f540..321b82e88 100644 --- a/afanasy/src/libafanasy/job.cpp +++ b/afanasy/src/libafanasy/job.cpp @@ -277,8 +277,8 @@ void Job::initDefaultValues() m_thumb_data = NULL; m_blocks_data = NULL; - m_depend_mask.setCaseSensitive(); - m_depend_mask_global.setCaseSensitive(); + m_depend_mask.setRegEx(); + m_depend_mask_global.setRegEx(); } bool Job::isValid( std::string * o_err) const diff --git a/afanasy/src/libafanasy/pool.cpp b/afanasy/src/libafanasy/pool.cpp index d1f6a36fc..ba1b38138 100644 --- a/afanasy/src/libafanasy/pool.cpp +++ b/afanasy/src/libafanasy/pool.cpp @@ -46,7 +46,8 @@ Pool::Pool(int i_id) void Pool::initDefaultValues() { - m_pattern.setCaseInsensitive(); + m_pattern.setRegEx(); + m_pattern.setCaseIns(); m_time_creation = 0; diff --git a/afanasy/src/libafanasy/regexp.cpp b/afanasy/src/libafanasy/regexp.cpp index 82696fd89..ff4654776 100644 --- a/afanasy/src/libafanasy/regexp.cpp +++ b/afanasy/src/libafanasy/regexp.cpp @@ -8,111 +8,116 @@ using namespace af; -const int RegExp::compile_flags = REG_EXTENDED; - RegExp::RegExp(): - contain( false), - exclude( false), - cflags( RegExp::compile_flags) + m_flags(0) { } RegExp::~RegExp() { -#ifndef REGEX_STD - if( false == pattern.empty()) regfree( ®exp); -#endif } -bool RegExp::setPattern( const std::string & str, std::string * strError) +void RegExp::setFind() +{ + m_flags = m_flags & (~FRegEx); + if (m_pattern.size()) + setPattern(m_pattern); +} + +void RegExp::setRegEx() +{ + m_flags = m_flags | FRegEx; + if (m_pattern.size()) + setPattern(m_pattern); +} + +bool RegExp::setPattern(const std::string & i_str, std::string * o_strError) { -#ifdef REGEX_STD - if( RegExp::Validate( str, strError)) + m_pattern = i_str; + + if (isFind()) { - pattern = str; - if( cflags & REG_ICASE ) - regexp = std::regex( pattern, std::regex_constants::icase); + m_strings.clear(); + + if (m_pattern.empty()) + return true; + + std::vector strings = af::strSplit(m_pattern); + for (auto & str : strings) + if (str.size()) + m_strings.push_back(str); + + if (m_strings.size() == 0) + m_pattern.clear(); + + return true; + } + + if (RegExp::Validate(i_str, o_strError)) + { + if (isCaseIns()) + m_regexp = std::regex(m_pattern, std::regex_constants::icase); else - regexp = std::regex( pattern); + m_regexp = std::regex(m_pattern); return true; } else { return false; } -#else - - if( str.empty()) - { - if( false == pattern.empty()) - { - pattern.clear(); - regfree( ®exp); - } - return true; - } - - if( false == RegExp::Validate( str, strError )) return false; - - if( false == pattern.empty()) regfree( ®exp); - pattern = str; - regcomp( ®exp, pattern.c_str(), cflags); - return true; - -#endif } -bool RegExp::match( const std::string & str) const +bool RegExp::match(const std::string & i_str) const { - if( pattern.empty()) return true; - -#ifdef REGEX_STD + if (m_pattern.empty()) + return true; int retval = 1; - if( contain ) + + if (isFind()) { - if( regex_search( str.begin(), str.end(), regexp)) - retval = 0; + for (auto & str : m_strings) + if (i_str.find(str) != i_str.npos) + { + retval = 0; + break; + } } else { - if( regex_match( str.begin(), str.end(), regexp)) - retval = 0; - } -#else - - regmatch_t regmatch; - - int retval = regexec( ®exp, str.c_str(), 1, ®match, 0); - if(( retval == 0 ) && ( false == contain )) - { - if( regmatch.rm_so != 0 ) retval = 1; - if( regmatch.rm_eo < str.size() ) retval = 1; + if (isContain()) + { + if (regex_search(i_str.begin(), i_str.end(), m_regexp)) + retval = 0; + } + else + { + if (regex_match(i_str.begin(), i_str.end(), m_regexp)) + retval = 0; + } } -#endif - - return ((retval == 0) != exclude ); + return ((retval == 0) != isExclude()); } int RegExp::weigh() const { - return sizeof(RegExp) + af::weigh( pattern); + return sizeof(RegExp) + af::weigh(m_pattern); } -bool RegExp::Validate( const std::string & str, std::string * errOutput) +bool RegExp::Validate(const std::string & i_str, std::string * o_errOutput) { - if( str.empty()) return true; - -#ifdef REGEX_STD + if (i_str.empty()) + return true; bool valid = true; + std::string errStr; try { - std::regex rx( str); + std::regex rx(i_str); } - catch( const std::regex_error& rerr) + catch(const std::regex_error& rerr) { errStr = rerr.what(); valid = false; @@ -122,33 +127,11 @@ bool RegExp::Validate( const std::string & str, std::string * errOutput) errStr = "Unknown exception."; valid = false; } - if( false == valid ) + if (false == valid) { - if( errOutput ) *errOutput = errStr; + if (o_errOutput) *o_errOutput = errStr; else AF_ERR << errStr; } return valid; - -#else - - regex_t check_re; - int retval = regcomp( &check_re, str.c_str(), compile_flags); - - if( retval != 0 ) - { - static const int buflen = 0xff; - char buffer[ buflen]; - regerror( retval, &check_re, buffer, buflen); - if( errOutput ) - *errOutput = buffer; - else - AF_ERR << buffer; - } - - regfree( &check_re); - - return retval == 0; - -#endif } diff --git a/afanasy/src/libafanasy/regexp.h b/afanasy/src/libafanasy/regexp.h index 6fffaa94e..7c6d5980a 100644 --- a/afanasy/src/libafanasy/regexp.h +++ b/afanasy/src/libafanasy/regexp.h @@ -1,12 +1,6 @@ #pragma once -#ifdef REGEX_STD #include -static const int REG_EXTENDED = 0; -static const int REG_ICASE = 1; -#else -#include -#endif #include "name_af.h" @@ -22,39 +16,54 @@ class RegExp ~RegExp(); - inline bool empty() const { return pattern.empty(); } - inline bool notEmpty() const { return false == pattern.empty(); } - inline const std::string & getPattern() const { return pattern;} - - static bool Validate( const std::string & str, std::string * errOutput = NULL); - - bool setPattern( const std::string & str, std::string * strError = NULL); - - inline void setCaseSensitive() { cflags = compile_flags; } - inline void setCaseInsensitive() { cflags = compile_flags | REG_ICASE; } - - inline void setMatch() { contain = false; } - inline void setContain() { contain = true; } - inline void setInclude() { exclude = false; } - inline void setExclude() { exclude = true; } - - bool match( const std::string & str) const; + enum Flags + { + FRegEx = 1 << 0, + FCaseIns = 1 << 1, + FContain = 1 << 2, + FExclude = 1 << 3 + }; + + void setFind(); + void setRegEx(); + + inline bool isFind() const {return (m_flags & FRegEx) == 0;} + inline bool isRegEx() const {return (m_flags & FRegEx);} + inline bool isCaseSen() const {return (m_flags & FCaseIns) == 0;} + inline bool isCaseIns() const {return (m_flags & FCaseIns);} + inline bool isMatch() const {return (m_flags & FContain) == 0;} + inline bool isContain() const {return (m_flags & FContain);} + inline bool isInclude() const {return (m_flags & FExclude) == 0;} + inline bool isExclude() const {return (m_flags & FExclude);} + + inline bool empty() const {return m_pattern.empty();} + inline bool notEmpty() const {return false == m_pattern.empty();} + inline const std::string & getPattern() const {return m_pattern;} + + bool setPattern(const std::string & i_str, std::string * o_strError = NULL); + + inline void setCaseSen() {m_flags = m_flags & (~FCaseIns);} + inline void setCaseIns() {m_flags = m_flags | FCaseIns; } + inline void setMatch() {m_flags = m_flags & (~FContain);} + inline void setContain() {m_flags = m_flags | FContain; } + inline void setInclude() {m_flags = m_flags & (~FExclude);} + inline void setExclude() {m_flags = m_flags | FExclude; } + + bool match(const std::string & i_str) const; int weigh() const; +public: + static bool Validate(const std::string & i_str, std::string * o_errOutput = NULL); + private: - int cflags; - bool exclude; - bool contain; - std::string pattern; + int m_flags; + + std::string m_pattern; -#ifdef REGEX_STD - std::regex regexp; -#else - regex_t regexp; -#endif + std::regex m_regexp; - static const int compile_flags; + std::vector m_strings; }; } diff --git a/afanasy/src/project.cmake/CMakeLists.txt b/afanasy/src/project.cmake/CMakeLists.txt index 75e8d08cd..817f4c92f 100644 --- a/afanasy/src/project.cmake/CMakeLists.txt +++ b/afanasy/src/project.cmake/CMakeLists.txt @@ -51,24 +51,8 @@ if(UNIX) endif(UNIX) if(WIN32) add_definitions(-DWINNT) - set( REGEX_STD ON) endif(WIN32) -if(CMAKE_COMPILER_IS_GNUCC) - if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5) -# message("Setting c++11 standard for GCC ${CMAKE_CXX_COMPILER_VERSION}") -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - set( REGEX_STD ON) - endif() -endif() - -if( REGEX_STD ) - add_definitions(-DREGEX_STD) - message("Using std::regex ECMAScript regular expressions (Perl-like).") -else() - message("Using POSIX-EXTENDED regular expressions.") -endif() - include_directories(${PYTHON_INCLUDE_PATH}) set( OUTPUT_DIRECTORY "../../../$ENV{AF_OSTYPE}/bin") diff --git a/afanasy/src/server/afnodesolve.cpp b/afanasy/src/server/afnodesolve.cpp index eb72c655c..75b877bf7 100644 --- a/afanasy/src/server/afnodesolve.cpp +++ b/afanasy/src/server/afnodesolve.cpp @@ -136,7 +136,7 @@ void AfNodeSolve::calcNeed(int i_flags, int i_resourcesquantity) if (resourcesquantity < 0) { - if (i_flags & af::Work::SolveCapacity) + if (i_flags & af::Work::FSolveCapacity) resourcesquantity = m_work->getRunningCapacityTotal(); else resourcesquantity = m_work->getRunningTasksNum(); diff --git a/afanasy/src/server/branchsrv.cpp b/afanasy/src/server/branchsrv.cpp index 303c0cbfb..56495d8cd 100644 --- a/afanasy/src/server/branchsrv.cpp +++ b/afanasy/src/server/branchsrv.cpp @@ -528,7 +528,7 @@ RenderAf * BranchSrv::v_solve(std::list & i_renders_list, MonitorCont if (false == node->canRun()) continue; - node->calcNeed(m_solving_flags); + node->calcNeed(m_work_flags); solve_list.push_back(node); } @@ -543,7 +543,7 @@ RenderAf * BranchSrv::v_solve(std::list & i_renders_list, MonitorCont if (false == node->canRun()) continue; - node->calcNeed(m_solving_flags); + node->calcNeed(m_work_flags); solve_list.push_back(node); } @@ -566,7 +566,7 @@ RenderAf * BranchSrv::v_solve(std::list & i_renders_list, MonitorCont } } - Solver::SortList(solve_list, m_solving_flags); + Solver::SortList(solve_list, m_work_flags); return Solver::SolveList(solve_list, i_renders_list, this); } diff --git a/afanasy/src/server/jobaf.cpp b/afanasy/src/server/jobaf.cpp index ced6e40fe..34c90aecc 100644 --- a/afanasy/src/server/jobaf.cpp +++ b/afanasy/src/server/jobaf.cpp @@ -259,6 +259,27 @@ bool JobAf::initialize() m_blocks_data[b]->setJobId( m_id); } + // + // Inherit hosts mask type from user if not set: + if (isHostsMaskInherit()) + { + if (m_user->isHostsMaskRegEx()) + v_setHostsMaskRegEx(); + else + v_setHostsMaskFind(); + } + else + { + // Set blocks host mask the same type as job: + for (int b = 0; b < m_blocks_num; b++) + { + if (isHostsMaskRegEx()) + m_blocks_data[b]->setHostsMaskRegEx(); + else + m_blocks_data[b]->setHostsMaskFind(); + } + } + // // Store job ( if not stored ) if( isFromStore() == false ) @@ -326,6 +347,19 @@ bool JobAf::initialize() return true; } +void JobAf::v_setHostsMaskFind() +{ + Work::v_setHostsMaskFind(); + for (int b = 0; b < m_blocks_num; b++) + m_blocks_data[b]->setHostsMaskFind(); +} +void JobAf::v_setHostsMaskRegEx() +{ + Work::v_setHostsMaskRegEx(); + for (int b = 0; b < m_blocks_num; b++) + m_blocks_data[b]->setHostsMaskRegEx(); +} + void JobAf::checkStates() { // This function is called on a job initialization, diff --git a/afanasy/src/server/jobaf.h b/afanasy/src/server/jobaf.h index eabf88831..7403c9d8b 100644 --- a/afanasy/src/server/jobaf.h +++ b/afanasy/src/server/jobaf.h @@ -123,6 +123,9 @@ class JobAf : public af::Job , public AfNodeSolve /// Force refresh, that can be skipped on DONE job. inline void forceRefresh() {m_force_refresh = true;} + virtual void v_setHostsMaskFind() override; + virtual void v_setHostsMaskRegEx() override; + public: /// Set Jobs Container. inline static void setJobContainer( JobContainer *Jobs){ ms_jobs = Jobs;} diff --git a/afanasy/src/server/solver.cpp b/afanasy/src/server/solver.cpp index 9a258f985..27873f32c 100644 --- a/afanasy/src/server/solver.cpp +++ b/afanasy/src/server/solver.cpp @@ -118,7 +118,7 @@ struct GreaterPriorityThenOlderCreation void Solver::SortList(std::list & i_list, int i_solving_flags) { - if (i_solving_flags & af::Work::SolvePriority) + if (i_solving_flags & af::Work::FSolvePriority) i_list.sort(GreaterNeed()); else i_list.sort(GreaterPriorityThenOlderCreation()); diff --git a/afanasy/src/server/useraf.cpp b/afanasy/src/server/useraf.cpp index 1f491d246..dda7fdc80 100644 --- a/afanasy/src/server/useraf.cpp +++ b/afanasy/src/server/useraf.cpp @@ -335,13 +335,13 @@ RenderAf * UserAf::v_solve( std::list & i_renders_list, MonitorContai if (false == node->canRun()) continue; - node->calcNeed(m_solving_flags); + node->calcNeed(m_work_flags); solve_list.push_back(node); } if (isSolvePriority()) - Solver::SortList(solve_list, m_solving_flags); + Solver::SortList(solve_list, m_work_flags); return Solver::SolveList(solve_list, i_renders_list, NULL); } diff --git a/afanasy/src/watch/itembranch.cpp b/afanasy/src/watch/itembranch.cpp index bd216ed18..545d39626 100644 --- a/afanasy/src/watch/itembranch.cpp +++ b/afanasy/src/watch/itembranch.cpp @@ -102,8 +102,18 @@ void ItemBranch::v_updateValues(af::Node * i_afnode, int i_msgType) if (branch->isSolveCapacity()) strParameters += ",Capacity"; else strParameters += ",RunTasks"; if (max_running_tasks != -1) strParameters += QString(" MaxRuningTasks:%1").arg(max_running_tasks); if (max_running_tasks_per_host != -1) strParameters += QString(" MaxRunTasksPerHost:%1").arg(max_running_tasks_per_host); - if (false == hostsmask.isEmpty()) strParameters += QString(" HostsMask(%1)").arg(hostsmask); - if (false == hostsmask_exclude.isEmpty()) strParameters += QString(" ExcludeHosts(%1)").arg(hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + strParameters += QString(" HostsMask(%1)").arg(hostsmask); + if (hosts_mask_regex) + strParameters += "RegEx"; + } + if (false == hostsmask_exclude.isEmpty()) + { + strParameters += QString(" ExcludeHosts(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + strParameters += "RegEx"; + } } else if (Watch::isJedi()) { @@ -130,8 +140,18 @@ void ItemBranch::v_updateValues(af::Node * i_afnode, int i_msgType) if (branch->isSolveCapacity()) strParameters += ",Capacity"; else strParameters += ",MaxTasks"; if (max_running_tasks != -1) strParameters += QString(" MaxTasks:%1").arg(max_running_tasks); if (max_running_tasks_per_host != -1) strParameters += QString(" MaxPerHost:%1").arg(max_running_tasks_per_host); - if (false == hostsmask.isEmpty()) strParameters += QString(" Hosts(%1)").arg(hostsmask); - if (false == hostsmask_exclude.isEmpty()) strParameters += QString(" Exclude(%1)").arg(hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + strParameters += QString(" Hosts(%1)").arg(hostsmask); + if (hosts_mask_regex) + strParameters += "RE"; + } + if (false == hostsmask_exclude.isEmpty()) + { + strParameters += QString(" Exclude(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + strParameters += "RE"; + } } else { @@ -158,8 +178,18 @@ void ItemBranch::v_updateValues(af::Node * i_afnode, int i_msgType) if (branch->isSolveCapacity()) strParameters += ",cap"; else strParameters += ",mt"; if (max_running_tasks != -1) strParameters += QString(" m%1").arg(max_running_tasks); if (max_running_tasks_per_host != -1) strParameters += QString(" mph%1").arg(max_running_tasks_per_host); - if (false == hostsmask.isEmpty()) strParameters += QString(" h(%1)").arg(hostsmask); - if (false == hostsmask_exclude.isEmpty()) strParameters += QString(" e(%1)").arg(hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + strParameters += QString(" h(%1)").arg(hostsmask); + if (hosts_mask_regex) + strParameters += "r"; + } + if (false == hostsmask_exclude.isEmpty()) + { + strParameters += QString(" e(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + strParameters += "r"; + } } ItemNode::updateStrParameters(strParameters); diff --git a/afanasy/src/watch/itemjob.cpp b/afanasy/src/watch/itemjob.cpp index 4ea27e8c8..b79ebfb1b 100644 --- a/afanasy/src/watch/itemjob.cpp +++ b/afanasy/src/watch/itemjob.cpp @@ -237,8 +237,18 @@ void ItemJob::v_updateValues(af::Node * i_afnode, int i_msgType) { if (false == dependmask_global.isEmpty()) m_str_props += QString(" Global Depends(%1)").arg(dependmask_global); if (false == dependmask.isEmpty() ) m_str_props += QString(" Depends(%1)").arg(dependmask); - if (false == hostsmask.isEmpty() ) m_str_props += QString(" HostsMask(%1)").arg(hostsmask); - if (false == hostsmask_exclude.isEmpty()) m_str_props += QString(" ExcludeHosts(%1)").arg(hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + m_str_props += QString(" HostsMask(%1)").arg(hostsmask); + if (hosts_mask_regex) + m_str_props += "RegEx"; + } + if (false == hostsmask_exclude.isEmpty()) + { + m_str_props += QString(" ExcludeHosts(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + m_str_props += "RegEx"; + } if (false == need_os.isEmpty() ) m_str_props += QString(" OS:%1").arg(need_os); if (false == need_properties.isEmpty() ) m_str_props += QString(" Properities(%1)").arg(need_properties); if (need_memory != -1) m_str_props += QString(" Mem>%1").arg(afqt::stoq(af::toKMG(int64_t(need_memory)*(1<<20), 1<<10))); @@ -255,8 +265,18 @@ void ItemJob::v_updateValues(af::Node * i_afnode, int i_msgType) { if (false == dependmask_global.isEmpty()) m_str_props += QString(" GDep(%1)").arg(dependmask_global); if (false == dependmask.isEmpty() ) m_str_props += QString(" Dep(%1)").arg(dependmask); - if (false == hostsmask.isEmpty() ) m_str_props += QString(" Host(%1)").arg(hostsmask); - if (false == hostsmask_exclude.isEmpty()) m_str_props += QString(" Exclude(%1)").arg(hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + m_str_props += QString(" Hosts(%1)").arg(hostsmask); + if (hosts_mask_regex) + m_str_props += "RE"; + } + if (false == hostsmask_exclude.isEmpty()) + { + m_str_props += QString(" Exclude(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + m_str_props += "RE"; + } if (false == need_os.isEmpty() ) m_str_props += QString(" OS:%1").arg(need_os); if (false == need_properties.isEmpty() ) m_str_props += QString(" Props(%1)").arg(need_properties); if (need_memory != -1) m_str_props += QString(" Mem>%1").arg(afqt::stoq(af::toKMG(int64_t(need_memory)*(1<<20), 1<<10))); @@ -273,8 +293,18 @@ void ItemJob::v_updateValues(af::Node * i_afnode, int i_msgType) { if (false == dependmask_global.isEmpty()) m_str_props += QString(" g(%1)").arg(dependmask_global); if (false == dependmask.isEmpty() ) m_str_props += QString(" d(%1)").arg(dependmask ); - if (false == hostsmask.isEmpty() ) m_str_props += QString(" h(%1)").arg(hostsmask ); - if (false == hostsmask_exclude.isEmpty()) m_str_props += QString(" e(%1)").arg(hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + m_str_props += QString(" h(%1)").arg(hostsmask); + if (hosts_mask_regex) + m_str_props += "r"; + } + if (false == hostsmask_exclude.isEmpty()) + { + m_str_props += QString(" e(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + m_str_props += "r"; + } if (false == need_os.isEmpty() ) m_str_props += QString(" %1").arg(need_os); if (false == need_properties.isEmpty() ) m_str_props += QString(" p(%1)").arg(need_properties); if (need_memory != -1) m_str_props += QString(" m>%1").arg(afqt::stoq(af::toKMG(int64_t(need_memory)*(1<<20), 1<<10))); diff --git a/afanasy/src/watch/itemuser.cpp b/afanasy/src/watch/itemuser.cpp index 55192bfe7..7bcc0a05f 100644 --- a/afanasy/src/watch/itemuser.cpp +++ b/afanasy/src/watch/itemuser.cpp @@ -69,8 +69,18 @@ void ItemUser::v_updateValues(af::Node * i_afnode, int i_msgType) strHCenterTop.clear(); if (max_running_tasks != -1) strHCenterTop += QString(" MaxRuningTasks:%1").arg(max_running_tasks); if (max_running_tasks_per_host != -1) strHCenterTop += QString(" MaxRunTasksPerHost:%1").arg(max_running_tasks_per_host); - if( false == hostsmask.isEmpty()) strHCenterTop += QString(" HostsMask(%1)").arg( hostsmask); - if( false == hostsmask_exclude.isEmpty()) strHCenterTop += QString(" ExcludeHosts(%1)").arg( hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + strHCenterTop += QString(" HostsMask(%1)").arg(hostsmask); + if (hosts_mask_regex) + strHCenterTop += "RegEx"; + } + if (false == hostsmask_exclude.isEmpty()) + { + strHCenterTop += QString(" ExcludeHosts(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + strHCenterTop += "RegEx"; + } strHCenterTop += Item::generateErrorsSolvingInfo( errors_avoidhost, errors_tasksamehost, errors_retries); if( errors_forgivetime > 0 ) strHCenterTop += QString(" ErrorsForgiveTime:%1").arg( af::time2strHMS( errors_forgivetime, true).c_str()); if( jobs_lifetime > 0 ) strHCenterTop += QString(" JobsLifeTime:%1").arg( af::time2strHMS( jobs_lifetime, true).c_str()); @@ -96,8 +106,18 @@ void ItemUser::v_updateValues(af::Node * i_afnode, int i_msgType) strHCenterTop.clear(); if (max_running_tasks != -1) strHCenterTop += QString(" MaxTasks:%1").arg(max_running_tasks); if (max_running_tasks_per_host != -1) strHCenterTop += QString(" MaxPerHost:%1").arg(max_running_tasks_per_host); - if( false == hostsmask.isEmpty()) strHCenterTop += QString(" Hosts(%1)").arg( hostsmask); - if( false == hostsmask_exclude.isEmpty()) strHCenterTop += QString(" Exclude(%1)").arg( hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + strHCenterTop += QString(" Hosts(%1)").arg(hostsmask); + if (hosts_mask_regex) + strHCenterTop += "REG"; + } + if (false == hostsmask_exclude.isEmpty()) + { + strHCenterTop += QString(" Exclude(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + strHCenterTop += "REG"; + } strHCenterTop += Item::generateErrorsSolvingInfo( errors_avoidhost, errors_tasksamehost, errors_retries); if( errors_forgivetime > 0 ) strHCenterTop += QString(" ErrForgive:%1").arg( af::time2strHMS( errors_forgivetime, true).c_str()); if( jobs_lifetime > 0 ) strHCenterTop += QString(" JobsLife:%1").arg( af::time2strHMS( jobs_lifetime, true).c_str()); @@ -123,8 +143,18 @@ void ItemUser::v_updateValues(af::Node * i_afnode, int i_msgType) strHCenterTop.clear(); if (max_running_tasks != -1) strHCenterTop += QString("m%1").arg(max_running_tasks); if (max_running_tasks_per_host != -1) strHCenterTop += QString(" mph%1").arg(max_running_tasks_per_host); - if( false == hostsmask.isEmpty()) strHCenterTop += QString(" h(%1)").arg( hostsmask); - if( false == hostsmask_exclude.isEmpty()) strHCenterTop += QString(" e(%1)").arg( hostsmask_exclude); + if (false == hostsmask.isEmpty()) + { + strHCenterTop += QString(" h(%1)").arg(hostsmask); + if (hosts_mask_regex) + strHCenterTop += "r"; + } + if (false == hostsmask_exclude.isEmpty()) + { + strHCenterTop += QString(" e(%1)").arg(hostsmask_exclude); + if (hosts_mask_regex) + strHCenterTop += "r"; + } strHCenterTop += Item::generateErrorsSolvingInfo( errors_avoidhost, errors_tasksamehost, errors_retries); if( errors_forgivetime > 0 ) strHCenterTop += QString(" f%1").arg( af::time2strHMS( errors_forgivetime, true).c_str()); if( jobs_lifetime > 0 ) strHCenterTop += QString(" l%1").arg( af::time2strHMS( jobs_lifetime, true).c_str()); diff --git a/afanasy/src/watch/itemwork.cpp b/afanasy/src/watch/itemwork.cpp index 283ced530..46fe424c9 100644 --- a/afanasy/src/watch/itemwork.cpp +++ b/afanasy/src/watch/itemwork.cpp @@ -41,6 +41,7 @@ void ItemWork::updateWorkValues(af::Work * i_afwork) max_running_tasks_per_host = i_afwork->getMaxRunTasksPerHost(); hostsmask = afqt::stoq(i_afwork->getHostsMask()); hostsmask_exclude = afqt::stoq(i_afwork->getHostsMaskExclude()); + hosts_mask_regex = i_afwork->isHostsMaskRegEx(); running_tasks_num = i_afwork->getRunningTasksNum(); running_capacity_total = i_afwork->getRunningCapacityTotal(); diff --git a/afanasy/src/watch/itemwork.h b/afanasy/src/watch/itemwork.h index 40fe7972a..8cb4ab6f1 100644 --- a/afanasy/src/watch/itemwork.h +++ b/afanasy/src/watch/itemwork.h @@ -21,6 +21,7 @@ class ItemWork : public ItemNode int max_running_tasks_per_host; QString hostsmask; QString hostsmask_exclude; + bool hosts_mask_regex; int running_tasks_num; int64_t running_capacity_total; diff --git a/afanasy/src/watch/listjobs.cpp b/afanasy/src/watch/listjobs.cpp index 78c6a8b44..58881e113 100644 --- a/afanasy/src/watch/listjobs.cpp +++ b/afanasy/src/watch/listjobs.cpp @@ -165,6 +165,14 @@ ListJobs::ListJobs(QWidget * i_parent, bool i_listwork, const std::string & i_na resetButtonsMenu(); + addButtonsMenu(Item::TAny, "Hosts Mask","Set hosts mask type."); + bp = addButtonPanel(Item::TAny, "FIND", "users_hosts_mask_find","Use simple find algorithm for hosts mask."); + connect(bp, SIGNAL(sigClicked()), this, SLOT(actHostsMaskFind())); + bp = addButtonPanel(Item::TAny, "REGEX","users_hosts_mask_regex","Use regular expressions for hosts mask."); + connect(bp, SIGNAL(sigClicked()), this, SLOT(actHostsMaskRegEx())); + + resetButtonsMenu(); + bp = addButtonPanel(Item::TJob, "LISTEN","jobs_listen","Listen job running tasks ouput."); connect(bp, SIGNAL(sigClicked()), this, SLOT(actListenJob())); @@ -422,6 +430,16 @@ void ListJobs::contextMenuEvent( QContextMenuEvent *event) menu.addSeparator(); + submenu = new QMenu("Hosts Mask Type", this); + action = new QAction("Find", this); + connect(action, SIGNAL(triggered() ), this, SLOT(actHostsMaskFind())); + submenu->addAction(action); + action = new QAction("RegEx", this); + connect(action, SIGNAL(triggered() ), this, SLOT(actHostsMaskRegEx())); + submenu->addAction(action); + menu.addMenu( submenu); + menu.addSeparator(); + submenu = new QMenu( "Set Parameter", this); addMenuParameters(submenu); @@ -785,6 +803,9 @@ void ListJobs::actUnsetHidden() {setParameter(Item::TJob, "hidden", "false");} void ListJobs::actPreviewApproval() {setParameter(Item::TJob, "ppa", "true" );} void ListJobs::actNoPreviewApproval() {setParameter(Item::TJob, "ppa", "false");} +void ListJobs::actHostsMaskFind() {setParameter(Item::TAny, "hosts_mask_type", "\"find\"");} +void ListJobs::actHostsMaskRegEx() {setParameter(Item::TAny, "hosts_mask_type", "\"regex\"");} + void ListJobs::actSetUser() { ItemJob* item = (ItemJob*)getCurrentItem(); diff --git a/afanasy/src/watch/listjobs.h b/afanasy/src/watch/listjobs.h index c3591d308..9dff1b0ae 100644 --- a/afanasy/src/watch/listjobs.h +++ b/afanasy/src/watch/listjobs.h @@ -53,6 +53,8 @@ private slots: void actUnsetHidden(); void actPreviewApproval(); void actNoPreviewApproval(); + void actHostsMaskFind(); + void actHostsMaskRegEx(); void actStart(); void actStop(); diff --git a/afanasy/src/watch/listusers.cpp b/afanasy/src/watch/listusers.cpp index 99255ed31..033637600 100644 --- a/afanasy/src/watch/listusers.cpp +++ b/afanasy/src/watch/listusers.cpp @@ -88,6 +88,17 @@ ListUsers::ListUsers( QWidget* parent): resetButtonsMenu(); + bm = addButtonsMenu(Item::TUser, "Hosts Mask","Set hosts mask type."); + bm->openMenu(); + + bp = addButtonPanel(Item::TUser, "FIND", "users_hosts_mask_find","Use simple find algorithm for hosts mask."); + connect(bp, SIGNAL(sigClicked()), this, SLOT(actHostsMaskFind())); + + bp = addButtonPanel(Item::TUser, "REGEX","users_hosts_mask_regex","Use regular expressions for hosts mask."); + connect(bp, SIGNAL(sigClicked()), this, SLOT(actHostsMaskRegEx())); + + resetButtonsMenu(); + bp = addButtonPanel(Item::TAny, "CUSTOM DATA","node_custom_data","Edit node custom data."); connect(bp, SIGNAL(sigClicked()), this, SLOT(actCustomData())); @@ -215,6 +226,8 @@ void ListUsers::actSolveJobsByOrder() {setParameterStr(Item::TUser, "solve_me void ListUsers::actSolveJobsByPriority() {setParameterStr(Item::TUser, "solve_method", "solve_priority"); } void ListUsers::actSolveJobsByCapacity() {setParameterStr(Item::TUser, "solve_need", "solve_capacity"); } void ListUsers::actSolveJobsByTasksNum() {setParameterStr(Item::TUser, "solve_need", "solve_tasksnum"); } +void ListUsers::actHostsMaskFind() {setParameterStr(Item::TUser, "hosts_mask_type", "find"); } +void ListUsers::actHostsMaskRegEx() {setParameterStr(Item::TUser, "hosts_mask_type", "regex");} void ListUsers::actRequestLog() { getItemInfo(Item::TAny, "log"); } diff --git a/afanasy/src/watch/listusers.h b/afanasy/src/watch/listusers.h index ff9d4c8c6..c06b151f9 100644 --- a/afanasy/src/watch/listusers.h +++ b/afanasy/src/watch/listusers.h @@ -35,6 +35,9 @@ private slots: void actSolveJobsByCapacity(); void actSolveJobsByTasksNum(); + void actHostsMaskFind(); + void actHostsMaskRegEx(); + void actDelete(); private: