summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xnagios-check-apt-updates60
1 files changed, 44 insertions, 16 deletions
diff --git a/nagios-check-apt-updates b/nagios-check-apt-updates
index f89c592..346a49d 100755
--- a/nagios-check-apt-updates
+++ b/nagios-check-apt-updates
@@ -25,6 +25,8 @@
use strict;
use English;
use Getopt::Long;
+use IO::Handle;
+use IPC::Open2;
$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
@@ -32,25 +34,46 @@ delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
my $APT = '/usr/bin/apt-get';
my $VERBOSE;
-sub do_check($$$$) {
- my ($pre_command, $name, $updates_security, $updates_other) = @_;
+sub do_check($$$$$) {
+ my ($pre_command, $timeout, $name, $updates_security, $updates_other) = @_;
+ my $fh;
+ my $pid;
+ my @command;
print STDERR "Running $APT update in $name\n" if $VERBOSE;
- open (UPDATE, "$pre_command$APT update|") or die ("Cannot run $APT update in $name: $!\n");
- my @ignore=<UPDATE>;
- close UPDATE;
+ @command = ($APT, 'update');
+ unshift @command, @$pre_command;
+ $fh = new IO::Handle;
+ $pid = open2($fh, \*STDIN, @command) or die ("Cannot run $APT update in $name: $!\n");
+ local $SIG{ALRM} = sub { die "Timeout for apt-get update.\n" };
+ alarm $timeout;
+ my @ignore=<$fh>;
+ alarm 0;
+ close $fh;
+ waitpid $pid, 0;
if ($CHILD_ERROR) { # program failed
die("$APT update returned with non-zero exit code in $name: ".($CHILD_ERROR / 256)."\n");
};
- print STDERR "Running $APT --simulate upgrade | sort -u in $name\n" if $VERBOSE;
- open (TODO, "$pre_command$APT --simulate upgrade | sort -u |") or die ("Cannot run $APT --simulate upgrade | sort -u in $name: $!\n");
- my @lines=<TODO>;
- close TODO;
+ print STDERR "Running $APT --simulate upgrade in $name\n" if $VERBOSE;
+ @command = ($APT, qw{--simulate upgrade});
+ unshift @command, @$pre_command;
+ $fh = new IO::Handle;
+ $pid = open2($fh, \*STDIN, @command) or die ("Cannot run $APT --simulate upgrade | sort -u in $name: $!\n");
+ local $SIG{ALRM} = sub { die "Timeout for apt-get --simulate upgrade.\n" };
+ alarm $timeout;
+ my @lines=<$fh>;
+ close $fh;
+ alarm 0;
+ waitpid $pid, 0;
if ($CHILD_ERROR) { # program failed
die("$APT --simulate upgrade | sort -u returned with non-zero exit code in $name: ".($CHILD_ERROR / 256)."\n");
};
+ @lines = sort {$a cmp $b} @lines;
+ my %uniq;
+ @lines = grep {!$uniq{$_}++} @lines;
+
print STDERR "Processing information for $name\n" if $VERBOSE;
for my $line (@lines) {
if ($line =~ m/^Inst\s+(\S+)\s+/) {
@@ -78,6 +101,7 @@ my $UNKNOWN = 3;
$params->{'chroots'} = [];
$params->{'vservers'} = [];
+$params->{'timeout'} = 20;
Getopt::Long::config('bundling');
if (!GetOptions (
'--help' => \$params->{'help'},
@@ -86,10 +110,11 @@ if (!GetOptions (
'--nosudo' => \$params->{'nosudo'},
'--verbose' => \$params->{'verbose'},
'--warnifupdates' => \$params->{'warnifupdates'},
+ '--timeout=i' => \$params->{'timeout'},
'--chroot=s' => $params->{'chroots'},
'--vserver=s' => $params->{'vservers'}
)) {
- die ("Usage: $PROGRAM_NAME [--help|--version] [--sudo|--nosudo] [--verbose]\n");
+ die ("Usage: $PROGRAM_NAME [--help|--version] [--sudo|--nosudo] [--timeout=<timeout>] [--verbose]\n");
};
if ($params->{'help'}) {
print "nagios-check-apt-updates $VERSION\n";
@@ -101,6 +126,7 @@ if ($params->{'help'}) {
print " --sudo Use sudo to call apt-get (default).\n";
print " --nosudo Do not use sudo to call apt-get.\n";
print " --warnifupdates Exit with a WARNING status if any updates are available.\n";
+ print " --timeout=<timeout> Timeout in seconds for each of the two apt-get runs.\n";
print " --verbose Be a little verbose.\n";
print " --chroot=<path> Run check in path.\n";
print " --vserver=<vserver> Run check in vserver.\n";
@@ -157,9 +183,10 @@ for my $root (@{$params->{'chroots'}}) {
};
};
for my $root (@chroots) {
- my $pre_command = ($root ne '/') ? "chroot $root " : '';
- $pre_command = ($use_sudo ? 'sudo ' : '').$pre_command;
- do_check($pre_command, $root, \@updates_security, \@updates_other);
+ my @pre_command = ();
+ unshift @pre_command, 'chroot', $root if ($root ne '/');
+ unshift @pre_command, 'sudo' if $use_sudo;
+ do_check(\@pre_command, $params->{'timeout'}, $root, \@updates_security, \@updates_other);
}
# Make sure vserver names are nice;
@@ -172,9 +199,10 @@ for my $vserver (@{$params->{'vservers'}}) {
};
};
for my $vserver (@vservers) {
- my $pre_command = "/usr/sbin/vserver $vserver exec ";
- $pre_command = ($use_sudo ? 'sudo ' : '').$pre_command;
- do_check($pre_command, $vserver, \@updates_security, \@updates_other);
+ my @pre_command = ();
+ unshift @pre_command, '/usr/sbin/vserver', $vserver, 'exec';
+ unshift @pre_command, 'sudo' if $use_sudo;
+ do_check(\@pre_command, $params->{'timeout'}, $vserver, \@updates_security, \@updates_other);
}