|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /proc/self/root/usr/sbin/ |
Upload File : |
#!/usr/bin/perl -w
#
# Copyright (C) 2004 Jimmy Olsen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Program to suggest configurations and configuration changes.
#
# $Log$
# Revision 1.11.2.1 2005/03/09 21:49:57 jimmyo
# munin-node-configure now properly respect user plugins.
#
# Revision 1.11 2004/12/10 10:40:12 jimmyo
# Fix bug with underscore in wildcard plugins.
#
# Revision 1.10 2004/11/16 20:00:42 jimmyo
# License cleanups.
#
# Revision 1.9 2004/09/07 19:33:32 jimmyo
# Documented the SNMP options a bit better.
#
# Revision 1.8 2004/09/05 12:00:18 jimmyo
# Set family and capabilities.
#
# Revision 1.7 2004/09/03 23:25:16 jimmyo
# Brushed up the SNMP probe functionality.
#
# Revision 1.6 2004/09/03 22:59:03 jimmyo
# Support comma-formatted snmp-options.
#
# Revision 1.5 2004/09/03 22:56:51 jimmyo
# Added support for SNMP probing.
#
# Revision 1.4 2004/01/29 19:25:52 jimmyo
# Fixed bad debug output (forgotten linebreaks) in munin-node-configure (SF#882385).
#
# Revision 1.3 2004/01/29 17:36:19 jimmyo
# Updated copyright information
#
# Revision 1.2 2004/01/15 15:20:00 jimmyo
# Making things workable after name change. Upping for test verwion.
#
# Revision 1.1 2004/01/02 18:50:00 jimmyo
# Renamed occurrances of lrrd -> munin
#
# Revision 1.1.1.1 2004/01/02 15:18:06 jimmyo
# Import of LRRD CVS tree after renaming to Munin
#
# Revision 1.11 2003/12/18 16:46:59 jimmyo
# now prints the reason for suggesting to not use a plugin, as long as the plugins gives one.
#
# Revision 1.10 2003/12/17 21:29:26 jimmyo
# Don\'t try to change uid/gid if not running as root. (Deb#224300)
#
# Revision 1.9 2003/11/10 22:05:42 toreanderson
# bugfux
#
# Revision 1.8 2003/11/10 17:52:33 jimmyo
# Small briainer-typo
#
# Revision 1.7 2003/11/10 17:32:18 jimmyo
# Check what to do with new plugins when upgrading.
#
# Revision 1.6 2003/11/07 17:43:16 jimmyo
# Cleanups and log entries
#
#
$| = 1; # Flush after every write to stdout
use strict;
use Getopt::Long;
my $version = "1.2.5";
my $config = "/etc/munin/munin-node.conf";
my $servicedir = "/etc/munin/plugins";
my $libdir = "/usr/share/munin/plugins";
my $bindir = "/usr/sbin";
my $installed = undef;
my $plugins = undef;
my $debug = 0;
my $suggest = 0;
my $shell = 0;
my @afamilies = ("auto", "manual", "contrib");
my @dfamilies = ("auto");
my @families = ();
my @snmp = ();
my $snmpver = undef;
my $snmpcomm = undef;
my $removes = 0;
my $do_usage = 0;
my $do_error = 0;
my $do_version = 0;
my $newer = undef;
$do_error = 1 unless GetOptions (
"help" => \$do_usage,
"shell!" => \$shell,
"debug!" => \$debug,
"suggest!" => \$suggest,
"config=s" => \$config,
"servicedir=s" => \$servicedir,
"remove-also!" => \$removes,
"libdir=s" => \$libdir,
"families=s" => \@families,
"version!" => \$do_version,
"snmp=s" => \@snmp,
"snmpversion=s" => \$snmpver,
"snmpcommunity=s" => \$snmpcomm,
"newer=s" => \$newer
);
if ($do_error or $do_usage)
{
print "Usage: $0 [options]
Options:
--help View this help page
--version Show version information
--debug View debug information (very verbose)
--config <file> Override configuration file
[$config]
--servicedir <dir> Override plugin dir [$servicedir]
--libdir <dir> Override plugin lib [$libdir]
--families <family,...> Override families (", join(',',@afamilies),") [",join(',',@dfamilies),"]
--suggest Show suggestions instead of status
--shell Show shell commands (implies --suggest)
--remove-also Also show rm-commands when doing --shell
--newer <version> Only show suggestions related to plugins newer
than version <version>. [0.0.0]
--snmp <host|cidr> Do SNMP probing on the host or CIDR network.
--snmpversion <ver> Set SNMP version (1, 2c or 3) [2c]
--snmpcommunity <comm> Set SNMP community [public]
";
exit ($do_error); # 1 if error, 0 if --help
}
if ($do_version)
{
print "munin-node-configure (munin-node) version $version.\n";
print "Written by Jimmy Olsen\n";
print "\n";
print "Copyright (C) 2003-2004 Jimmy Olsen\n";
print "This is free software released under the GNU Public License. There is NO\n";
print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
exit 0;
}
if (defined $newer and (!$shell or $removes))
{
print "Fatal: --newer only supported along with --shell.\n";
exit 2;
}
if (!@families)
{
if (@snmp)
{
@families = ();
$shell=1;
}
elsif ($suggest or $shell)
{
@families = @dfamilies;
}
else
{
@families = @afamilies;
}
}
@families = split (/,/, join (',', @families));
@snmp = split (/,/, join (',', @snmp));
if (@snmp and !$shell)
{
print "Fatal: --snmp only supported along with --shell.\n";
exit 3;
}
if (@families)
{
$plugins = &get_plugins ($plugins , $libdir);
$installed = &get_installed ($installed, $servicedir);
if (! $shell and $suggest)
{
&normal ("Plugin", "Used", "Suggestions");
&normal ("------", "----", "-----------");
}
elsif (! $shell)
{
&normal ("Plugin", "Used", "Extra information");
&normal ("------", "----", "-----------------");
}
foreach my $plug (sort keys %{$plugins})
{
next unless defined $plugins->{$plug}->{'family'};
next unless (grep (/^$plugins->{$plug}->{'family'}$/, @families));
my $now = (exists $installed->{$plug}?"yes":"no");
my $want = (exists $plugins->{$plug}->{'default'}?$plugins->{$plug}->{'default'}:"no");
my $snow = (exists $installed->{$plug}->{'suggest'}?$installed->{$plug}->{'suggest'}:undef);
my $swant = (exists $plugins->{$plug}->{'suggest'}?$plugins->{$plug}->{'suggest'}:undef);
my $sugg = "";
if ($shell)
{
if ($plug =~ /_$/) # Wildcard plugin...
{
if ($now eq "yes" and $want eq "no")
{
if ($snow and @{$snow})
{
foreach my $wild (sort @{$snow})
{
&link_remove ("$plug$wild");
}
}
}
else
{
if ($snow and @{$snow})
{
foreach my $wild (sort @{$snow})
{
if (! grep (/^$wild$/, @{$swant}))
{
&link_remove ("$plug$wild");
}
}
}
if ($swant and @{$swant})
{
foreach my $wild (sort @{$swant})
{
next if -e "$servicedir/$plug"."_".$wild; # None of our business...
if (! grep (/^$wild$/, @{$snow}))
{
&link_add ($plug, $wild);
}
}
}
}
}
else
{
if ($now eq "yes" and $want eq "no")
{
&link_remove ($plug);
}
elsif ($now eq "no" and $want eq "yes")
{
next if -e "$servicedir/$plug"; # None of our business...
&link_add ($plug);
}
}
}
elsif ($suggest)
{
if ($plug =~ /_$/) # Wildcard plugin...
{
if ($now eq "yes" && $want eq "no" or
$now eq "no" && $want eq "yes" && $swant && @{$swant})
{
$sugg = "$want ";
}
if ($snow and @{$snow})
{
foreach my $wild (sort @{$snow})
{
if (! grep (/^$wild$/, @{$swant}))
{
$sugg .= "-$wild ";
}
}
}
if ($swant and @{$swant})
{
foreach my $wild (sort @{$swant})
{
next if -e "$servicedir/$plug"."_".$wild; # None of our business...
if (! grep (/^$wild$/, @{$snow}))
{
$sugg .= "+$wild ";
}
}
}
&normal ($plug, $now, $sugg);
}
else
{
next if -e "$servicedir/$plug"; # None of our business...
if ($now ne $want)
{
$sugg = $want;
}
elsif (defined $plugins->{$plug}->{'defaultreason'} and
$plugins->{$plug}->{'defaultreason'} =~ /^[^\(]*\((.+)\)\s*$/)
{
$sugg = "[$1]";
}
&normal ($plug, $now, $sugg);
}
}
else
{
if ($plug =~ /_$/) # Wildcard plugin...
{
if ($snow and @{$snow})
{
$sugg = join ' ', @{$snow};
}
&normal ($plug, $now, $sugg);
}
else
{
&normal ($plug, $now, "");
}
}
}
}
if (@snmp and $shell)
{
if (-x "$bindir/munin-node-configure-snmp")
{
if (eval "require Net::SNMP;")
{
my @params;
push (@params, "$bindir/munin-node-configure-snmp");
push (@params, "--snmpversion", $snmpver) if defined $snmpver;
push (@params, "--community", $snmpcomm) if defined $snmpcomm;
push (@params, "--debug") if $debug;
push (@params, @snmp);
exec (@params);
# NOTREACHED
}
else
{
print STDERR "# ERROR: Cannot perform SNMP probe. SNMP operations require the perl module\n";
print STDERR "# Net::SNMP, which is currently not installed (or not in one of the following\n";
print STDERR "# directories: @INC\n";
}
}
else
{
print STDERR "# ERROR: Cannot perform SNMP probe. SNMP operations require the SNMP part\n";
print STDERR "# of Munin to be installed, which is currently not installed, or not in the \n";
print STDERR "# rigt directory: $bindir\n";
}
}
sub link_remove
{
my $plug = shift;
return unless $removes;
return unless (-l "$servicedir/$plug"); # Strange...
print "rm -f $servicedir/$plug\n";
}
sub link_add
{
my $plug = shift;
my $wild = shift;
if (defined $wild)
{
print "ln -s $libdir/$plug $servicedir/$plug$wild\n";
}
else
{
print "ln -s $libdir/$plug $servicedir/$plug\n";
}
}
sub normal
{
printf ("%-26s | %-4s | %-39s\n", @_);
}
sub get_installed
{
(my $ps, my $dir) = @_;
print "DEBUG: Opening \"$dir\" for reading...\n" if $debug;
opendir (DIR, $dir) or die "Could not open \"$dir\" for reading: $!";
my @installed = readdir (DIR);
close (DIR);
foreach my $inst (@installed)
{
my $realfile = undef;
next unless -l "$dir/$inst"; # None of our business...
next unless ($realfile = readlink ("$dir/$inst"));
next unless ($realfile =~ /^$libdir\//); # None of our business...
$realfile =~ s/^.+\///;
print "DEBUG: Checking file: $inst..." if $debug;
if ($realfile =~ /_$/) # Wildcard plugin...
{
print "$realfile..." if $debug;
(my $wild = $inst) =~ s/^$realfile//;
print "$wild..." if $debug;
push @{$ps->{$realfile}->{'suggest'}}, $wild;
}
$ps->{$realfile}->{'installed'} = "yes";
print "\n" if $debug;
}
return $ps;
}
sub get_plugins
{
(my $ps, my $dir) = @_;
my %versions = ();
if (defined $newer and -f "$dir/plugins.history")
{
if (open (HIST, "$dir/plugins.history"))
{
my @slurp = <HIST>;
my $reached_version = 0;
my $ver = "0.0.0";
close (HIST);
my $uname = lc `uname`;
chomp $uname;
foreach my $line (@slurp)
{
chomp $line;
$line =~ s/#.*//g;
$line =~ s/^\s+//g;
$line =~ s/\s+$//g;
next unless $line =~ /\S/;
if ($line =~ /^\[([^\]]+)\]$/)
{
$ver = $1;
print "Setting version to \"$ver\".\n" if $debug;
if ($ver eq $newer)
{
$reached_version = 1;
}
elsif ($reached_version)
{
$reached_version++;
}
}
elsif ($reached_version < 2)
{
next;
}
elsif ($line =~ /^([^\/]+)\/(.+)$/)
{
if ($uname eq $1)
{
$ps->{$2}->{'version'} = $ver;
print "-- Adding plugin \"$2\" to version tree ($ver)...\n" if $debug;
}
}
elsif ($line =~ /^(.+)$/)
{
$ps->{$1}->{'version'} = $ver;
print "-- Adding plugin \"$1\" to version tree ($ver)...\n" if $debug;
}
}
}
else
{
warn "Warning: Could not open \"$dir/plugins.history\": $!";
}
}
print "DEBUG: Opening \"$dir\" for reading...\n" if $debug;
opendir (DIR, $dir) or die "Could not open \"$dir\" for reading: $!";
my @plugins = readdir (DIR);
close (DIR);
foreach my $plug (@plugins)
{
my $path = "$dir/$plug";
$path = readlink($path) and $path = $path =~ /^\// ? $path : "$dir/$path" while -l $path;
next unless -f $path;
next unless -x _;
next if $plug =~ /^\./;
$ps->{$plug}->{'family'} = "contrib"; # Set default family...
print "DEBUG: Checking plugin: $plug..." if $debug;
if (! open (FILE, "$dir/$plug"))
{
warn "WARNING: Could not open file \"$dir/$plug\" for reading ($!). Skipping.";
next;
}
while (<FILE>)
{
chomp;
if (/#%#\s+family\s*=\s*(\S+)\s*$/)
{
$ps->{$plug}->{'family'} = $1;
print "$1..." if $debug;
}
elsif (/#%#\s+capabilities\s*=\s*(.+)$/)
{
foreach my $cap (split (/\s+/, $1))
{
$ps->{$plug}->{'capability'}->{$cap} = 1;
print "$cap..." if $debug;
}
}
}
close (FILE);
unless (grep (/^$ps->{$plug}->{'family'}$/, @families)) {
print "\n" if $debug;
next;
}
if ($ps->{$plug}->{'family'} eq "auto" and defined $newer and
!defined $ps->{$plug}->{'version'}) {
print "\n" if $debug;
next;
}
if ($ps->{$plug}->{'capability'}->{'autoconf'})
{
my $fork = open (PLUG, "-|");
if ($fork == -1)
{
die "ERROR: Unable to fork: $!"
}
elsif ($fork == 0) # Child
{
close (STDERR);
open (STDERR, ">&STDOUT");
exec ("$bindir/munin-run", "--servicedir", $libdir, $plug, "autoconf");
}
else
{
$ps->{$plug}->{'defaultreason'} = join (' ', map {chomp; $_} <PLUG>);
}
close (PLUG);
if ($?)
{
$ps->{$plug}->{'default'} = "no";
}
else
{
$ps->{$plug}->{'default'} = "yes";
}
print $ps->{$plug}->{'default'}, ":", $ps->{$plug}->{'defaultreason'}, "..." if $debug;
}
if ($ps->{$plug}->{'capability'}->{'suggest'})
{
if (exists $ps->{$plug}->{'default'} and
$ps->{$plug}->{'default'} eq "yes")
{
my $fork = open (PLUG, "-|");
if ($fork == -1)
{
die "ERROR: Unable to fork: $!"
}
elsif ($fork == 0) # Child
{
exec ("$bindir/munin-run", "--servicedir", $libdir, $plug, "suggest");
}
else
{
push (@{$ps->{$plug}->{'suggest'}}, split (/\s+/, join (' ', map {chomp; $_} <PLUG>)));
}
close (PLUG);
if ($?)
{
$ps->{$plug}->{'suggest'} = "";
}
print join (' ', @{$ps->{$plug}->{'suggest'}}) if $debug;
}
}
print "\n" if $debug;
}
return $ps;
}
1;
=head1 NAME
munin-node-configure - A program to view configurations for munin-node
=head1 SYNOPSIS
munin-node-configure [options]
=head1 OPTIONS
=over 5
=item B<< --help >>
View this help page
=item B<< --version >>
Show version information
=item B<< --debug >>
View debug information (very verbose)
=item B<< --config <file> >>
Override configuration file [/etc/munin/client.conf]
=item B<< --servicedir <dir> >>
Override plugin dir [/etc/munin/plugins/]
=item B<< --libdir <dir> >>
Override plugin lib [/usr/share/munin/plugins]
=item B<< --families <family,...> >>
Override families [auto]
=item B<< --suggest >>
Show suggestions instead of status
=item B<< --shell >>
Show shell commands (implies --suggest)
=item B<< --remove-also >>
Also show rm-commands when doing --shell
=item B<< --snmp <host|cidr,...> >>
Do SNMP probing on the host or CIDR network (e.g. "192.168.1.0/24"). This
may take some time, especially if the probe includes many hosts. This option
can be specified multiple times, or once with a comma-separated list, to
include more than one host/CIDR.
=item B<< --snmpversion <ver> >>
Set the SNMP version (1, 2c or 3) to use when probing. Default is "2c".
=item B<< --snmpcommunity <comm> >>
Set SNMP community to use when probing. Default is "public".
=back
=head1 DESCRIPTION
Munin's node is a daemon that Munin connects to fetch data. This data is
stored in .rrd-files, and later graphed and htmlified. It's designed to
let it be very easy to graph new datasources.
Munin-node-configure is a script to show the current configuration of which
plugins the host is running, as well as suggestions on what changes to make
to this configuration. Munin-node-configure does this by using munin-run(1) to
ask the plugins themselves of wether they should be run or not.
=head1 FILES
/etc/munin/munin-node.conf
/etc/munin/plugin-conf.d/*
/etc/munin/plugins/*
/usr/share/munin/plugins/*
=head1 VERSION
This is munin-node-configure v1.2.5.
=head1 AUTHORS
Jimmy Olsen.
=head1 BUGS
None known.
=head1 COPYRIGHT
Copyright © 2003 Jimmy Olsen
This is free software; see the source for copying conditions. There is
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
This program is released under the GNU General Public License
=cut
# vim:syntax=perl