Go lang check agents
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
inc/check_status
|
||||||
150
inc/check_status.go
Normal file
150
inc/check_status.go
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
"io/ioutil"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// a struct to hold the result from each request including an index
|
||||||
|
// which will be used for sorting the results after they come in
|
||||||
|
type result struct {
|
||||||
|
id int
|
||||||
|
status int
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
type check struct {
|
||||||
|
// defining struct variables
|
||||||
|
Url string `json:"url"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Computers_id int `json:"computers_id"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// boundedParallelGet sends requests in parallel but only up to a certain
|
||||||
|
// limit, and furthermore it's only parallel up to the amount of CPUs but
|
||||||
|
// is always concurrent up to the concurrency limit
|
||||||
|
func boundedParallelGet(Checks []check, concurrencyLimit int) []check {
|
||||||
|
|
||||||
|
// this buffered channel will block at the concurrency limit
|
||||||
|
semaphoreChan := make(chan struct{}, concurrencyLimit)
|
||||||
|
|
||||||
|
// this channel will not block and collect the http request results
|
||||||
|
resultsChan := make(chan *result)
|
||||||
|
|
||||||
|
// make sure we close these channels when we're done with them
|
||||||
|
defer func() {
|
||||||
|
close(semaphoreChan)
|
||||||
|
close(resultsChan)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// keen an index and loop through every url we will send a request to
|
||||||
|
for _,chck := range Checks {
|
||||||
|
|
||||||
|
// start a go routine with the index and url in a closure
|
||||||
|
go func(chck check) {
|
||||||
|
var status int
|
||||||
|
|
||||||
|
// this sends an empty struct into the semaphoreChan which
|
||||||
|
// is basically saying add one to the limit, but when the
|
||||||
|
// limit has been reached block until there is room
|
||||||
|
semaphoreChan <- struct{}{}
|
||||||
|
|
||||||
|
// send the request and put the response in a result struct
|
||||||
|
// along with the index so we can sort them later along with
|
||||||
|
// any error that might have occoured
|
||||||
|
//fmt.Println(chck.Url)
|
||||||
|
|
||||||
|
client := http.Client{
|
||||||
|
Timeout: 7 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := client.Get(chck.Url)
|
||||||
|
|
||||||
|
status = 404
|
||||||
|
if err == nil {
|
||||||
|
status = res.StatusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &result{chck.Id, status, err}
|
||||||
|
// now we can send the result struct through the resultsChan
|
||||||
|
resultsChan <- result
|
||||||
|
|
||||||
|
// once we're done it's we read from the semaphoreChan which
|
||||||
|
// has the effect of removing one from the limit and allowing
|
||||||
|
// another goroutine to start
|
||||||
|
<-semaphoreChan
|
||||||
|
}(chck)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make a slice to hold the results we're expecting
|
||||||
|
var results []result
|
||||||
|
|
||||||
|
// start listening for any results over the resultsChan
|
||||||
|
// once we get a result append it to the result slice
|
||||||
|
for {
|
||||||
|
result := <-resultsChan
|
||||||
|
results = append(results, *result)
|
||||||
|
|
||||||
|
// if we've reached the expected amount of urls then stop
|
||||||
|
if len(results) == len(Checks) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret []check
|
||||||
|
for i := range results {
|
||||||
|
ch := m[results[i].id]
|
||||||
|
if results[i].status == 200 {
|
||||||
|
ch.Status = "OK"
|
||||||
|
ret = append(ret,*ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now we're done we return the results
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// we'll use the init function to set up the benchmark
|
||||||
|
// by making a slice of 100 URLs to send requets to
|
||||||
|
var urls []string
|
||||||
|
var checks []check
|
||||||
|
var m = make(map[int]*check)
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
bytes, _ := ioutil.ReadAll(os.Stdin)
|
||||||
|
json.Unmarshal(bytes , &checks)
|
||||||
|
for i := range checks {
|
||||||
|
m[checks[i].Id] = &checks[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the main function sets up an anonymous benchmark func
|
||||||
|
// that will time how long it takes to get all the URLs
|
||||||
|
// at the specified concurrency level
|
||||||
|
//
|
||||||
|
// and you should see something like the following printed
|
||||||
|
// depending on how fast your computer and internet is
|
||||||
|
//
|
||||||
|
// 5 bounded parallel requests: 100/100 in 5.533223255
|
||||||
|
// 10 bounded parallel requests: 100/100 in 2.5115351219
|
||||||
|
// 25 bounded parallel requests: 100/100 in 1.189462884
|
||||||
|
// 50 bounded parallel requests: 100/100 in 1.17430002
|
||||||
|
// 75 bounded parallel requests: 100/100 in 1.001383863
|
||||||
|
// 100 bounded parallel requests: 100/100 in 1.3769354
|
||||||
|
func main() {
|
||||||
|
//startTime := time.Now()
|
||||||
|
results := boundedParallelGet(checks, 100)
|
||||||
|
//seconds := time.Since(startTime).Seconds()
|
||||||
|
//tmplate := "requests: %d/%d in %v"
|
||||||
|
|
||||||
|
// fmt.Printf(tmplate, len(results), len(checks), seconds)
|
||||||
|
|
||||||
|
val,_ := json.MarshalIndent(results, "", " ")
|
||||||
|
fmt.Print(string(val))
|
||||||
|
}
|
||||||
|
|
||||||
118
inc/remote_status.php
Normal file
118
inc/remote_status.php
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
FusionInventory
|
||||||
|
Copyright (C) 2010-2011 by the FusionInventory Development Team.
|
||||||
|
|
||||||
|
http://www.fusioninventory.org/ http://forge.fusioninventory.org/
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
This file is part of FusionInventory project.
|
||||||
|
|
||||||
|
FusionInventory is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
FusionInventory is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with FusionInventory. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@package FusionInventory
|
||||||
|
@author Walid Nouh
|
||||||
|
@co-author
|
||||||
|
@copyright Copyright (c) 2010-2011 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 2010
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
include ("../../../inc/includes.php");
|
||||||
|
|
||||||
|
declare(ticks=1);
|
||||||
|
|
||||||
|
|
||||||
|
global $DB,$agents;
|
||||||
|
|
||||||
|
$check_arr = [];
|
||||||
|
$pfInventoryComputerComputer = new PluginFusioninventoryInventoryComputerComputer();
|
||||||
|
foreach (getAllDataFromTable(PluginFusioninventoryAgent::getTable()) as $a) {
|
||||||
|
|
||||||
|
$check = [];
|
||||||
|
$a_computerextend = $pfInventoryComputerComputer->hasAutomaticInventory($a["computers_id"]);
|
||||||
|
|
||||||
|
$check["url"] = "http://".$a_computerextend["remote_addr"].":62354/status";
|
||||||
|
$check["id"] = $a["id"];
|
||||||
|
$check["computers_id"] = $a["computers_id"];
|
||||||
|
$check["status"] = "unknown";
|
||||||
|
|
||||||
|
$check_arr[] = $check;
|
||||||
|
//print_r($agent->getAgentStatusURLs());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$descriptorspec = array(
|
||||||
|
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
|
||||||
|
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
|
||||||
|
2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
|
||||||
|
);
|
||||||
|
|
||||||
|
$cwd = '/tmp';
|
||||||
|
$env = array('debug' => 'false');
|
||||||
|
|
||||||
|
$process = proc_open(__DIR__.'/bench_urls', $descriptorspec, $pipes, $cwd, $env);
|
||||||
|
|
||||||
|
if (is_resource($process)) {
|
||||||
|
// $pipes now looks like this:
|
||||||
|
// 0 => writeable handle connected to child stdin
|
||||||
|
// 1 => readable handle connected to child stdout
|
||||||
|
// Any error output will be appended to /tmp/error-output.txt
|
||||||
|
|
||||||
|
fwrite($pipes[0], json_encode($check_arr));
|
||||||
|
fclose($pipes[0]);
|
||||||
|
|
||||||
|
$checked = json_decode(stream_get_contents($pipes[1]));
|
||||||
|
fclose($pipes[1]);
|
||||||
|
|
||||||
|
// It is important that you close any pipes before calling
|
||||||
|
// proc_close in order to avoid a deadlock
|
||||||
|
$return_value = proc_close($process);
|
||||||
|
|
||||||
|
echo "command returned $return_value\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$DB->update("glpi_computers", [
|
||||||
|
'states_id' => NULL ] ,
|
||||||
|
[ '1' => '1' ]
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($checked as $s) {
|
||||||
|
echo $s->computers_id." ";
|
||||||
|
|
||||||
|
$comp = new Computer();
|
||||||
|
$comp->getFromDB($s->computers_id);
|
||||||
|
$comp->fields["states_id"] = 2;
|
||||||
|
$DB->update("glpi_computers", [
|
||||||
|
'states_id' => $comp->fields["states_id"] ],
|
||||||
|
[ 'id' => $s->computers_id ]
|
||||||
|
);
|
||||||
|
echo $comp->fields["contact"]."\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// print_r($a_computerextend);
|
||||||
|
exit(0);
|
||||||
@@ -6,8 +6,7 @@ if (!defined('GLPI_ROOT')) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PluginRemoteSupportComputer extends CommonDBTM {
|
class PluginRemotesupportRemotesupport extends CommonDBTM {
|
||||||
|
|
||||||
static function showInfo($item) {
|
static function showInfo($item) {
|
||||||
|
|
||||||
$fi_path = Plugin::getWebDir('fusioninventory');
|
$fi_path = Plugin::getWebDir('fusioninventory');
|
||||||
@@ -28,7 +27,7 @@ class PluginRemoteSupportComputer extends CommonDBTM {
|
|||||||
echo '<tr class="tab_bg_1">';
|
echo '<tr class="tab_bg_1">';
|
||||||
echo '<td>';
|
echo '<td>';
|
||||||
|
|
||||||
$url .= "<a target=\"_blank\" href=\"https://" . $_SERVER['SERVER_ADDR']. "/vnc.html?path=vnc%2F". $a_computerextend['remote_addr'] ."&autoconnect=true&resize=scale&reconnect=true&show_dot=true\"><li class=\"document\"><i class=\"fa fa-laptop-medical\"></i>" . $a_computerextend['remote_addr'] . "</li></a>";
|
$url = "<a target=\"_blank\" href=\"https://" . $_SERVER['SERVER_ADDR']. "/vnc.html?path=vnc%2F". $a_computerextend['remote_addr'] ."&autoconnect=true&resize=scale&reconnect=true&show_dot=true\"><li class=\"document\"><i class=\"fa fa-laptop-medical\"></i>" . $a_computerextend['remote_addr'] . "</li></a>";
|
||||||
|
|
||||||
if ($url != ""){
|
if ($url != ""){
|
||||||
echo "<div><ul class=\"timeline_choices\"><h2>VNC connect : </h2>";
|
echo "<div><ul class=\"timeline_choices\"><h2>VNC connect : </h2>";
|
||||||
@@ -40,4 +39,51 @@ class PluginRemoteSupportComputer extends CommonDBTM {
|
|||||||
echo '</table>';
|
echo '</table>';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static function cronRemotesupport($task) {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
Toolbox::logInFile("remotsupport","Starting search of agents\n");
|
||||||
|
|
||||||
|
$agents = [];
|
||||||
|
$data_set = [];
|
||||||
|
|
||||||
|
foreach (getAllDataFromTable(PluginFusioninventoryAgent::getTable()) as $a) {
|
||||||
|
|
||||||
|
$data_set[] = $a["id"];
|
||||||
|
$agents[$a["id"]] = $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($data_set as $id) {
|
||||||
|
$agent = new PluginFusioninventoryAgent;
|
||||||
|
$agent->getFromDB((int)$id);
|
||||||
|
$st = $agent->getStatus();
|
||||||
|
|
||||||
|
if ($st["message"] != "noanswer")
|
||||||
|
Toolbox::logInFile("remotsupport",print_r($agents[$id],true));
|
||||||
|
|
||||||
|
$comp = new Computer();
|
||||||
|
$comp->getFromDB($agents[$id]["computers_id"]);
|
||||||
|
if ($st["message"] == "noanswer")
|
||||||
|
$comp->fields["states_id"] = NULL;
|
||||||
|
else
|
||||||
|
$comp->fields["states_id"] = 2;
|
||||||
|
$DB->update("glpi_computers", [
|
||||||
|
'states_id' => $comp->fields["states_id"] ],
|
||||||
|
[ 'id' => $agents[$id]["computers_id"] ]
|
||||||
|
);
|
||||||
|
$comp->fields["contact"]."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function cronInfo($name) {
|
||||||
|
return [
|
||||||
|
'description' => "Agent search remotesupport"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,12 +34,16 @@ function plugin_init_remotesupport()
|
|||||||
if (Plugin::isPluginActive('remotesupport')) {
|
if (Plugin::isPluginActive('remotesupport')) {
|
||||||
|
|
||||||
// $PLUGIN_HOOKS['add_javascript']['remotesupport'][] = 'js/support.js';
|
// $PLUGIN_HOOKS['add_javascript']['remotesupport'][] = 'js/support.js';
|
||||||
include(PLUGIN_REMOTESUPPORT_DIR . "/inc/remotesupport.class.php");
|
|
||||||
|
|
||||||
$PLUGIN_HOOKS['autoinventory_information']['remotesupport'] = array(
|
$PLUGIN_HOOKS['autoinventory_information']['remotesupport'] = array(
|
||||||
'Computer' => array('PluginRemoteSupportComputer', 'showInfo')
|
'Computer' => array('PluginRemotesupportRemotesupport', 'showInfo')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CronTask::Register('PluginRemotesupportRemotesupport', 'remotesupport', 300,
|
||||||
|
['mode'=>2, 'allowmode'=>3, 'logs_lifetime'=>30,
|
||||||
|
'comment'=> 'Remotesupport crontab search agents']);
|
||||||
|
|
||||||
|
|
||||||
// Add Config Page
|
// Add Config Page
|
||||||
// Plugin::registerClass('PluginRemotesupportConfig', ['addtabon' => 'Config']);
|
// Plugin::registerClass('PluginRemotesupportConfig', ['addtabon' => 'Config']);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user