Changeset 9c06054 in nscp


Ignore:
Timestamp:
12/07/11 07:01:41 (18 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.0, 0.4.1, 0.4.2
Children:
f085f9b
Parents:
f33c12f
Message:
  • Added python unittests to make sure threading is working properly
  • Simpliefied and cleaned up the command line syntax a bit
  • Now --exec is the default option for client mode (but it will notify you it thought so)
  • Added "command-less" execution to PythonScript so you can do --exec --script ... (without having --exec run)
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • changelog

    r9853bc3 r9c06054  
    55 * Fixa dependonservice LanManWorkStation (old win) 
    66 * Fix RtlStringFromGUID problem on NT4 
     7 
     82011-12-06 MickeM 
     9 * Added python unittests to make sure threading is working properly 
     10 * Simpliefied and cleaned up the command line syntax a bit 
     11 * Now --exec is the default option for client mode (but it will notify you it thought so) 
     12 * Added "command-less" execution to PythonScript so you can do --exec --script ... (without having --exec run) 
     13 * Fixed an issue related to python threading 
     14 * Fixed Scheduler header propgation 
     15 * Fixed so all Client module use "complex" API meaning headers are propagated correctly 
     16 * Fixed scheduler alias issue 
    717 
    8182011-11-27 MickeM 
  • include/scripts/functions.hpp

    r04ef932 r9c06054  
    1414  } 
    1515 
     16  bool validate(std::wstring &error) const { 
     17    if (script.empty()) { 
     18      error = _T("No script given on command line!"); 
     19      return false; 
     20    } 
     21    if (!boost::filesystem::exists(script)) { 
     22      error = _T("Script not found: ") + script.string(); 
     23      return false; 
     24    } 
     25    if (!boost::filesystem::is_regular(script)) { 
     26      error = _T("Script is not a file: ") + script.string(); 
     27      return false; 
     28    } 
     29    return true; 
     30  } 
     31 
    1632  static void push(list_type &list, std::wstring alias, boost::filesystem::wpath script) { 
    1733    list.push_back(script_container(alias, script)); 
  • modules/PythonScript/PythonScript.cpp

    r9853bc3 r9c06054  
    109109python_script::python_script(unsigned int plugin_id, const std::string alias, const script_container& script) : alias(alias), plugin_id(plugin_id) { 
    110110  NSC_DEBUG_MSG_STD(_T("Loading python script: ") + script.script.string()); 
    111   std::wcout << script.script.string() << std::endl;; 
    112   _exec(utf8::cvt<std::string>(script.script.string())); 
     111  std::wstring err; 
     112  if (!script.validate(err)) { 
     113    NSC_LOG_ERROR(err); 
     114    return; 
     115  } 
     116  _exec(utf8::cvt<std::string>(script.script.file_string())); 
    113117  callFunction("init", plugin_id, alias, utf8::cvt<std::string>(script.alias)); 
    114118} 
     
    162166      path /= _T("lib"); 
    163167      PyRun_SimpleString(("sys.path.append('" + utf8::cvt<std::string>(path.string()) + "')").c_str()); 
     168 
    164169      object ignored = exec_file(scriptfile.c_str(), localDict, localDict);  
    165170    } catch( error_already_set e) { 
    166171      script_wrapper::log_exception(); 
     172    } catch(...) { 
     173      NSC_LOG_ERROR(_T("Failed to run python script: ") + utf8::to_unicode(scriptfile)); 
    167174    } 
    168175  } catch (...) { 
     
    195202      Py_Initialize(); 
    196203      PyEval_InitThreads(); 
    197  
     204      //PyEval_ReleaseLock(); 
     205 
     206      PyThreadState *state; 
     207      state = PyEval_SaveThread(); 
    198208        //PyThreadState *mainThreadState = PyThreadState_Get(); 
    199209        //PyThreadState_Clear 
    200         //PyGILState_Release(mainThreadState); 
     210        //PyThreadState_(mainThreadState); 
    201211 
    202212      do_init = true; 
     
    220230 
    221231      } 
     232      //PyEval_ReleaseLock(); 
    222233      BOOST_FOREACH(script_container &script, scripts_) { 
    223234        instances_.push_back(boost::shared_ptr<python_script>(new python_script(get_id(), utf8::cvt<std::string>(alias), script))); 
    224235      } 
    225       PyEval_ReleaseLock(); 
    226236 
    227237    } catch (std::exception &e) { 
     
    255265} 
    256266 
    257 NSCAPI::nagiosReturn PythonScript::execute_and_load_python(std::list<std::wstring> args) { 
    258   try { 
    259     po::options_description desc; 
     267NSCAPI::nagiosReturn PythonScript::execute_and_load_python(std::list<std::wstring> args, std::wstring &message) { 
     268  try { 
     269    po::options_description desc("Options for the following commands: (exec, execute)"); 
    260270    boost::program_options::variables_map vm; 
    261271    std::wstring file; 
    262272    desc.add_options() 
     273      ("help", "Display help") 
    263274      ("script", po::wvalue<std::wstring>(&file), "The script to run") 
    264275      ("file", po::wvalue<std::wstring>(&file), "The script to run") 
     
    269280    po::store(parsed, vm); 
    270281    po::notify(vm); 
     282 
     283    if (vm.count("help") > 0) { 
     284      std::stringstream ss; 
     285      ss << desc; 
     286      message = utf8::to_unicode(ss.str()); 
     287      return NSCAPI::returnUNKNOWN; 
     288    } 
    271289 
    272290    boost::optional<boost::filesystem::wpath> ofile = find_file(file); 
     
    276294    python_script script(get_id(), "", sc); 
    277295    script.callFunction("__main__"); 
     296    message = _T("Script execute successfully..."); 
     297    return NSCAPI::returnOK; 
    278298  } catch (const std::exception &e) { 
    279     NSC_LOG_ERROR_STD(_T("Failed to execute script ") + utf8::cvt<std::wstring>(e.what())); 
    280   } catch (...) { 
    281     NSC_LOG_ERROR_STD(_T("Failed to execute script...")); 
     299    message = _T("Failed to execute script ") + utf8::to_unicode(e.what()); 
     300    NSC_LOG_ERROR_STD(message); 
     301    return NSCAPI::returnUNKNOWN; 
     302  } catch (...) { 
     303    message = _T("Failed to execute script "); 
     304    NSC_LOG_ERROR_STD(message); 
     305    return NSCAPI::returnUNKNOWN; 
    282306  } 
    283307} 
     
    344368NSCAPI::nagiosReturn PythonScript::commandRAWLineExec(const wchar_t* char_command, const std::string &request, std::string &response) { 
    345369  std::wstring command = char_command; 
    346   if (command == _T("execute-and-load-python") || command == _T("execute-python") || command == _T("run")) { 
     370  if (command == _T("help")) { 
     371    std::list<std::wstring> args; 
     372    args.push_back(_T("--help")); 
     373    std::wstring result; 
     374    int ret = execute_and_load_python(args, result); 
     375    nscapi::functions::create_simple_exec_response<std::wstring>(_T("help"), ret, result, response); 
     376    return ret; 
     377  } else if (command == _T("execute-and-load-python") || command == _T("execute-python") || command == _T("run") || command == _T("execute") || command == _T("exec")|| command == _T("")) { 
    347378    nscapi::functions::decoded_simple_command_data data = nscapi::functions::parse_simple_exec_request(char_command, request); 
    348     return execute_and_load_python(data.args); 
     379    if (data.command == _T("") && data.args.size() == 0) 
     380      return NSCAPI::returnIgnored; 
     381    std::wstring result; 
     382    int ret = execute_and_load_python(data.args, result); 
     383    nscapi::functions::create_simple_exec_response(data.command, ret, result, response); 
     384    return ret; 
    349385  } 
    350386  boost::shared_ptr<script_wrapper::function_wrapper> inst = script_wrapper::function_wrapper::create(get_id()); 
     
    398434    std::wstring src, cmd, msg, perf; 
    399435    int code = nscapi::functions::parse_simple_submit_request(request, src, cmd, msg, perf); 
    400     NSC_LOG_ERROR_STD(_T(" --- command: ") + cmd); 
    401436    int ret = inst->handle_simple_message(chnl, to_string(src), to_string(cmd), code, msg, perf); 
    402437    nscapi::functions::create_simple_submit_response(channel, cmd, ret, _T(""), response); 
  • modules/PythonScript/PythonScript.h

    ra629015 r9c06054  
    8888  NSCAPI::nagiosReturn handleRAWNotification(const std::wstring &channel, std::string &request, std::string &response); 
    8989 
    90   NSCAPI::nagiosReturn execute_and_load_python(std::list<std::wstring> args); 
    91   //NSCAPI::nagiosReturn RunLUA(const unsigned int argLen, wchar_t **char_args, std::wstring &message, std::wstring &perf); 
    92   //NSCAPI::nagiosReturn extract_return(Lua_State &L, int arg_count,  std::wstring &message, std::wstring &perf); 
    93  
    94   //script_wrapper::lua_handler 
    95   //void register_command(script_wrapper::lua_script* script, std::wstring command, std::wstring function); 
     90  NSCAPI::nagiosReturn execute_and_load_python(std::list<std::wstring> args, std::wstring &message); 
    9691 
    9792private: 
  • modules/Scheduler/Scheduler.cpp

    rf33c12f r9c06054  
    4141    schedule_map schedules; 
    4242    sh::settings_registry settings(get_settings_proxy()); 
    43     settings.set_alias(_T("scheduler"), alias); 
     43    settings.set_alias(alias, _T("scheduler")); 
    4444 
    4545    settings.alias().add_path_to_settings() 
  • modules/Scheduler/simple_scheduler.cpp

    racf0660 r9c06054  
    7878 
    7979  void simple_scheduler::thread_proc(int id) { 
    80     int iteration = 0; 
    81     schedule_queue_type::value_type instance; 
    82     while (!stop_requested_) { 
    83       instance = queue_.pop(); 
    84       if (!instance) { 
    85         boost::unique_lock<boost::mutex> lock(idle_thread_mutex_); 
    86         idle_thread_cond_.wait(lock); 
    87         continue; 
     80    try { 
     81      int iteration = 0; 
     82      schedule_queue_type::value_type instance; 
     83      while (!stop_requested_) { 
     84        instance = queue_.pop(); 
     85        if (!instance) { 
     86          boost::unique_lock<boost::mutex> lock(idle_thread_mutex_); 
     87          idle_thread_cond_.wait(lock); 
     88          continue; 
     89        } 
     90 
     91        try { 
     92          boost::posix_time::time_duration off = now() - (*instance).time; 
     93          if (off.total_seconds() > error_threshold_) { 
     94            log_error(_T("Ran scheduled item ") + to_wstring((*instance).schedule_id) + _T(" ") + to_wstring(off.total_seconds()) + _T(" seconds to late from thread ") + to_wstring(id)); 
     95          } 
     96          boost::thread::sleep((*instance).time); 
     97        } catch (boost::thread_interrupted  &e) { 
     98          if (!queue_.push(*instance)) 
     99            log_error(_T("ERROR")); 
     100          if (stop_requested_) { 
     101            log_error(_T("Terminating thread: ") + to_wstring(id)); 
     102            return; 
     103          } 
     104          continue; 
     105        } catch (...) { 
     106          if (!queue_.push(*instance)) 
     107            log_error(_T("ERROR")); 
     108          continue; 
     109        } 
     110 
     111        boost::posix_time::ptime now_time = now(); 
     112        boost::optional<target> item = get_task((*instance).schedule_id); 
     113        if (item) { 
     114          try { 
     115            if (handler_) 
     116              handler_->handle_schedule(*item); 
     117            reschedule(*item,now_time); 
     118          } catch (...) { 
     119            log_error(_T("UNKNOWN ERROR RUNING TASK: ")); 
     120            reschedule(*item); 
     121          } 
     122        } else { 
     123          log_error(_T("Task not found: ") + to_wstring((*instance).schedule_id)); 
     124        } 
    88125      } 
     126    } catch (const std::exception &e) { 
     127      log_error(_T("Exception in scheduler thread (thread will be killed): ") + utf8::to_unicode(e.what())); 
     128    } catch (...) { 
     129      log_error(_T("Exception in scheduler thread (thread will be killed)")); 
     130    } 
    89131 
    90       try { 
    91         boost::posix_time::time_duration off = now() - (*instance).time; 
    92         if (off.total_seconds() > error_threshold_) { 
    93           log_error(_T("Ran scheduled item ") + to_wstring((*instance).schedule_id) + _T(" ") + to_wstring(off.total_seconds()) + _T(" seconds to late from thread ") + to_wstring(id)); 
    94         } 
    95         boost::thread::sleep((*instance).time); 
    96       } catch (boost::thread_interrupted  &e) { 
    97         if (!queue_.push(*instance)) 
    98           log_error(_T("ERROR")); 
    99         if (stop_requested_) { 
    100           log_error(_T("Terminating thread: ") + to_wstring(id)); 
    101           return; 
    102         } 
    103         continue; 
    104       } catch (...) { 
    105         if (!queue_.push(*instance)) 
    106           log_error(_T("ERROR")); 
    107         continue; 
    108       } 
    109  
    110       boost::posix_time::ptime now_time = now(); 
    111       boost::optional<target> item = get_task((*instance).schedule_id); 
    112       if (item) { 
    113         try { 
    114           if (handler_) 
    115             handler_->handle_schedule(*item); 
    116           reschedule(*item,now_time); 
    117         } catch (...) { 
    118           log_error(_T("UNKNOWN ERROR RUNING TASK: ")); 
    119           reschedule(*item); 
    120         } 
    121       } else { 
    122         log_error(_T("Task not found: ") + to_wstring((*instance).schedule_id)); 
    123       } 
    124     } 
    125132  } 
    126133 
  • service/NSClient++.cpp

    r96c1461 r9c06054  
    689689  return true; 
    690690} 
    691 bool NSClientT::boot_load_plugins(bool boot) { 
     691bool NSClientT::boot_load_all_plugins() { 
    692692  LOG_DEBUG_CORE(_T("booting::loading plugins")); 
    693693  try { 
     
    717717  } catch (settings::settings_exception e) { 
    718718    LOG_ERROR_CORE_STD(_T("Settings exception when loading modules: ") + e.getMessage()); 
     719    return false; 
    719720  } catch (...) { 
    720721    LOG_ERROR_CORE_STD(_T("Unknown exception when loading plugins")); 
    721722    return false; 
    722723  } 
     724  return true; 
     725} 
     726 
     727bool NSClientT::boot_load_plugin(std::wstring plugin) { 
     728  try { 
     729    if (plugin.length() > 4 && plugin.substr(plugin.length()-4) == _T(".dll")) 
     730      plugin = plugin.substr(0, plugin.length()-4); 
     731 
     732    std::wstring plugin_file = NSCPlugin::get_plugin_file(plugin); 
     733    boost::filesystem::wpath pluginPath = expand_path(_T("${module-path}")); 
     734    boost::filesystem::wpath file = pluginPath / plugin_file; 
     735    if (boost::filesystem::is_regular(file)) { 
     736      plugin_type plugin = addPlugin(file, _T("")); 
     737    } else { 
     738      LOG_ERROR_CORE_STD(_T("Failed to load: ") + std::wstring(plugin)); 
     739      return false; 
     740    } 
     741  } catch (const NSPluginException &e) { 
     742    LOG_ERROR_CORE_STD(_T("Module (") + e.file_ + _T(") was not found: ") + e.error_); 
     743    return false; 
     744  } catch(const std::exception &e) { 
     745    LOG_ERROR_CORE_STD(_T("Module (") + plugin + _T(") was not found: ") + utf8::to_unicode(e.what())); 
     746    return false; 
     747  } catch(...) { 
     748    LOG_ERROR_CORE_STD(_T("Module (") + plugin + _T(") was not found...")); 
     749    return false; 
     750  } 
     751  return true; 
     752} 
     753bool NSClientT::boot_start_plugins(bool boot) { 
    723754  try { 
    724755    loadPlugins(boot?NSCAPI::normalStart:NSCAPI::dontStart); 
     
    848879 */ 
    849880void NSClientT::unloadPlugins(bool unloadLoggers) { 
     881  if (unloadLoggers) 
    850882  { 
    851883    boost::unique_lock<boost::shared_mutex> writeLock(m_mutexRW, boost::get_system_time() + boost::posix_time::seconds(10)); 
     
    854886      return; 
    855887    } 
    856     if (unloadLoggers) 
    857       logger_master_.remove_all_plugins(); 
     888    logger_master_.remove_all_plugins(); 
    858889  } 
    859890  { 
     
    14671498  service_name_ = service_name; 
    14681499  boot_init(); 
    1469   boot_load_plugins(true); 
     1500  boot_load_all_plugins(); 
     1501  boot_start_plugins(true); 
    14701502/* 
    14711503  DWORD dwSessionId = remote_processes::getActiveSessionId(); 
  • service/NSClient++.h

    r96c1461 r9c06054  
    132132  // Service helper functions 
    133133  bool boot_init(); 
    134   bool boot_load_plugins(bool boot); 
     134  bool boot_load_all_plugins(); 
     135  bool boot_load_plugin(std::wstring plugin); 
     136  bool boot_start_plugins(bool boot); 
    135137  bool exitCore(bool boot); 
    136138  void set_settings_context(std::wstring context) { context_ = context; } 
  • service/cli_parser.hpp

    r96c1461 r9c06054  
    7575 
    7676    client.add_options() 
    77       ("exec,e", po::value<std::wstring>(), "Run a command (execute)") 
     77      ("exec,e", po::value<std::wstring>()->implicit_value(_T("")), "Run a command (execute)") 
     78      ("boot,b", "Boot the client before executing command (similar as running the command from test)") 
    7879      ("query,q", po::value<std::wstring>(), "Run a query with a given name") 
    7980      ("submit,s", po::value<std::wstring>(), "Name of query to ask") 
     
    335336 
    336337      std::wstring command; 
    337       enum modes { exec, query, submit}; 
    338       modes mode; 
     338      enum modes { exec, query, submit, none}; 
     339      modes mode = none; 
    339340 
    340341      if (vm.count("exec")) { 
     
    346347        mode = query; 
    347348      } 
     349      if (vm.count("submit")) { 
     350        command = vm["submit"].as<std::wstring>(); 
     351        mode = submit; 
     352      } 
    348353 
    349354      if (vm.count("module")) 
    350355        module = vm["module"].as<std::wstring>(); 
     356 
     357      bool boot = false; 
     358      if (vm.count("boot")) 
     359        boot = true; 
    351360 
    352361      std::vector<std::wstring> kvp_args; 
     
    382391        mainClient.log_info(__FILE__, __LINE__, _T("Command: ") + command); 
    383392        mainClient.log_info(__FILE__, __LINE__, _T("Mode: ") + strEx::itos(mode)); 
     393        mainClient.log_info(__FILE__, __LINE__, _T("Boot: ") + strEx::itos(boot)); 
    384394        std::wstring args; 
    385395        BOOST_FOREACH(std::wstring s, arguments) 
     
    388398      } 
    389399      core_->boot_init(); 
    390       if (module.empty()) { 
    391         core_->boot_load_plugins(false); 
    392       } 
     400      if (module.empty()) 
     401        core_->boot_load_all_plugins(); 
     402      else 
     403        core_->boot_load_plugin(module); 
     404      core_->boot_start_plugins(boot); 
    393405      int ret = 0; 
    394406      std::list<std::wstring> resp; 
     407      if (mode == none) { 
     408        mode = exec; 
     409        std::wcerr << _T("Since no mode was specified assuming --exec (other options are --query and --submit)") << std::endl; 
     410      } 
    395411      if (mode == query) { 
    396412        ret = mainClient.simple_query(module, command, arguments, resp); 
     413      } else if (mode == exec) { 
     414        ret = mainClient.simple_exec(module, command, arguments, resp); 
     415        if (ret == NSCAPI::returnIgnored) { 
     416          ret = 1; 
     417          std::wcout << _T("Command not found (by module): ") << command << std::endl; 
     418          mainClient.simple_exec(module, _T("help"), arguments, resp); 
     419        } 
    397420      } else { 
    398         if (command.empty()) { 
    399           mainClient.simple_exec(module, _T("help"), arguments, resp); 
    400           ret = 1; 
    401         } else { 
    402           ret = mainClient.simple_exec(module, command, arguments, resp); 
    403           if (ret == NSCAPI::returnIgnored) { 
    404             ret = 1; 
    405             std::wcout << _T("Command not found (by module): ") << command << std::endl; 
    406             mainClient.simple_exec(module, _T("help"), arguments, resp); 
    407           } 
    408         } 
    409       } 
    410       mainClient.exitCore(false); 
     421        std::wcerr << _T("Need to specify one of --exec, --query or --submit") << std::endl; 
     422      } 
     423      mainClient.exitCore(boot); 
    411424 
    412425      BOOST_FOREACH(std::wstring r, resp) { 
     
    415428      return ret; 
    416429    } catch(std::exception & e) { 
    417       mainClient.log_error(__FILE__, __LINE__, std::string("Client: Unable to parse command line: ") + e.what()); 
     430      std::wcerr << _T("Client: Unable to parse command line: ") << utf8::to_unicode(e.what()) << std::endl; 
    418431      return 1; 
    419432    } catch(...) { 
    420       mainClient.log_error(__FILE__, __LINE__, "Unknown exception parsing command line"); 
     433      std::wcerr << _T("Client: Unable to parse command line: UNKNOWN") << std::endl; 
    421434      return 1; 
    422435    } 
  • service/settings_client.hpp

    r58f0e80 r9c06054  
    2626        return; 
    2727      } 
    28       if (!core_->boot_load_plugins(false)) { 
    29         std::wcout << _T("boot::load_plugins failed!") << std::endl; 
     28      if (!core_->boot_load_all_plugins()) { 
     29        std::wcout << _T("boot::load_all_plugins failed!") << std::endl; 
     30        return; 
     31      } 
     32      if (!core_->boot_start_plugins(false)) { 
     33        std::wcout << _T("boot::start_plugins failed!") << std::endl; 
    3034        return; 
    3135      } 
  • service/simple_client.hpp

    rfb7e36a r9c06054  
    1919        return; 
    2020      } 
    21       if (!core_->boot_load_plugins(true)) { 
    22         core_->log_error(__FILE__, __LINE__, _T("Service failed to load plugin")); 
     21      if (!core_->boot_load_all_plugins()) { 
     22        core_->log_error(__FILE__, __LINE__, _T("Service failed to load plugins")); 
     23        return; 
     24      } 
     25      if (!core_->boot_start_plugins(true)) { 
     26        core_->log_error(__FILE__, __LINE__, _T("Service failed to start plugins")); 
    2327        return; 
    2428      } 
Note: See TracChangeset for help on using the changeset viewer.