dsa-check-packages: Ignore :$arch in package names of dpkg -l output
[mirror/dsa-nagios.git] / dsa-nagios-checks / checks / dsa-check-packages
index 29e7e4d..107b94b 100755 (executable)
@@ -38,6 +38,7 @@ use warnings;
 use English;
 
 my $IGNORE = "/etc/nagios/obsolete-packages-ignore";
+my $IGNORED = "/etc/nagios/obsolete-packages-ignore.d";
 
 my %CODE = (
        'OK'            => 0,
@@ -60,7 +61,13 @@ sub record($) {
 sub get_packages {
        $ENV{'COLUMNS'} = 1000;
        $ENV{'LC_ALL'} = 'C';
-       open(F, "dpkg -l|") or die ("Cannot run dpkg: $!\n");
+       open(F, "dpkg --print-architecture|") or die ("Cannot run dpkg --print-architecture: $!\n");
+       my $arch = <F>;
+       chomp($arch);
+       close(F);
+
+
+       open(F, "dpkg -l|") or die ("Cannot run dpkg -l: $!\n");
        my @lines = <F>;
        close(F);
        chomp(@lines);
@@ -71,6 +78,7 @@ sub get_packages {
        my %pkgs;
        for my $line (@lines) {
                my ($state, $pkg, $version, undef) = split(/  */, $line);
+               $pkg =~ s/\Q:$arch\E$//;
                $pkgs{$state}{$pkg} = { 'installed' => $version }
        }
 
@@ -132,16 +140,33 @@ sub get_packages {
 }
 
 sub load_ignores {
-       my ($ignorefile, $require_file) = @_;
+       my ($ignorefiles, $require_file) = @_;
 
        my @ignores;
-       if (!$require_file and ! -e $ignorefile) {
-               return \@ignores;
-       }
 
-       open (F, "< $ignorefile") or die ("Cannot open $ignorefile: $!\n");
-       @ignores = <F>;
-       close F;
+       for my $ignoreitem (@$ignorefiles) {
+               next if (!$require_file and ! -e $ignoreitem);
+
+               my @filestoopen;
+               if (-d $ignoreitem) {
+                       opendir(DIR, $ignoreitem) or die ("Cannot open dir $ignoreitem: $!\n");
+                       @filestoopen = readdir(DIR);
+                       closedir(DIR);
+
+                       @filestoopen = grep { -f ($ignoreitem.'/'.$_) } @filestoopen;
+                       @filestoopen = grep { /^([a-z0-9_.-]+)+[a-z0-9]+$/i } @filestoopen;
+                       @filestoopen = grep { !/dpkg-(old|dist|new|tmp)$/ } @filestoopen;
+                       @filestoopen = map { ($ignoreitem.'/'.$_) } @filestoopen;
+               } else {
+                       push @filestoopen, $ignoreitem;
+               }
+
+               for my $f (@filestoopen) {
+                       open (F, "< $f") or die ("Cannot open $f: $!\n");
+                       push @ignores, <F>;
+                       close F;
+               }
+       }
        chomp(@ignores);
        return \@ignores;
 }
@@ -182,21 +207,20 @@ sub filter_ignored {
 
 sub usage {
        my ($fd, $exit) = @_;
-       print $fd "Usage: $PROGRAM_NAME [<ignorefile>]\n";
+       print $fd "Usage: $PROGRAM_NAME [<ignorefile|dir> [<ignorefile|dir> ...]]\n";
        exit $exit;
 }
 
-my $ignorefile = $IGNORE;
+my $ignorefiles = [$IGNORE, $IGNORED];
 my $ignorefile_userset = 0;
-usage(\*STDERR, 1) if (@ARGV > 1);
-if (@ARGV == 1) {
+if (@ARGV >= 1) {
        usage(\*STDOUT, 0) if ($ARGV[0] eq "-h");
        usage(\*STDOUT, 0) if ($ARGV[0] eq "--help");
-       $ignorefile = $ARGV[0];
        $ignorefile_userset = 1;
+       $ignorefiles = \@ARGV;
 };
 
-my $ignores = load_ignores($ignorefile, $ignorefile_userset);
+my $ignores = load_ignores($ignorefiles, $ignorefile_userset);
 my $packages = get_packages();
 
 filter_ignored($packages, $ignores);
@@ -207,46 +231,55 @@ my @reportform = (
        { 'key' => 'obsolete',
          'listpackages' => 1,
          'long' => "%d local or obsolete packages: %s",
-         'short' => "%d obs",
+         'short' => "%d obs/loc",
+         'perf' => "obs_loc=%d;1;5;0",
          'status' => 'WARNING' },
        { 'key' => 'outofdate',
          'listpackages' => 1,
          'long' => "%d out of date packages: %s",
          'short' => "%d updates",
+         'perf' => "outdated=%d;1;5;0",
          'status' => 'WARNING' },
        { 'key' => 'current',
          'listpackages' => 0,
          'long' => "%d packages current.",
          'short' => "%d ok",
+         'perf' => "current=%d;;;0",
          'status' => 'OK' },
        { 'key' => 'obsolete-ignored',
          'listpackages' => 1,
          'long' => "%d whitelisted local or obsolete packages: %s",
-         'short' => "%d obs(ignored)",
+         'short' => "%d obs/loc(ignored)",
+         'perf' => "obs_ign=%d;;;0",
          'status' => 'OK' },
        { 'key' => 'rc',
          'listpackages' => 1,
          'long' => "%d packages removed but not purged: %s",
          'short' => "%d rc",
+         'perf' => "rm_unprg=%d;;;0",
          'status' => 'OK' },
        { 'key' => 'hi',
          'listpackages' => 1,
          'long' => "%d packages on hold: %s",
          'short' => "%d hi",
+         'perf' => "hold=%d;;;0",
          'status' => 'OK' },
        { 'key' => 'pc',
          'listpackages' => 1,
          'long' => "%d packages requested to be purged but conffiles still installed: %s",
          'short' => "%d pc",
+         'perf' => "prg_conf=%d;1;;0",
          'status' => 'WARNING' },
        );
 
 my @longout;
+my @perfout;
 my @shortout;
 for my $form (@reportform) {
        my $pkgs = $packages->{$form->{'key'}};
        delete $packages->{$form->{'key'}};
        my $num = scalar keys %$pkgs;
+       push @perfout, sprintf($form->{'perf'}, $num);
        next unless ($num > 0);
        if ($form->{'listpackages'}) {
                my $list = join(", ", keys %$pkgs);
@@ -269,8 +302,10 @@ if (scalar keys %$packages) {
 
 my $shortout = $EXITCODE.": ".join(", ", @shortout);
 my $longout = join("\n", @longout);
+my $perfout = "|".join(" ", @perfout);
 
-print $shortout,"\n";
+print $shortout;
 print $longout,"\n";
+print $perfout,"\n";
 
 exit $CODE{$EXITCODE};