#!/usr/bin/perl -w # # Plugin for monitoring boinc processes # # Parameters: # # password -- The password for RPC authentication # (default: boinc_cmd will look for a file # 'gui_rpc_auth.cfg' and use the password in it) # host -- the host to connect to (default: localhost) # port -- optional (default: 31416) # # This plugin can monitor boinc processes running on local/remote machines. # You can see the progress on various projects. # # Author: Petr Ruzicka # 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 "\003"; { local $/ = "\003"; $reply = <$client>; } $reply =~ /(.*)<\/nonce>/; $hash = md5_hex($1, $password); print $client "$hash\003"; { local $/ = "\003"; $reply = <$client>; } if ($reply =~ //) { print "yes\n"; exit 0; } } print "no\n"; exit 1; } sub config { my $client = IO::Socket::INET->new ( PeerAddr => $host, PeerPort => $port, Proto => 'tcp' ) or die "Can't bind : $@\n"; print $client "\003"; { local $/ = "\003"; $reply = <$client>; } $reply =~ /(.*)<\/nonce>/; my $hash = md5_hex($1, $password); print $client "$hash\003"; { local $/ = "\003"; $reply = <$client>; } if ($reply !~ //) { die "Wrong password: $_"; } print $client ""; while (chomp($reply = <$client>) && ($reply ne "")) { if ($reply =~ /(.*)<\/domain_name>/) { print "graph_title BOINC task progress [$1]\n"; print "graph_category boinc\n"; print "graph_args -l 0\n"; print "graph_vlabel %\n"; } if ($reply =~ /(.*)<\/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' ) or die "Can't bind : $@\n"; print $client "\003"; { local $/ = "\003"; $reply = <$client>; } $reply =~ /(.*)<\/nonce>/; my $hash = md5_hex($1, $password); print $client "$hash\003"; { local $/ = "\003"; $reply = <$client>; } if ($reply !~ //) { die "Wrong password: $_"; } print $client ""; while (chomp($reply = <$client>) && ($reply ne "")) { if ($reply =~ /(\w+).*<\/project_name>/) { $project = $1; $fraction_done=0; while (chomp($reply = <$client>) && ($reply ne "") && ($reply ne "")) { if ($reply =~ /\s*1<\/active_task_state>/) { while (chomp($reply = <$client>) && ($reply ne "")) { if ($reply =~ /(.*)<\/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(); }