From fd60efeb31bf2f9c639eb1186a1ae851cae352a9 Mon Sep 17 00:00:00 2001 From: Peter Palfrader Date: Mon, 13 Nov 2006 16:38:33 +0000 Subject: Try to implement timeouts git-svn-id: svn+ssh://asteria.noreply.org/svn/weaselutils/trunk@243 bc3d92e2-beff-0310-a7cd-cc87d7ac0ede --- nagios-check-apt-updates | 60 +++++++++++++++++++++++++++++++++++------------- 1 file 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=; - 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=; - 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=] [--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 in seconds for each of the two apt-get runs.\n"; print " --verbose Be a little verbose.\n"; print " --chroot= Run check in path.\n"; print " --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); } -- cgit v1.2.3