コード例 #1
0
 /**
  * @test
  */
 public function addTimeslot()
 {
     $pfTimeslot = new PluginFusioninventoryTimeslot();
     $input = array('entities_id' => 0, 'is_recursive' => 0, 'name' => 'unitdefault');
     $pfTimeslot->add($input);
     $cnt = countElementsInTable('glpi_plugin_fusioninventory_timeslots');
     $this->assertEquals(1, $cnt, "Timeslot may be added");
     $GLPIlog = new GLPIlogs();
     $GLPIlog->testSQLlogs();
     $GLPIlog->testPHPlogs();
 }
コード例 #2
0
 /**
  * Get the list of taskjobstates
  */
 function getTaskjobstatesForAgent($agent_id, $methods = array(), $options = array())
 {
     global $DB;
     // Check for read only which means we do not change the jobstates state (especially usefull
     // for the get_agent_jobs.php script).
     $read_only = false;
     if (isset($options['read_only'])) {
         $read_only = $options['read_only'];
     }
     $pfTimeslot = new PluginFusioninventoryTimeslot();
     $jobstates = array();
     //Get the datetime of agent request
     $now = new Datetime();
     // list of jobstates not allowed to run (ie. filtered by schedule and timeslots)
     $jobstates_to_cancel = array();
     $query = implode(" \n", array("SELECT", "     task.`id`, task.`name`, task.`is_active`,", "     task.`datetime_start`, task.`datetime_end`,", "     task.`plugin_fusioninventory_timeslots_id` as timeslot_id,", "     job.`id`, job.`name`, job.`method`, job.`actors`,", "     run.`itemtype`, run.`items_id`, run.`state`,", "     run.`id`, run.`plugin_fusioninventory_agents_id`", "FROM `glpi_plugin_fusioninventory_taskjobstates` run", "LEFT JOIN `glpi_plugin_fusioninventory_taskjobs` job", "  ON job.`id` = run.`plugin_fusioninventory_taskjobs_id`", "LEFT JOIN `glpi_plugin_fusioninventory_tasks` task", "  ON task.`id` = job.`plugin_fusioninventory_tasks_id`", "WHERE", "  job.`method` IN ('" . implode("','", $methods) . "')", "  and run.`state` IN ('" . implode("','", array(PluginFusioninventoryTaskjobstate::PREPARED, PluginFusioninventoryTaskjobstate::SERVER_HAS_SENT_DATA, PluginFusioninventoryTaskjobstate::AGENT_HAS_SENT_DATA)) . "')", "  AND run.`plugin_fusioninventory_agents_id` = " . $agent_id, "ORDER BY job.`id`"));
     $query_result = $DB->query($query);
     $results = array();
     if ($query_result) {
         $results = PluginFusioninventoryToolbox::fetchAssocByTable($query_result);
     }
     // Fetch a list of unique actors since the same actor can be assigned to many jobs.
     $actors = array();
     foreach ($results as $result) {
         $actors_from_job = importArrayFromDB($result['job']['actors']);
         foreach ($actors_from_job as $actor) {
             $actor_key = "" . key($actor) . "_" . $actor[key($actor)];
             if (!isset($actors[$actor_key])) {
                 $actors[$actor_key] = array();
                 foreach ($this->getAgentsFromActors(array($actor)) as $agent) {
                     $actors[$actor_key][$agent] = true;
                 }
             }
         }
     }
     // Merge agents into one list
     $agents = array();
     foreach ($actors as $key => $agents_list) {
         //Toolbox::logDebug(array("agents_list count" => count($agents_list)));
         //Toolbox::logDebug(array("agents_list" => $agents_list));
         foreach ($agents_list as $id => $val) {
             if (!isset($agents[$id])) {
                 $agents[$id] = true;
             }
         }
     }
     $agents = array_keys($agents);
     //Toolbox::logDebug(array("final agents list count" => count($agents)));
     //Toolbox::logDebug(array("final agents list" => $agents));
     // Get timeslot's entries from this list at the time of the request (ie. get entries according
     // to the day of the week)
     $timeslot_entries = array();
     $day_of_week = $now->format("N");
     $timeslot_ids = array();
     foreach ($results as $result) {
         $timeslot_ids[$result['task']['timeslot_id']] = 1;
     }
     $timeslot_entries = $pfTimeslot->getTimeslotEntries(array_keys($timeslot_ids), $day_of_week);
     $timeslot_cursor = $pfTimeslot->getTimeslotCursor($now);
     /**
      * Ensure the agent's jobstates are allowed to run at the time of the agent's request.
      * The following checks if:
      * - The tasks associated with those taskjobs are not disabled.
      * - The task's schedule and timeslots still match the time those jobstates have been
      * requested.
      * - The agent is still present in the dynamic actors (eg. Dynamic groups)
      */
     foreach ($results as $result) {
         $jobstate = new PluginFusioninventoryTaskjobstate();
         $jobstate->getFromDB($result['run']['id']);
         //Cancel the job it has already been sent to the agent but the agent did not replied
         if ($result['run']['state'] == $jobstate::SERVER_HAS_SENT_DATA or $result['run']['state'] == $jobstate::AGENT_HAS_SENT_DATA) {
             $jobstates_to_cancel[$jobstate->fields['id']] = array('jobstate' => $jobstate, 'reason' => __("The agent is requesting a configuration that has already been sent to him by the server. It is more likely that the agent is subject to a critical error.", 'fusioninventory'), 'code' => $jobstate::IN_ERROR);
             continue;
         }
         //Cancel the jobstate if the related tasks has been deactivated
         if ($result['task']['is_active'] == 0) {
             $jobstates_to_cancel[$jobstate->fields['id']] = array('jobstate' => $jobstate, 'reason' => __('The task has been deactivated after preparation of this job.', 'fusioninventory'));
             continue;
         }
         // Cancel the jobstate if it the schedule doesn't match.
         if (!is_null($result['task']['datetime_start'])) {
             $schedule_start = new DateTime($result['task']['datetime_start']);
             if (!is_null($result['task']['datetime_end'])) {
                 $schedule_end = new DateTime($result['task']['datetime_end']);
             } else {
                 $schedule_end = $now;
             }
             if (!($schedule_start <= $now and $now <= $schedule_end)) {
                 $jobstates_to_cancel[$jobstate->fields['id']] = array('jobstate' => $jobstate, 'reason' => __("This job can not be executed anymore due to the task's schedule.", 'fusioninventory'));
                 continue;
             }
         }
         // Cancel the jobstate if it is requested outside of any timeslot.
         $timeslot_id = $result['task']['timeslot_id'];
         // Do nothing if there are no defined timeslots for this jobstate.
         if ($timeslot_id > 0) {
             $timeslot_matched = false;
             // We do nothing if there are no timeslot_entries, meaning this jobstate is not allowed
             // to be executed at the day of request.
             if (array_key_exists($timeslot_id, $timeslot_entries)) {
                 foreach ($timeslot_entries[$timeslot_id] as $timeslot_entry) {
                     if ($timeslot_entry['begin'] <= $timeslot_cursor and $timeslot_cursor <= $timeslot_entry['end']) {
                         //The timeslot cursor (ie. time of request) matched a timeslot entry so we can
                         //break the loop here.
                         $timeslot_matched = true;
                         break;
                     }
                 }
             }
             // If no timeslot matched, cancel this jobstate.
             if (!$timeslot_matched) {
                 $jobstates_to_cancel[$jobstate->fields['id']] = array('jobstate' => $jobstate, 'reason' => __("This job can not be executed anymore due to the task's timeslot.", 'fusioninventory'));
                 continue;
             }
         }
         // Make sure the agent is still present in the list of actors that generated
         // this jobstate.
         // TODO: If this jobstate needs to be cancelled, it would be worth to point out which actor
         // is the source of this execution. To do this, we need to track the 'actor_source' in the
         // jobstate when it's generated by prepareTaskjobs().
         //$job_actors = importArrayFromDB($result['job']['actors']);
         $chrono = microtime(true);
         if (!in_array($agent_id, $agents)) {
             $jobstates_to_cancel[$jobstate->fields['id']] = array('jobstate' => $jobstate, 'reason' => __('This agent does not belong anymore in the actors defined in the job.', 'fusioninventory'));
             continue;
         }
         //Toolbox::logDebug(
         //   sprintf(
         //      "Time to check if '%s' is still in actors list: %5.6f",
         //      $_GET['machineid'],(microtime(true) - $chrono)
         //   )
         //);
         //TODO: The following method (actually defined as member of taskjob) needs to be
         //initialized when getting the jobstate from DB (with a getfromDB hook for example)
         $jobstate->method = $result['job']['method'];
         //Add the jobstate to the list since previous checks are good.
         $jobstates[$jobstate->fields['id']] = $jobstate;
     }
     //Remove the list of jobstates previously filtered for removal.
     foreach ($jobstates_to_cancel as $jobstate) {
         if (!isset($jobstate['code'])) {
             $jobstate['code'] = PluginFusioninventoryTaskjobstate::CANCELLED;
         }
         switch ($jobstate['code']) {
             case PluginFusioninventoryTaskjobstate::IN_ERROR:
                 $jobstate['jobstate']->fail($jobstate['reason']);
                 break;
             default:
                 $jobstate['jobstate']->cancel($jobstate['reason']);
                 break;
         }
     }
     return $jobstates;
 }
コード例 #3
0
 static function cronWakeupAgents($crontask)
 {
     global $DB;
     $wakeupArray = array();
     $tasks = array();
     //Get the maximum number of agent to wakeup,
     //as allowed in the general configuration
     $config = new PluginFusioninventoryConfig();
     $maxWakeUp = $config->getValue('wakeup_agent_max');
     $counter = 0;
     $continue = true;
     //Get all active timeslots
     $timeslot = new PluginFusioninventoryTimeslot();
     $timeslots = $timeslot->getCurrentActiveTimeslots();
     if (empty($timeslots)) {
         $query_timeslot = '';
     } else {
         $query_timeslot = "OR (`plugin_fusioninventory_timeslots_id` IN (" . implode(',', $timeslots) . "))";
     }
     //Get all active task requiring an agent wakeup
     //Check all tasks without timeslot or task with a current active timeslot
     $query = "SELECT `id`, `wakeup_agent_counter`, `wakeup_agent_time`, `last_agent_wakeup` \n                 FROM `glpi_plugin_fusioninventory_tasks` \n                 WHERE `wakeup_agent_time` > 0 \n                    AND `wakeup_agent_counter` > 0\n                    AND `is_active`='1' \n                    AND ((`plugin_fusioninventory_timeslots_id`='0') \n                    {$query_timeslot})";
     foreach ($DB->request($query) as $task) {
         if (!is_null($task['wakeup_agent_time'])) {
             //Do not wake up is last wake up in inferior to the minimum wake up interval
             $interval = time() - strtotime($task['last_agent_wakeup']);
             if ($interval < $task['wakeup_agent_time'] * MINUTE_TIMESTAMP) {
                 continue;
             }
         }
         //For each task, get a number of taskjobs at the PREPARED state
         //(the maximum is defined in wakeup_agent_counter)
         $query_states = "SELECT `taskjobstates`.`plugin_fusioninventory_agents_id`, \n                                 `tasks`.`id` as `taskID`, \n                                 `tasks`.`wakeup_agent_time`,\n                                 `tasks`.`last_agent_wakeup`\n                          FROM `glpi_plugin_fusioninventory_taskjobstates` as `taskjobstates`,\n                               `glpi_plugin_fusioninventory_taskjobs` as `taskjobs`\n                          LEFT JOIN `glpi_plugin_fusioninventory_tasks` as `tasks` \n                             ON `tasks`.`id`=`taskjobs`.`plugin_fusioninventory_tasks_id`\n                          WHERE `tasks`.`id`='" . $task['id'] . "' \n                             AND `taskjobs`.`id`=`taskjobstates`.`plugin_fusioninventory_taskjobs_id` \n                             AND `taskjobstates`.`state`='" . PluginFusioninventoryTaskjobstate::PREPARED . "' \n                          ORDER BY `taskjobstates`.`id` ASC LIMIT " . $task['wakeup_agent_counter'];
         foreach ($DB->request($query_states) as $state) {
             $agents_id = $state['plugin_fusioninventory_agents_id'];
             //Check if agent is already added to the list of agents to wake up
             if (!isset($wakeupArray[$agents_id])) {
                 //This agent must be woken up
                 $wakeupArray[$agents_id] = $agents_id;
                 $counter++;
             }
             //Store task ID
             if (!in_array($state['taskID'], $tasks)) {
                 $tasks[] = $state['taskID'];
             }
             //Do not process more than the maximum number of wakeup allowed in the configuration
             if ($counter >= $maxWakeUp) {
                 if (PluginFusioninventoryConfig::isExtradebugActive()) {
                     Toolbox::logDebug(__("Maximum number of agent wakeup reached", 'fusioninventory') . ":" . $maxWakeUp);
                 }
                 $continue = false;
                 break;
             }
         }
         //We've reached the maximum number of agents to wake up !
         if (!$continue) {
             break;
         }
     }
     //Number of agents successfully woken up
     $wokeup = 0;
     $myTask = new PluginFusioninventoryTask();
     if (!empty($tasks)) {
         //Update last wake up time each task
         $query_lastrun = "UPDATE `glpi_plugin_fusioninventory_tasks` \n                           SET `last_agent_wakeup`='" . $_SESSION['glpi_currenttime'] . "' \n                           WHERE `id` IN (" . implode(",", $tasks) . ")";
         $DB->query($query_lastrun);
         $agent = new PluginFusioninventoryAgent();
         //Try to wake up agents one by one
         foreach ($wakeupArray as $ID => $value) {
             $agent->getFromDB($ID);
             if ($agent->wakeUp()) {
                 $wokeup++;
             }
         }
     }
     $crontask->addVolume($wokeup);
     return true;
 }
コード例 #4
0
  @co-author
  @copyright Copyright (c) 2010-2014 FusionInventory team
  @license   AGPL License 3.0 or (at your option) any later version
             http://www.gnu.org/licenses/agpl-3.0-standalone.html
  @link      http://www.fusioninventory.org/
  @link      http://forge.fusioninventory.org/projects/fusioninventory-for-glpi/
  @since     2014

  ------------------------------------------------------------------------
*/
include "../../../inc/includes.php";
Session::checkRight('plugin_fusioninventory_task', READ);
if (!isset($_GET["id"])) {
    $_GET["id"] = "";
}
$pfTimeslot = new PluginFusioninventoryTimeslot();
//Add a new timeslot
if (isset($_POST["add"])) {
    $pfTimeslot->check(-1, CREATE, $_POST);
    if ($newID = $pfTimeslot->add($_POST)) {
        if ($_SESSION['glpibackcreated']) {
            Html::redirect($pfTimeslot->getFormURL() . "?id=" . $newID);
        }
    }
    Html::back();
    // delete a timeslot
} else {
    if (isset($_POST["delete"])) {
        $pfTimeslot->check($_POST['id'], DELETE);
        $ok = $pfTimeslot->delete($_POST);
        $pfTimeslot->redirectToList();