2007-09-09 11:24:47 +02:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
#
|
|
|
|
# Plugin for monitoring boinc processes
|
|
|
|
#
|
|
|
|
# Parameters:
|
|
|
|
#
|
|
|
|
# password -- The password for RPC authentication
|
2018-08-02 02:03:42 +02:00
|
|
|
# (default: boinc_cmd will look for a file
|
2007-09-09 11:24:47 +02:00
|
|
|
# 'gui_rpc_auth.cfg' and use the password in it)
|
|
|
|
# host -- the host to connect to (default: localhost)
|
|
|
|
# port -- optional (default: 31416)
|
|
|
|
#
|
2018-08-02 02:03:42 +02:00
|
|
|
# This plugin can monitor boinc processes running on local/remote machines.
|
2007-09-09 11:24:47 +02:00
|
|
|
# You can see the progress on various projects.
|
|
|
|
#
|
|
|
|
# Author: Petr Ruzicka <petr.ruzicka@gmail.com>
|
|
|
|
# GPL v3
|
|
|
|
#
|
|
|
|
#%# family=auto
|
|
|
|
#%# capabilities=autoconf
|
|
|
|
|
|
|
|
use IO::Socket;
|
|
|
|
use Digest::MD5 qw(md5_hex);
|
|
|
|
|
|
|
|
|
|
|
|
if ($ENV{'password_path'}) {
|
|
|
|
$password = $ENV{'password_path'};
|
|
|
|
} else {
|
|
|
|
$password = $ENV{'password'} || `cat /var/lib/boinc/gui_rpc_auth.cfg 2>/dev/null`;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $host = $ENV{'host'} || '127.0.0.1';
|
|
|
|
my $port = $ENV{'port'} || '31416';
|
|
|
|
|
|
|
|
|
|
|
|
sub autoconf {
|
|
|
|
my $client = new IO::Socket::INET (
|
|
|
|
PeerAddr => $host,
|
|
|
|
PeerPort => $port,
|
|
|
|
Proto => 'tcp' );
|
|
|
|
|
|
|
|
if ($client) {
|
|
|
|
print $client "<boinc_gui_rpc_request><auth1/></boinc_gui_rpc_request>\003";
|
|
|
|
|
|
|
|
{
|
|
|
|
local $/ = "\003";
|
|
|
|
$reply = <$client>;
|
|
|
|
}
|
|
|
|
|
|
|
|
$reply =~ /<nonce>(.*)<\/nonce>/;
|
|
|
|
$hash = md5_hex($1, $password);
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
print $client "<boinc_gui_rpc_request><auth2><nonce_hash>$hash</nonce_hash></auth2></boinc_gui_rpc_request>\003";
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
{
|
|
|
|
local $/ = "\003";
|
|
|
|
$reply = <$client>;
|
|
|
|
}
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
if ($reply =~ /<authorized\/>/) {
|
|
|
|
print "yes\n";
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
print "no\n";
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub config {
|
|
|
|
my $client = IO::Socket::INET->new ( PeerAddr => $host,
|
|
|
|
PeerPort => $port,
|
|
|
|
Proto => 'tcp' )
|
2018-08-02 02:03:42 +02:00
|
|
|
or die "Can't bind : $@\n";
|
2007-09-09 11:24:47 +02:00
|
|
|
|
|
|
|
print $client "<boinc_gui_rpc_request><auth1/></boinc_gui_rpc_request>\003";
|
|
|
|
|
2018-08-02 02:03:42 +02:00
|
|
|
{
|
2007-09-09 11:24:47 +02:00
|
|
|
local $/ = "\003";
|
|
|
|
$reply = <$client>;
|
|
|
|
}
|
|
|
|
|
|
|
|
$reply =~ /<nonce>(.*)<\/nonce>/;
|
|
|
|
my $hash = md5_hex($1, $password);
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
print $client "<boinc_gui_rpc_request><auth2><nonce_hash>$hash</nonce_hash></auth2></boinc_gui_rpc_request>\003";
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
{
|
|
|
|
local $/ = "\003";
|
|
|
|
$reply = <$client>;
|
|
|
|
}
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
if ($reply !~ /<authorized\/>/) {
|
|
|
|
die "Wrong password: $_";
|
|
|
|
}
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
print $client "<boinc_gui_rpc_request><get_state></boinc_gui_rpc_request>";
|
|
|
|
|
|
|
|
while (chomp($reply = <$client>) && ($reply ne "</boinc_gui_rpc_reply>")) {
|
|
|
|
if ($reply =~ /<domain_name>(.*)<\/domain_name>/) {
|
|
|
|
print "graph_title BOINC task progress [$1]\n";
|
2017-02-22 04:04:04 +01:00
|
|
|
print "graph_category htc\n";
|
2007-09-09 11:24:47 +02:00
|
|
|
print "graph_args -l 0\n";
|
|
|
|
print "graph_vlabel %\n";
|
2018-08-02 02:03:42 +02:00
|
|
|
}
|
2007-09-09 11:24:47 +02:00
|
|
|
if ($reply =~ /<project_name>(.*)<\/project_name>/) {
|
|
|
|
my $boinc_munin_name=$1;
|
|
|
|
$boinc_munin_name =~ /(\w+).*/;
|
|
|
|
print "$1.label $boinc_munin_name\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close ($client);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub report {
|
|
|
|
my $client = IO::Socket::INET->new ( PeerAddr => $host,
|
|
|
|
PeerPort => $port,
|
|
|
|
Proto => 'tcp' )
|
2018-08-02 02:03:42 +02:00
|
|
|
or die "Can't bind : $@\n";
|
2007-09-09 11:24:47 +02:00
|
|
|
|
|
|
|
print $client "<boinc_gui_rpc_request><auth1/></boinc_gui_rpc_request>\003";
|
|
|
|
|
2018-08-02 02:03:42 +02:00
|
|
|
{
|
2007-09-09 11:24:47 +02:00
|
|
|
local $/ = "\003";
|
|
|
|
$reply = <$client>;
|
|
|
|
}
|
|
|
|
|
|
|
|
$reply =~ /<nonce>(.*)<\/nonce>/;
|
|
|
|
my $hash = md5_hex($1, $password);
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
print $client "<boinc_gui_rpc_request><auth2><nonce_hash>$hash</nonce_hash></auth2></boinc_gui_rpc_request>\003";
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
{
|
|
|
|
local $/ = "\003";
|
|
|
|
$reply = <$client>;
|
|
|
|
}
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
if ($reply !~ /<authorized\/>/) {
|
|
|
|
die "Wrong password: $_";
|
|
|
|
}
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
print $client "<boinc_gui_rpc_request><get_state></boinc_gui_rpc_request>";
|
2018-08-02 02:03:42 +02:00
|
|
|
|
2007-09-09 11:24:47 +02:00
|
|
|
while (chomp($reply = <$client>) && ($reply ne "</boinc_gui_rpc_reply>")) {
|
|
|
|
if ($reply =~ /<project_name>(\w+).*<\/project_name>/) {
|
|
|
|
$project = $1;
|
|
|
|
$fraction_done=0;
|
|
|
|
while (chomp($reply = <$client>) && ($reply ne "<project>") && ($reply ne "</client_state>")) {
|
|
|
|
if ($reply =~ /\s*<active_task_state>1<\/active_task_state>/) {
|
|
|
|
while (chomp($reply = <$client>) && ($reply ne "</active_task>")) {
|
|
|
|
if ($reply =~ /<fraction_done>(.*)<\/fraction_done>/) {
|
|
|
|
$fraction_done+=int($1*100 + .5 * ($1*100 <=> 0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
print "$project.value $fraction_done\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close ($client);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined $ARGV[0]) {
|
|
|
|
my $arg = $ARGV[0];
|
|
|
|
my %funcs = ( config => \&config,
|
|
|
|
autoconf => \&autoconf,
|
|
|
|
report => \&report
|
|
|
|
);
|
|
|
|
|
|
|
|
if (exists $funcs{$arg}) {
|
|
|
|
$funcs{$arg}->();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$funcs{"report"}->();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
report();
|
|
|
|
}
|