Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / other / boinc_projs @ 10eb3992

Historique | Voir | Annoter | Télécharger (9,34 ko)

1
#!/usr/bin/perl -w
2
#
3
# boinc_projs - Munin plugin to monitor actively running BOINC projects
4
#
5
# Run 'perldoc boinc_projs' for full man page
6
#
7
# Author:  Palo M. <palo.gm@gmail.com>
8
# License: GPLv3 <http://www.gnu.org/licenses/gpl-3.0.txt>
9
#
10
#
11
# Parameters supported:
12
# 	config
13
#
14
#
15
# Configurable variables
16
#       boinccmd   - command-line control program (default: boinccmd)
17
# 	host       - Host to query (default: none = use local host)
18
#       port       - GUI RPC port (default: none = use BOINC-default)
19
#       boincdir   - Directory containing appropriate password file
20
#                    gui_rpc_auth.cfg (default: none)
21
#       password   - Password for BOINC (default: none) !!! UNSAFE !!!
22
#
23
#
24
# $Log$
25
#
26
# Revision 1.0  2009/09/13  Palo M.
27
#   Add documentation and license information
28
#   Ready to publish on Munin Exchange
29
# Revision 0.9  2009/09/13  Palo M.
30
#   Add possibility to read password from file
31
# Revision 0.8  2009/09/12  Palo M.
32
#   Update default binary name: boinc_cmd -> boinccmd
33
# Revision 0.7  2008/08/29  Palo M.
34
#   Creation - Attempt to port functionality from C++ code
35
#
36
# (Revisions 0.1 - 0.6) were done in C++
37
#
38
#
39
#
40
# Magic markers:
41
#%# family=contrib
42

    
43
use strict;
44

    
45

    
46
#########################################################################
47
# 1. Parse configuration variables
48
#
49
my $BOINCCMD = exists $ENV{'boinccmd'} ? $ENV{'boinccmd'} : "boinccmd";
50
my $HOST = exists $ENV{'host'} ? $ENV{'host'} : undef;
51
my $PORT = exists $ENV{'port'} ? $ENV{'port'} : undef;
52
my $PASSWORD = exists $ENV{'password'} ? $ENV{'password'} : undef;
53
my $BOINCDIR = exists $ENV{'boincdir'} ? $ENV{'boincdir'} : undef;
54

    
55
#########################################################################
56
# 2. Basic executable
57
#
58
if (defined $HOST) {
59
  $BOINCCMD .= " --host $HOST";
60
  if (defined $PORT) {
61
    $BOINCCMD .= ":$PORT";
62
  }
63
}
64
if (defined $PASSWORD) {
65
  $BOINCCMD .= " --passwd $PASSWORD";
66
}
67
if (defined $BOINCDIR) {
68
  chdir $BOINCDIR;
69
}
70

    
71
#########################################################################
72
# 3. Fetch all needed data from BOINC-client with single call
73
#
74
my $prj_status = "";
75
my $results = "";
76

    
77
my $simpleGuiInfo = `$BOINCCMD --get_simple_gui_info 2>/dev/null`;
78
if ($simpleGuiInfo ne "") {
79
  # Some data were retrieved, so let's split them
80
  my @sections;
81
  my @section1;
82
  @sections = split /=+ Projects =+\n/, $simpleGuiInfo;
83
  @section1 = split /=+ [A-z]+ =+\n/, $sections[1];
84
  $prj_status = $section1[0];
85

    
86
  @sections = split /=+ Results =+\n/, $simpleGuiInfo;
87
  @section1 = split /=+ [A-z]+ =+\n/, $sections[1];
88
  $results = $section1[0];
89
}
90

    
91
if ($prj_status eq "") { exit -1; }
92

    
93
# 3.a) Split --get_project_status into projects
94
my @prjInfos = split /\d+\) -+\n/, $prj_status;
95
shift @prjInfos; # Throw out first empty line
96

    
97
# 3.b) Fetch project infos
98
my %projects;    # Store projects infos here
99
my @projects;    # Just to keep the order of projects
100
for my $prj_info (@prjInfos) {
101
  my @lines = split /\n/, $prj_info;
102
  my $line1 = shift @lines; # get project name
103
  if ($line1 !~ /^\s+name: /) { die "Unexpected output from boinccmd"; }
104
  $line1 =~ s/^\s+name: //; # Make just the project name itself
105
  my $line2 = shift @lines; # get project URL
106
  if ($line2 !~ /^\s+master URL: /) { die "Unexpected output from boinccmd"; }
107
  $line2 =~ s/^\s+master URL: //; # Make just the URL itself
108
  my $prj_url = $line2;
109
  my $prj_name = $line1;
110
  $line1 =~ s/\@/at/g;
111
  $line1 =~ s/[^0-9A-z]/_/g;
112
  my $prj_var = "prj_" . $line1;
113
  push @projects,$prj_url;
114
  $projects{$prj_url} = {
115
			 prj_name    => $prj_name,
116
			 prj_var     => $prj_var,
117
			 prj_running => 0
118
			};
119
}
120

    
121

    
122
#########################################################################
123
# 4. Parse results
124
#
125
# 4.a) Split --get_results
126
my @rsltInfos = split /\d+\) -+\n/, $results;
127
shift @rsltInfos; # Throw out first empty line
128

    
129
# 4.b) Parse results, find those which are running
130
for my $rslt_info (@rsltInfos) {
131
  my @lines = split /\n/, $rslt_info;
132
  my @url = grep /^\s+project URL: /,@lines;
133
  my $url = $url[0];
134
  $url =~ s/^\s+project URL: //; # Make just the URL itself
135
  my @schedstat = grep /^\s+scheduler state: /,@lines;
136
  my $schedstat = $schedstat[0];
137
  $schedstat =~ s/^\s+scheduler state: //;
138
  my @state = grep /^\s+state: /,@lines;
139
  my $state = $state[0];
140
  $state =~ s/^\s+state: //;
141
  my @acttask = grep /^\s+active_task_state: /,@lines;
142
  my $acttask = $acttask[0];
143
  $acttask =~ s/^\s+active_task_state: //;
144
  if ( ($schedstat eq "2") && ($state eq "2") && ($acttask eq "1") ) {
145
    # This is running task
146
    $projects{$url}->{prj_running} += 1;
147
  }
148
}
149

    
150

    
151
#########################################################################
152
# 5. Display output
153
#
154

    
155
if ( (defined $ARGV[0]) && ($ARGV[0] eq "config") ) {
156
#
157
# 5.a) Display config
158
#
159

    
160
  if (defined $HOST) {
161
    print "host_name $HOST\n";
162
  }
163

    
164
  print "graph_title Running BOINC processes\n";
165
  print "graph_category BOINC\n";
166
  print "graph_args --base 1000 -l 0\n";
167
  print "graph_vlabel BOINC applications\n";
168

    
169
  # First project is AREA, next are STACK
170
  # Not nice, but fast:
171
  my $prj1 = shift @projects;
172
  print "$projects{$prj1}->{prj_var}.label $projects{$prj1}->{prj_name}\n";
173
  print "$projects{$prj1}->{prj_var}.draw AREA\n";
174
  print "$projects{$prj1}->{prj_var}.type GAUGE\n";
175

    
176
  for my $prjN (@projects) {
177
    print "$projects{$prjN}->{prj_var}.label $projects{$prjN}->{prj_name}\n";
178
    print "$projects{$prjN}->{prj_var}.draw STACK\n";
179
    print "$projects{$prjN}->{prj_var}.type GAUGE\n";
180
  }
181

    
182
  exit 0;
183
}
184

    
185
#
186
# 5.b) Display running state of projects
187
#
188

    
189
for my $prjN (@projects) {
190
  print "$projects{$prjN}->{prj_var}.value $projects{$prjN}->{prj_running}\n";
191
}
192

    
193
exit 0;
194

    
195

    
196
#########################################################################
197
# perldoc section
198

    
199
=head1 NAME
200

    
201
boinc_projs - Munin plugin to monitor actively running BOINC projects.
202

    
203
=head1 APPLICABLE SYSTEMS
204

    
205
Linux machines running BOINC and munin-node
206

    
207
- or -
208

    
209
Linux servers (running munin-node) used to collect data from other systems 
210
which are running BOINC, but not running munin-node (e.g. non-Linux systems)
211

    
212
=head1 CONFIGURATION
213

    
214
Following configuration variables are supported:
215

    
216
=over 12
217

    
218
=item B<boinccmd>
219

    
220
command-line control program (default: boinccmd)
221

    
222
=item B<host>
223

    
224
Host to query (default: none)
225

    
226
=item B<port>
227

    
228
GUI RPC port (default: none = use BOINC-default)
229

    
230
=item B<boincdir>
231

    
232
Directory containing appropriate file gui_rpc_auth.cfg (default: none)
233

    
234
=item B<password>
235

    
236
Password for BOINC (default: none) 
237

    
238
=back
239

    
240
=head2 B<Security Consideration:>
241

    
242
Using of variable B<password> poses a security risk. Even if the Munin 
243
configuration file for this plugin containing BOINC-password is properly 
244
protected, the password is exposed as environment variable and finally passed 
245
to boinccmd as a parameter. It is therefore possible for local users of the 
246
machine running this plugin to eavesdrop the BOINC password. 
247

    
248
Using of variable password is therefore strongly discouraged and is left here 
249
as a legacy option and for testing purposes.
250

    
251
It should be always possible to use B<boincdir> variable instead - in such case 
252
the file gui_rpc_auth.cfg is read by boinccmd binary directly. 
253
If this plugin is used to fetch data from remote system, the gui_rpc_auth.cfg 
254
can be copied to special directory in a secure way (e.g. via scp) and properly 
255
protected by file permissions.
256

    
257
=head1 INTERPRETATION
258

    
259
This plugin shows the number of currently running BOINC tasks on the machine. 
260
If machine is attached to several BOINC projects, data for all these projects 
261
are displayed.
262

    
263
=head1 EXAMPLES
264

    
265
=head2 Local BOINC Example
266

    
267
BOINC is running on local machine. The BOINC binaries are installed in 
268
F</opt/boinc/custom-6.10.1/>, the BOINC is running in directory
269
F</usr/local/boinc/> under username boinc, group boinc and the password is used 
270
to protect access to BOINC:
271

    
272
  [boinc_*]
273
  group boinc
274
  env.boinccmd /opt/boinc/custom-6.10.1/boinccmd
275
  env.boincdir /usr/local/boinc
276

    
277
=head2 Remote BOINC Example
278

    
279
BOINC is running on 2 remote machines C<foo> and C<bar>. 
280
On the local machine the binary of command-line interface is installed in 
281
directory F</usr/local/bin/>.
282
The BOINC password used on the remote machine C<foo> is stored in file 
283
F</etc/munin/boinc/foo/gui_rpc_auth.cfg>.
284
The BOINC password used on the remote machine C<bar> is stored in file 
285
F</etc/munin/boinc/bar/gui_rpc_auth.cfg>.
286
These files are owned and readable by root, readable by group munin and not 
287
readable by others. 
288
There are 2 symbolic links to this plugin created in the munin plugins 
289
directory (usually F</etc/munin/plugins/>): F<snmp_foo_boincprojs> and 
290
F<snmp_bar_boincprojs>
291

    
292
  [snmp_foo_boinc*]
293
  group munin
294
  env.boinccmd /usr/local/bin/boinccmd
295
  env.host foo
296
  env.boincdir /etc/munin/boinc/foo
297

    
298
  [snmp_bar_boinc*]
299
  group munin
300
  env.boinccmd /usr/local/bin/boinccmd
301
  env.host bar
302
  env.boincdir /etc/munin/boinc/bar
303

    
304
This way the plugin can be used by Munin the same way as the Munin plugins 
305
utilizng SNMP (although this plugin itself does not use SNMP).
306

    
307
=head1 BUGS
308

    
309
There is no C<autoconf> capability at the moment. This is due to the fact, that 
310
BOINC installations may vary over different systems, sometimes using default 
311
directory from distribution (e.g. F</var/lib/boinc/> in Debian or Ubuntu), but 
312
often running in user directories or in other separate directories.
313
Also the user-ID under which BOINC runs often differs. 
314
Under these circumstances the C<autoconf> would be either lame or too 
315
complicated.
316

    
317
=head1 AUTHOR
318

    
319
Palo M. <palo.gm@gmail.com>
320

    
321
=head1 LICENSE
322

    
323
GPLv3
324

    
325
=cut
326

    
327
# vim:syntax=perl