2011-06-21 Vanessa Gil <vanessa.gil@artica.es>
* win32/pandora_windows_service.cc win32/modules/pandora_module.cc win32/modules/pandora_module.h win32/modules/pandora_module_factory.cc unix/pandora_agent: Allow the windows and unix agent to include preconditions on modules. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@4474 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
parent
ae8dff9657
commit
883dd23579
|
@ -1,3 +1,11 @@
|
|||
2011-06-21 Vanessa Gil <vanessa.gil@artica.es>
|
||||
|
||||
* win32/pandora_windows_service.cc
|
||||
win32/modules/pandora_module.cc
|
||||
win32/modules/pandora_module.h
|
||||
win32/modules/pandora_module_factory.cc
|
||||
unix/pandora_agent: Allow the windows and unix agent to include preconditions on modules.
|
||||
|
||||
2011-06-09 Vanessa Gil <vanessa.gil@artica.es>
|
||||
|
||||
* unix/pandora_agent: Clean the code: parse configuration files.
|
||||
|
|
|
@ -16,7 +16,7 @@ Version 3.2
|
|||
|
||||
=head1 USAGE
|
||||
|
||||
C<< pandora_agent F<pandora home> >>
|
||||
<< pandora_agent F<pandora home> >>
|
||||
|
||||
=cut
|
||||
|
||||
|
@ -314,7 +314,9 @@ sub parse_conf_modules($) {
|
|||
'conditions' => [],
|
||||
'cron' => '',
|
||||
'cron_utimestamp' => 0,
|
||||
'cron_interval' => -1
|
||||
'cron_interval' => -1,
|
||||
'precondition' => [],
|
||||
'precon'=> 0
|
||||
};
|
||||
} elsif ($line =~ /^\s*module_name\s+(.+)$/) {
|
||||
$module->{'name'} = $1;
|
||||
|
@ -322,6 +324,19 @@ sub parse_conf_modules($) {
|
|||
$module->{'description'} = $1;
|
||||
} elsif ($line =~ /^\s*module_type\s+(\S+)\s*$/) {
|
||||
$module->{'type'} = $1;
|
||||
}elsif ($line =~ /^\s*module_precondition\s+(.*)$/) {
|
||||
my $action = $1;
|
||||
$module->{'precon'} = 1;
|
||||
# Numeric comparison
|
||||
if ($action =~ /^\s*([<>!=]+)\s+(\d+\.\d*)\s+(.*)$/) {
|
||||
push (@{$module->{'precondition'}}, {'operator' => $1, 'value_1' => $2, 'command' => $3});
|
||||
# Interval
|
||||
} elsif ($action =~ /^\s*[(]\s*(\d+\.\d*)\s*,\s*(\d+\.\d*)\s*[)]\s+(.*)$/) {
|
||||
push (@{$module->{'precondition'}}, {'operator' => '()', 'value_1' => $1, 'value_2' => $2, 'command' => $3});
|
||||
# Regular expression
|
||||
} elsif ($action =~ /^\s*=~\s+(\S*)\s+(.*)$/) {
|
||||
push (@{$module->{'precondition'}}, {'operator' => '=~', 'value_1' => $1, 'command' => $2});
|
||||
}
|
||||
} elsif ($line =~ /^\s*module_exec\s+(.+)$/) {
|
||||
$module->{'func'} = \&module_exec;
|
||||
$module->{'params'} = $1;
|
||||
|
@ -1002,13 +1017,45 @@ sub load_parts () {
|
|||
$Parts{'__utimestamp__'} = $utimestamp;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Execute the given command precondition.
|
||||
################################################################################
|
||||
sub module_precondition_exec ($) {
|
||||
my $module = shift;
|
||||
my @data;
|
||||
|
||||
# Check module parameters
|
||||
return () unless ($module->{'params_precon'} ne '');
|
||||
|
||||
# Execute the command
|
||||
if ($module->{'timeout'} == 0) {
|
||||
@data = `$module->{'params_precon'} 2> $DevNull`;
|
||||
} else {
|
||||
my $cmd = quotemeta ($module->{'params_precon'});
|
||||
@data = `$Conf{'pandora_exec'} $module->{'timeout'} $cmd 2> $DevNull`;
|
||||
}
|
||||
|
||||
# Something went wrong or no data
|
||||
return () unless ($? eq 0 && defined ($data[0]));
|
||||
|
||||
# Evaluate module preconditions
|
||||
evaluate_module_preconditions ($module, $data[0]);
|
||||
|
||||
return @data;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Execute the given command.
|
||||
################################################################################
|
||||
sub module_exec ($) {
|
||||
my $module = shift;
|
||||
my @data;
|
||||
my $exe;
|
||||
|
||||
$exe = evaluate_module_preconditions ($module);
|
||||
|
||||
return @data if ($exe == 0);
|
||||
|
||||
# Check module parameters
|
||||
return () unless ($module->{'params'} ne '');
|
||||
|
||||
|
@ -1192,6 +1239,37 @@ sub module_freepercentmemory ($) {
|
|||
return sprintf (("%d", $avail * 100 / $total));
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Evaluate and execute module preconditions.
|
||||
################################################################################
|
||||
sub evaluate_module_preconditions ($) {
|
||||
my ($module) = @_;
|
||||
my $exe = 1;
|
||||
|
||||
# Evaluate preconditions
|
||||
if ($module->{'precon'}){
|
||||
|
||||
foreach my $precondition (@{$module->{'precondition'}}) {
|
||||
|
||||
my $data = `$precondition->{'command'} 2> $DevNull`;
|
||||
|
||||
if (($precondition->{'operator'} eq '>' && $data > $precondition->{'value_1'}) ||
|
||||
($precondition->{'operator'} eq '<' && $data < $precondition->{'value_1'}) ||
|
||||
($precondition->{'operator'} eq '=' && $data == $precondition->{'value_1'}) ||
|
||||
($precondition->{'operator'} eq '!=' && $data != $precondition->{'value_1'}) ||
|
||||
($precondition->{'operator'} eq '=~' && $data =~ /$precondition->{'value_1'}/) ||
|
||||
($precondition->{'operator'} eq '()' && $data > $precondition->{'value_1'} && $data < $precondition->{'value_2'})) {
|
||||
$exe = 1;
|
||||
} else {
|
||||
$exe = 0;
|
||||
return $exe;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $exe;
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
# Evaluate and execute module conditions.
|
||||
################################################################################
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
using namespace Pandora;
|
||||
using namespace Pandora_Modules;
|
||||
using namespace Pandora_Strutils;
|
||||
|
@ -50,6 +52,7 @@ Pandora_Module::Pandora_Module (string name) {
|
|||
this->async = false;
|
||||
this->data_list = NULL;
|
||||
this->inventory_list = NULL;
|
||||
this->precondition_list = NULL;
|
||||
this->condition_list = NULL;
|
||||
this->cron = NULL;
|
||||
}
|
||||
|
@ -61,11 +64,29 @@ Pandora_Module::Pandora_Module (string name) {
|
|||
*/
|
||||
Pandora_Module::~Pandora_Module () {
|
||||
Condition *cond = NULL;
|
||||
Precondition *precond = NULL;
|
||||
list<Condition *>::iterator iter;
|
||||
list<Precondition *>::iterator iter_pre;
|
||||
|
||||
/* Clean data lists */
|
||||
this->cleanDataList ();
|
||||
|
||||
/* Clean precondition list */
|
||||
if (this->precondition_list != NULL && this->precondition_list->size () > 0) {
|
||||
iter_pre = this->precondition_list->begin ();
|
||||
for (iter_pre = this->precondition_list->begin ();
|
||||
iter_pre != this->precondition_list->end ();
|
||||
iter++) {
|
||||
/* Free regular expressions */
|
||||
precond = *iter_pre;
|
||||
if (precond->string_value != "") {
|
||||
regfree (&(precond->regexp));
|
||||
}
|
||||
delete (*iter_pre);
|
||||
}
|
||||
delete (this->precondition_list);
|
||||
}
|
||||
|
||||
/* Clean condition list */
|
||||
if (this->condition_list != NULL && this->condition_list->size () > 0) {
|
||||
iter = this->condition_list->begin ();
|
||||
|
@ -674,6 +695,63 @@ Pandora_Module::getSave () {
|
|||
return this->save;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new precondition to the module.
|
||||
*
|
||||
* @param precondition string.
|
||||
*/
|
||||
void
|
||||
Pandora_Module::addPrecondition (string precondition) {
|
||||
Precondition *precond;
|
||||
char operation[256], string_value[1024], command[1024];
|
||||
|
||||
/* Create the precondition list if it does not exist */
|
||||
if (this->precondition_list == NULL) {
|
||||
this->precondition_list = new list<Precondition *> ();
|
||||
}
|
||||
|
||||
/* Create the new precondition */
|
||||
precond = new Precondition;
|
||||
if (precond == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
precond->value_1 = 0;
|
||||
precond->value_2 = 0;
|
||||
|
||||
/* Numeric comparison */
|
||||
if (sscanf (precondition.c_str (), "%255s %lf %1023[^\n]s", operation, &(precond->value_1), command) == 3) {
|
||||
precond->operation = operation;
|
||||
precond->command = command;
|
||||
precond->command = "cmd.exe /c \"" + precond->command + "\"";
|
||||
this->precondition_list->push_back (precond);
|
||||
return;
|
||||
|
||||
/* Regular expression */
|
||||
} else if (sscanf (precondition.c_str (), "=~ %1023s %1023[^\n]s", string_value, command) == 2) {
|
||||
precond->operation = "=~";
|
||||
precond->string_value = string_value;
|
||||
precond->command = command;
|
||||
if (regcomp (&(precond->regexp), string_value, 0) != 0) {
|
||||
pandoraDebug ("Invalid regular expression %s", string_value);
|
||||
delete (precond);
|
||||
return;
|
||||
}
|
||||
this->precondition_list->push_back (precond);
|
||||
|
||||
/* Interval */
|
||||
} else if (sscanf (precondition.c_str (), "(%lf , %lf) %1023[^\n]s", &(precond->value_1), &(precond->value_2), command) == 3) {
|
||||
precond->operation = "()";
|
||||
precond->command = command;
|
||||
this->precondition_list->push_back (precond);
|
||||
} else {
|
||||
pandoraDebug ("Invalid module condition: %s", precondition.c_str ());
|
||||
delete (precond);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new condition to the module.
|
||||
*
|
||||
|
@ -701,7 +779,7 @@ Pandora_Module::addCondition (string condition) {
|
|||
if (sscanf (condition.c_str (), "%255s %lf %1023[^\n]s", operation, &(cond->value_1), command) == 3) {
|
||||
cond->operation = operation;
|
||||
cond->command = command;
|
||||
this->condition_list->push_back (cond);
|
||||
this->condition_list->push_back (cond);
|
||||
/* Regular expression */
|
||||
} else if (sscanf (condition.c_str (), "=~ %1023s %1023[^\n]s", string_value, command) == 2) {
|
||||
cond->operation = "=~";
|
||||
|
@ -712,7 +790,7 @@ Pandora_Module::addCondition (string condition) {
|
|||
delete (cond);
|
||||
return;
|
||||
}
|
||||
this->condition_list->push_back (cond);
|
||||
this->condition_list->push_back (cond);
|
||||
/* Interval */
|
||||
} else if (sscanf (condition.c_str (), "(%lf , %lf) %1023[^\n]s", &(cond->value_1), &(cond->value_2), command) == 3) {
|
||||
cond->operation = "()";
|
||||
|
@ -723,11 +801,174 @@ Pandora_Module::addCondition (string condition) {
|
|||
delete (cond);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Run commands through cmd.exe */
|
||||
cond->command = "cmd.exe /c \"" + cond->command + "\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates and executes module preconditions.
|
||||
*/
|
||||
int
|
||||
Pandora_Module::evaluatePreconditions () {
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
DWORD retval, dwRet;
|
||||
SECURITY_ATTRIBUTES attributes;
|
||||
HANDLE out, new_stdout, out_read, job;
|
||||
string working_dir;
|
||||
Precondition *precond = NULL;
|
||||
float float_output;
|
||||
list<Precondition *>::iterator iter;
|
||||
unsigned char run;
|
||||
int exe = 1;
|
||||
string output;
|
||||
|
||||
if (this->precondition_list != NULL && this->precondition_list->size () > 0) {
|
||||
|
||||
iter = this->precondition_list->begin ();
|
||||
for (iter = this->precondition_list->begin ();
|
||||
iter != this->precondition_list->end ();
|
||||
iter++) {
|
||||
|
||||
precond = *iter;
|
||||
run = 0;
|
||||
|
||||
|
||||
/* Set the bInheritHandle flag so pipe handles are inherited. */
|
||||
attributes.nLength = sizeof (SECURITY_ATTRIBUTES);
|
||||
attributes.bInheritHandle = TRUE;
|
||||
attributes.lpSecurityDescriptor = NULL;
|
||||
|
||||
/* Create a job to kill the child tree if it become zombie */
|
||||
/* CAUTION: In order to compile this, WINVER should be defined to 0x0500.
|
||||
This may need no change, since it was redefined by the
|
||||
program, but if needed, the macro is defined
|
||||
in <windef.h> */
|
||||
job = CreateJobObject (&attributes, this->module_name.c_str ());
|
||||
if (job == NULL) {
|
||||
pandoraLog ("CreateJobObject bad. Err: %d", GetLastError ());
|
||||
this->has_output = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the handle to the current STDOUT. */
|
||||
out = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
|
||||
if (! CreatePipe (&out_read, &new_stdout, &attributes, 0)) {
|
||||
pandoraLog ("CreatePipe failed. Err: %d", GetLastError ());
|
||||
this->has_output = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ensure the read handle to the pipe for STDOUT is not inherited */
|
||||
SetHandleInformation (out_read, HANDLE_FLAG_INHERIT, 0);
|
||||
|
||||
/* Set up members of the STARTUPINFO structure. */
|
||||
ZeroMemory (&si, sizeof (si));
|
||||
GetStartupInfo (&si);
|
||||
|
||||
si.cb = sizeof (si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
si.hStdError = new_stdout;
|
||||
si.hStdOutput = new_stdout;
|
||||
|
||||
/* Set up members of the PROCESS_INFORMATION structure. */
|
||||
ZeroMemory (&pi, sizeof (pi));
|
||||
pandoraDebug ("Executing: %s", precond->command.c_str ());
|
||||
|
||||
/* Set the working directory of the process. It's "utils" directory
|
||||
to find the GNU W32 tools */
|
||||
working_dir = getPandoraInstallDir () + "util\\";
|
||||
|
||||
/* Create the child process. */
|
||||
if (! CreateProcess (NULL, (CHAR *) precond->command.c_str (), NULL,
|
||||
NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW, NULL,
|
||||
working_dir.c_str (), &si, &pi)) {
|
||||
pandoraLog ("Pandora_Module_Exec: %s CreateProcess failed. Err: %d",
|
||||
this->module_name.c_str (), GetLastError ());
|
||||
this->has_output = false;
|
||||
} else {
|
||||
char buffer[BUFSIZE + 1];
|
||||
unsigned long read, avail;
|
||||
|
||||
if (! AssignProcessToJobObject (job, pi.hProcess)) {
|
||||
pandoraLog ("Could not assigned proccess to job (error %d)",
|
||||
GetLastError ());
|
||||
}
|
||||
ResumeThread (pi.hThread);
|
||||
|
||||
/*string output;*/
|
||||
int tickbase = GetTickCount();
|
||||
while ( (dwRet = WaitForSingleObject (pi.hProcess, 500)) != WAIT_ABANDONED ) {
|
||||
PeekNamedPipe (out_read, buffer, BUFSIZE, &read, &avail, NULL);
|
||||
if (avail > 0) {
|
||||
ReadFile (out_read, buffer, BUFSIZE, &read, NULL);
|
||||
buffer[read] = '\0';
|
||||
output += (char *) buffer;
|
||||
}
|
||||
|
||||
float_output = atof(output.c_str());
|
||||
|
||||
if (dwRet == WAIT_OBJECT_0) {
|
||||
break;
|
||||
} else if(this->getTimeout() < GetTickCount() - tickbase) {
|
||||
/* STILL_ACTIVE */
|
||||
TerminateProcess(pi.hThread, STILL_ACTIVE);
|
||||
pandoraLog ("Pandora_Module_Exec: %s timed out (retcode: %d)", this->module_name.c_str (), STILL_ACTIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GetExitCodeProcess (pi.hProcess, &retval);
|
||||
|
||||
if (retval != 0) {
|
||||
if (! TerminateJobObject (job, 0)) {
|
||||
pandoraLog ("TerminateJobObject failed. (error %d)",
|
||||
GetLastError ());
|
||||
}
|
||||
if (retval != STILL_ACTIVE) {
|
||||
pandoraLog ("Pandora_Module_Exec: %s did not executed well (retcode: %d)",
|
||||
this->module_name.c_str (), retval);
|
||||
}
|
||||
this->has_output = false;
|
||||
}
|
||||
|
||||
if (!output.empty()) {
|
||||
this->setOutput (output);
|
||||
} else {
|
||||
this->setOutput ("");
|
||||
}
|
||||
|
||||
/* Close job, process and thread handles. */
|
||||
CloseHandle (job);
|
||||
CloseHandle (pi.hProcess);
|
||||
CloseHandle (pi.hThread);
|
||||
}
|
||||
|
||||
CloseHandle (new_stdout);
|
||||
CloseHandle (out_read);
|
||||
|
||||
if ((precond->operation == ">" && float_output > precond->value_1) ||
|
||||
(precond->operation == "<" && float_output < precond->value_1) ||
|
||||
(precond->operation == "=" && float_output == precond->value_1) ||
|
||||
(precond->operation == "!=" && float_output != precond->value_1) ||
|
||||
(precond->operation == "=~" && regexec (&(precond->regexp), output.c_str(), 0, NULL, 0) == 0) ||
|
||||
(precond->operation == "()" && float_output > precond->value_1 && float_output < precond->value_2)){
|
||||
exe = 1;
|
||||
} else {
|
||||
exe = 0;
|
||||
return exe;
|
||||
}
|
||||
|
||||
CloseHandle (pi.hProcess);
|
||||
}
|
||||
}
|
||||
return exe;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Evaluates and executes module conditions.
|
||||
*/
|
||||
|
|
|
@ -89,6 +89,18 @@ namespace Pandora_Modules {
|
|||
MODULE_PLUGIN /**< Plugin */
|
||||
} Module_Kind;
|
||||
|
||||
/**
|
||||
* Defines the structure that holds module preconditions.
|
||||
*/
|
||||
typedef struct {
|
||||
double value_1;
|
||||
double value_2;
|
||||
string string_value;
|
||||
string operation;
|
||||
string command;
|
||||
regex_t regexp;
|
||||
} Precondition;
|
||||
|
||||
/**
|
||||
* Defines the structure that holds module conditions.
|
||||
*/
|
||||
|
@ -165,6 +177,7 @@ namespace Pandora_Modules {
|
|||
Module_Kind module_kind;
|
||||
string save;
|
||||
list<Condition *> *condition_list;
|
||||
list<Precondition *> *precondition_list;
|
||||
Cron *cron;
|
||||
|
||||
protected:
|
||||
|
@ -248,7 +261,10 @@ namespace Pandora_Modules {
|
|||
void setSave (string save);
|
||||
|
||||
void exportDataOutput ();
|
||||
void addPrecondition ();
|
||||
void addCondition (string condition);
|
||||
void addPrecondition (string precondition);
|
||||
int evaluatePreconditions ();
|
||||
void evaluateConditions ();
|
||||
int checkCron ();
|
||||
void setCron (string cron_string);
|
||||
|
|
|
@ -85,6 +85,7 @@ using namespace Pandora_Strutils;
|
|||
#define TOKEN_CONDITION ("module_condition ")
|
||||
#define TOKEN_CRONTAB ("module_crontab ")
|
||||
#define TOKEN_CRONINTERVAL ("module_cron_interval ")
|
||||
#define TOKEN_PRECONDITION ("module_precondition ")
|
||||
|
||||
string
|
||||
parseLine (string line, string token) {
|
||||
|
@ -127,14 +128,16 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
|||
string module_retries, module_startdelay, module_retrydelay;
|
||||
string module_perfcounter, module_tcpcheck;
|
||||
string module_port, module_timeout, module_regexp;
|
||||
string module_plugin, module_save, module_condition;
|
||||
string module_plugin, module_save, module_condition, module_precondition;
|
||||
string module_crontab, module_cron_interval, module_post_process;
|
||||
Pandora_Module *module;
|
||||
bool numeric;
|
||||
Module_Type type;
|
||||
long agent_interval;
|
||||
list<string> condition_list;
|
||||
list<string> precondition_list;
|
||||
list<string>::iterator condition_iter;
|
||||
list<string>::iterator precondition_iter;
|
||||
|
||||
module_name = "";
|
||||
module_type = "";
|
||||
|
@ -172,6 +175,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
|||
module_crontab = "";
|
||||
module_cron_interval = "";
|
||||
module_post_process = "";
|
||||
module_precondition = "";
|
||||
|
||||
stringtok (tokens, definition, "\n");
|
||||
|
||||
|
@ -188,6 +192,15 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
|||
if (module_type == "") {
|
||||
module_type = parseLine (line, TOKEN_TYPE);
|
||||
}
|
||||
if (module_precondition == "") {
|
||||
module_precondition = parseLine (line, TOKEN_PRECONDITION);
|
||||
|
||||
/* Queue the precondition and keep looking for more */
|
||||
if (module_precondition != "") {
|
||||
precondition_list.push_back (module_precondition);
|
||||
module_precondition = "";
|
||||
}
|
||||
}
|
||||
if (module_interval == "") {
|
||||
module_interval = parseLine (line, TOKEN_INTERVAL);
|
||||
}
|
||||
|
@ -424,6 +437,16 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
|||
module->setAsync (true);
|
||||
}
|
||||
|
||||
/* Module precondition */
|
||||
if (precondition_list.size () > 0) {
|
||||
precondition_iter = precondition_list.begin ();
|
||||
for (precondition_iter = precondition_list.begin ();
|
||||
precondition_iter != precondition_list.end ();
|
||||
precondition_iter++) {
|
||||
module->addPrecondition (*precondition_iter);
|
||||
}
|
||||
}
|
||||
|
||||
/* Module condition */
|
||||
if (condition_list.size () > 0) {
|
||||
condition_iter = condition_list.begin ();
|
||||
|
|
|
@ -1159,6 +1159,7 @@ Pandora_Windows_Service::pandora_run () {
|
|||
string server_addr;
|
||||
int startup_delay = 0;
|
||||
static unsigned char delayed = 0;
|
||||
int exe = 1;
|
||||
|
||||
pandoraDebug ("Run begin");
|
||||
|
||||
|
@ -1189,7 +1190,11 @@ Pandora_Windows_Service::pandora_run () {
|
|||
Pandora_Module *module;
|
||||
|
||||
module = this->modules->getCurrentValue ();
|
||||
|
||||
exe = module->evaluatePreconditions ();
|
||||
|
||||
if (exe == 0) return;
|
||||
|
||||
pandoraDebug ("Run %s", module->getName ().c_str ());
|
||||
|
||||
if (module->checkCron () == 1) {
|
||||
|
|
Loading…
Reference in New Issue