[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Stable update proposal: sitesummary 0.0.33



Ref item 9 on <URL:http://wiki.debian.org/DebianEdu/Meeting/20070813>,
here is a update proposal for the stable release.

I propose to update the version of sitesummary in the stable
repository from 0.0.30 to 0.0.33.  This fixes a bug in the collection
of the peername IP address, and add a few featires to list the clients
with a given kernel version or that have not submitted information for
a while.  There is also a draft nagios config generator, but this is
not yet complete.

The changes are tested on the skolelinux servers, and the resulting
output can be seen on <URL:http://maintainer.skolelinux.no/sitesummary/>.

Here is the diff -r output between the two versions:

Index: debian/changelog
===================================================================
--- debian/changelog    (revision 38710)
+++ debian/changelog    (working copy)
@@ -1,3 +1,34 @@
+sitesummary (0.0.33) unstable; urgency=low
+
+  * Collect loaded kernel modules, to ease nagios autoconfiguration.
+  * Add >180 days to the agesinceseen-summary list, for really old entries.
+
+ -- Petter Reinholdtsen <pere@debian.org>  Sat,  1 Dec 2007 14:13:16 +0100
+
+sitesummary (0.0.32) unstable; urgency=low
+
+  * Collect /proc/mounts and /etc/fstab in system, for use when
+    generating nagios checks for the file systems.
+  * Start on experimental code to generate nagios configuration from
+    the collected sitesummary information.
+  * Fix peername code in the collector.
+  * Set the locale to C when collecting data, to make sure the output
+    format is well known. (Closes: #452899)
+  * Minor cleanup in output.
+
+ -- Petter Reinholdtsen <pere@debian.org>  Mon, 26 Nov 2007 09:52:33 +0100
+
+sitesummary (0.0.31) unstable; urgency=low
+
+  * Add -l option to kernelversion-summary and site-summary, to get it
+    to list the individual hosts with the given kernel version and
+    site/sitegroup setting.
+  * New script agesinceseen-summary, listing the hosts that have
+    failed to submit a report in the last few days.  It support -l to
+    list the individual hosts.
+
+ -- Petter Reinholdtsen <pere@debian.org>  Fri, 23 Nov 2007 22:28:14 +0100
+
 sitesummary (0.0.30) unstable; urgency=low

   * Change default apache setup to allow everyone read access to
Index: agesinceseen-summary
===================================================================
--- agesinceseen-summary        (revision 0)
+++ agesinceseen-summary        (revision 39483)
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use SiteSummary;
+use Getopt::Std;
+
+my %agegroup =
+    (
+      0 => '>0 days',
+      3 => '>3 days',
+      7 => '>one week',
+     14 => '>14 days',
+     30 => '>30 days',
+     90 => '>90 days',
+    180 => '>180 days',
+);
+
+my %agedist;
+my %opts;
+
+sub usage {
+    my $retval = shift;
+    print <<EOF;
+Usage: $0 [-l]
+   -l   list hosts with the given age
+EOF
+    exit $retval;
+}
+
+getopt("l", \%opts) || usage(1);
+
+for_all_hosts(\&handle_host);
+
+print_summary();
+
+sub handle_host {
+    my $hostid = shift;
+    my $topdir = get_filepath_current($hostid, "/");
+    my $age = (time() - (stat($topdir))[9]) / (60 * 60 * 24);
+
+    my $thisgroup;
+    for my $group (sort { $a <=> $b; } keys %agegroup) {
+        if ($age > $group) {
+            $thisgroup = $group;
+        }
+    }
+    if (defined $thisgroup) {
+        if (exists $agedist{$thisgroup}) {
+            push @{$agedist{$thisgroup}}, $hostid ;
+        } else {
+            $agedist{$thisgroup} = [$hostid];
+        }
+    }
+}
+
+sub print_summary {
+    printf("  %-20s %5s\n", "hostclass", "count");
+    for my $group (sort { $a <=> $b; } keys %agedist) {
+        printf("  %-20s %5d\n", $agegroup{$group}, scalar @{$agedist{$group}});
+        if (exists $opts{l}) {
+            for my $hostid (sort @{$agedist{$group}}) {
+                my $hostname = get_hostname($hostid);
+                my $site = get_site($hostid) || "";
+                my $sitegroup = get_sitegroup($hostid) || "";
+                printf "    %s %s/%s %s\n", $hostname, $site, $sitegroup, $hostid;
+            }
+            print "\n";
+        }
+    }
+}
Index: collect.d/system
===================================================================
--- collect.d/system    (revision 38710)
+++ collect.d/system    (working copy)
@@ -26,7 +26,15 @@
     lsscsi       > lsscsi
 fi

+if type lsmod >/dev/null 2>&1; then
+    lsmod       > lsmod
+fi
+
 uname -smr  > uname-smr
 uname -n    > hostname
 ifconfig -a > ifconfig-a
 cat /proc/cpuinfo > cpuinfo
+
+# Collect mount points, for nagios configuration
+cp /etc/fstab fstab
+cat /proc/mounts > procmounts
Index: kernelversion-summary
===================================================================
--- kernelversion-summary       (revision 38710)
+++ kernelversion-summary       (working copy)
@@ -4,9 +4,22 @@
 use warnings;

 use SiteSummary;
+use Getopt::Std;

 my %kernelvers;
+my %opts;

+sub usage {
+    my $retval = shift;
+    print <<EOF;
+Usage: $0 [-l]
+   -l   list hosts using the given kernel versions
+EOF
+    exit $retval;
+}
+
+getopt("l", \%opts) || usage(1);
+
 for_all_hosts(\&handle_host);

 print_summary();
@@ -15,14 +28,26 @@
     my $hostid = shift;
     #print "$hostid\n";
     for my $kver (get_linux_kernel_ver($hostid)) {
-       $kver = "" unless defined $kver;
-       $kernelvers{$kver}++;
+        $kver = "" unless defined $kver;
+        if (exists $kernelvers{$kver}) {
+            push @{$kernelvers{$kver}}, $hostid ;
+        } else {
+            $kernelvers{$kver} = [$hostid];
+        }
     }
 }

 sub print_summary {
     printf("  %-20s %5s\n", "kernel", "count");
     for my $kver (sort keys %kernelvers) {
-       printf("  %-20s %5d\n", $kver, $kernelvers{$kver});
+        printf("  %-20s %5d\n", $kver,  scalar @{$kernelvers{$kver}});
+        if (exists $opts{l}) {
+            for my $hostid (sort @{$kernelvers{$kver}}) {
+                my $hostname = get_hostname($hostid);
+                my $site = get_site($hostid) || "";
+                my $sitegroup = get_sitegroup($hostid) || "";
+                printf "    %s %s/%s %s\n", $hostname, $site, $sitegroup, $hostid;
+            }
+        }
     }
 }
Index: sitesummary-makewebreport
===================================================================
--- sitesummary-makewebreport   (revision 38710)
+++ sitesummary-makewebreport   (working copy)
@@ -15,7 +15,12 @@
 <pre>
 EOF

-for f in site-summary hostclass-summary kernelversion-summary debian_edu-summary ; do
+for f in site-summary \
+    hostclass-summary \
+    kernelversion-summary \
+    agesinceseen-summary \
+    debian_edu-summary ; do
+    echo "$f:"
     /usr/lib/sitesummary/$f
     echo
 done
Index: sitesummary-nodes
===================================================================
--- sitesummary-nodes   (revision 38710)
+++ sitesummary-nodes   (working copy)
@@ -10,7 +10,7 @@
 use Getopt::Std;

 my %opts;
-getopts("m", \%opts);
+getopts("mn", \%opts);

 my %hostnames;

@@ -18,6 +18,8 @@

 if ($opts{'m'}) {
     print_munin_list();
+} elsif ($opts{'n'}) { # XXX Nagios config generation do not work yet
+    generate_nagios_config();
 } else {
     print_list();
 }
@@ -34,13 +36,13 @@
     }
 }

-sub is_munin_client {
-    my $hostid = shift;
-    # Check debian/dpkg-l for 'ii *munin-node '
+sub is_pkg_installed {
+    my ($hostid, $pkgname) = @_;
+    # Check debian/dpkg-l for 'ii *pkgname '
     my $path = get_filepath_current($hostid, "/debian/dpkg-l");
     if (open (my $fh, $path)) {
         while(<$fh>) {
-            if (m/^ii *munin-node /) {
+            if (m/^ii *$pkgname /) {
                 close($fh);
                 return 1
             }
@@ -50,6 +52,17 @@
     return undef;
 }

+sub is_munin_client {
+    my $hostid = shift;
+    return is_pkg_installed($hostid, "munin-node");
+}
+
+sub is_nagios_client {
+    my $hostid = shift;
+    return is_pkg_installed($hostid, "nagios-nrpe-server") ||
+        is_pkg_installed($hostid, "nagios-text");
+}
+
 sub print_munin_list {
     for my $hostname (sort keys %hostnames) {
         next unless (is_munin_client($hostnames{$hostname}));
@@ -65,3 +78,100 @@
 EOF
     }
 }
+
+sub generate_nagios_config {
+    for my $hostname (sort keys %hostnames) {
+        my $hostid = $hostnames{$hostname};
+        next unless (is_nagios_client($hostid));
+
+        my $ifconfigpath = get_filepath_current($hostid, "/system/ifconfig-a");
+        my $peerinfopath = get_filepath_current($hostid, "/peerinfo");
+        open (F, "<", $peerinfopath)||die "Unable to read from $peerinfopath";
+        my ($address) = split(/\s+/, scalar <F>);
+        close(F);
+
+        # first, check ping to see if the other checks should be performed
+        print <<EOF;
+##################### $hostname #######################
+define host {
+        host_name           $hostname
+        address             $address
+}
+define service {
+        use                 server-service
+        host_name           $hostname
+        service_description ping
+        check_command       check_ping!100.0,20%!500.0,60%
+}
+EOF
+
+            print <<EOF if is_pkg_installed($hostid, "openssh-server");
+define service {
+        use                 server-service
+        host_name           $hostname
+        service_description ssh
+        check_command       check_ssh
+}
+EOF
+
+        my %tcpservices =
+        (
+         139  => { name => 'samba',   package => 'samba' },
+         631  => { name => 'cups',    package => 'cupsys' },
+         636  => { name => 'ldaps',   package => 'slapd' },
+         3128 => { name => 'squid',   package => 'squid' },
+#       10000 => { name => 'webmin',  package => 'webmin' },
+         );
+
+        for my $port (sort { $a <=> $b } keys %tcpservices) {
+            next if (exists $tcpservices{$port}->{package} && !
+                     is_pkg_installed($hostid,
+                                      $tcpservices{$port}->{package}));
+            my $servicename = $tcpservices{$port}->{name};
+            print <<EOF;
+define service {
+        use                 server-service
+        host_name           $hostname
+        service_description $servicename
+        check_command       check_tcp!$port
+}
+EOF
+        }
+        # check munin if munin-node is installed
+        # check hw and sw raid status
+        # check hardware status
+        # check free swap
+        # check X font server
+        # check LDAP
+        # check DNS
+        # check disk free space
+        my $path = get_filepath_current($hostid, "/system/procmounts");
+        if ( -e $path ) {
+            open (F, "<", $path) || die "unable to read from $path";
+            my %checked;
+            while (<F>) {
+                chomp;
+                my ($dev, $partition, $fs, $opts) = split;
+                next if (exists $checked{$partition});
+                next if ($fs eq "devpts" ||
+                         $fs eq "proc" ||
+                         $fs eq "rootfs" ||
+                         $fs eq "rpc_pipefs" ||
+                         $fs eq "sysfs" ||
+                         $fs eq "tmpfs");
+
+                $checked{$partition} = 1;
+                my $warn = 10;
+                my $crit = 5;
+                print <<EOF;
+define service {
+        use                 server-service
+        host_name           $hostname
+        service_description Disk $partition
+        check_command       check_disk!$warn%!$crit%!$partition
+}
+EOF
+            }
+        }
+    }
+}
Index: sitesummary-client
===================================================================
--- sitesummary-client  (revision 38710)
+++ sitesummary-client  (working copy)
@@ -8,7 +8,12 @@
 set -e

 PATH=/sbin:/usr/sbin:/bin:/usr/bin
+export PATH

+# Make sure the output from programs is well known.
+LC_ALL=C
+export LC_ALL
+
 # Make sure to store files in a ramfs backed
 # storage area on diskless clients, so use /tmp/.
 tmpdir=/tmp/sitesummary-$$
Index: site-summary
===================================================================
--- site-summary        (revision 38710)
+++ site-summary        (working copy)
@@ -4,10 +4,25 @@
 use warnings;

 use SiteSummary;
+use Getopt::Std;

 my %sites;
 my %sitegroups;
+my %hostmap;
+my %sitegroupmap;
+my %opts;

+sub usage {
+    my $retval = shift;
+    print <<EOF;
+Usage: $0 [-l]
+   -l   list hosts with the given site/sitegroup
+EOF
+    exit $retval;
+}
+
+getopt("l", \%opts) || usage(1);
+
 for_all_hosts(\&handle_host);

 print_summary();
@@ -16,18 +31,48 @@
     my $hostid = shift;
     #print "$hostid\n";
     for my $site (get_site($hostid)) {
-       $site = "" unless defined $site;
-       $sites{$site}++;
-       $sitegroups{$site}{get_sitegroup($hostid)}++ if get_sitegroup($hostid);
+        $site = "" unless defined $site;
+        $sites{$site}++;
+        my $sitegroup = get_sitegroup($hostid);
+        if ($sitegroup) {
+            $sitegroups{$site}{$sitegroup}++;
+            if (exists $sitegroupmap{$site} && exists $sitegroupmap{$site}{$sitegroup}) {
+                push @{$sitegroupmap{$site}{$sitegroup}}, $hostid ;
+            } else {
+                $sitegroupmap{$site}{$sitegroup} = [$hostid];
+            }
+        } else {
+            if (exists $hostmap{$site}) {
+                push @{$hostmap{$site}}, $hostid ;
+            } else {
+                $hostmap{$site} = [$hostid];
+            }
+        }
     }
 }

 sub print_summary {
     printf("  %-20s %5s\n", "site", "count");
     for my $site (sort keys %sites) {
-       printf("  %-20s %5d\n", $site, $sites{$site});
-       for my $sitegroup (sort keys %{$sitegroups{$site}}) {
-           printf("    %-18s %5d\n", $sitegroup, $sitegroups{$site}{$sitegroup});
-       }
+        printf("  %-20s %5d\n", $site, $sites{$site});
+        if (exists $opts{l}) {
+            for my $hostid (sort @{$hostmap{$site}}) {
+                my $hostname = get_hostname($hostid);
+                my $site = get_site($hostid) || "";
+                my $sitegroup = get_sitegroup($hostid) || "";
+                printf "    %s %s/%s %s\n", $hostname, $site, $sitegroup, $hostid;
+            }
+        }
+        for my $sitegroup (sort keys %{$sitegroups{$site}}) {
+            printf("    %-18s %5d\n", $sitegroup, $sitegroups{$site}{$sitegroup});
+            if (exists $opts{l}) {
+                for my $hostid (sort @{$sitegroupmap{$site}{$sitegroup}}) {
+                    my $hostname = get_hostname($hostid);
+                    my $site = get_site($hostid) || "";
+                    my $sitegroup = get_sitegroup($hostid) || "";
+                    printf "      %s %s/%s %s\n", $hostname, $site, $sitegroup, $hostid;
+                }
+            }
+        }
     }
 }
Index: sitesummary-collector.cgi
===================================================================
--- sitesummary-collector.cgi   (revision 38710)
+++ sitesummary-collector.cgi   (working copy)
@@ -10,6 +10,7 @@
 use CGI;
 use POSIX qw(strftime);
 use Socket;
+use Sys::Syslog;

 my $basedir   = "/var/lib/sitesummary";
 my $handlerdir = "/usr/lib/sitesummary/handler.d";
@@ -17,6 +18,9 @@
 $ENV{PATH} = "/bin:/usr/bin";

 print "Content-Type: text/plain\n\n";
+
+my ($peeripaddr, $peername) = get_peerinfo(\*STDIN);
+
 if (exists $ENV{REQUEST_METHOD} && $ENV{REQUEST_METHOD} ne "POST")
 {
     print "Sitesummary  HTTP-POST submission URL\n";
@@ -62,7 +66,6 @@
 EOF
 }

-my ($peeripaddr, $peername) = get_peerinfo(\*STDIN);
 my $timestamp = strftime("%Y-%m-%dT%H:%M:%S", gmtime());

 if ($filename =~ m/.tar.gz$/) {
@@ -76,7 +79,7 @@
 # XXX Come up with some unique file name.
 my $savefile = "$basedir/tmpstorage/$peeripaddr-$timestamp-$$-$filename";

-open(SITESUMMARY, ">$savefile") or die "Unable to write to $savefile";
+open(SITESUMMARY, ">", $savefile) or die "Unable to write to $savefile";
 print SITESUMMARY @entry;
 close SITESUMMARY;

@@ -95,10 +98,10 @@
     my $eth2mac;
     open(IFCONFIG, "system/ifconfig-a") || die "Unable to read ifconfig-a";
     while (<IFCONFIG>) {
-       chomp;
-       $eth0mac = $1 if (m/^eth0\s+Link encap:Ethernet  HWaddr (\S+)/);
-       $eth1mac = $1 if (m/^eth1\s+Link encap:Ethernet  HWaddr (\S+)/);
-       $eth2mac = $1 if (m/^eth2\s+Link encap:Ethernet  HWaddr (\S+)/);
+        chomp;
+        $eth0mac = $1 if (m/^eth0\s+Link encap:Ethernet  HWaddr (\S+)/);
+        $eth1mac = $1 if (m/^eth1\s+Link encap:Ethernet  HWaddr (\S+)/);
+        $eth2mac = $1 if (m/^eth2\s+Link encap:Ethernet  HWaddr (\S+)/);
     }
     close (IFCONFIG);
     #print STDERR "MAC: $eth0mac\n";
@@ -110,12 +113,12 @@
     my ($peeripaddr, $peername, $filename) = @_;
     my $dirname;
     if ($filename =~ m/(.+).tar.gz$/) {
-       $dirname = $1;
-       mkdir $dirname;
-       chdir $dirname;
-       `tar zxf $filename`;
+        $dirname = $1;
+        mkdir $dirname;
+        chdir $dirname;
+        `tar zxf $filename`;
     } else {
-       die "Unhandled file format '$filename'";
+        die "Unhandled file format '$filename'";
     }

     open(PEERINFO, ">peerinfo") || die;
@@ -127,37 +130,38 @@

     my $status = "new";
     if ( -d $newdir ) {
-       `rm -r $newdir`;
-       my $status = "update";
+        `rm -r $newdir`;
+        my $status = "update";
     }

     rename $dirname, $newdir || die;
     for my $handler (<$handlerdir/*>) {
-       `$handler $newdir $status`;
+        `$handler $newdir $status`;
     }
 }

 sub get_peerinfo {
     my $sockethandle = shift;
+    my ($peeripaddr, $peername) = ("", "");

-    # Return something while this function do not work.
-    return ("127.0.0.1", "localhost");
-
-    # XXX The call to sockaddr_in trigger "Bad arg length for
-    # Socket::unpack_sockaddr_in, length is 2, should be 16 at
-    # /usr/lib/perl/5.8/Socket.pm line 198."  No idea why.
-    my ($peerport, $peeripaddr) = sockaddr_in(getpeername($sockethandle));
-    if ($peerport) {
-       my $peername = gethostbyaddr($peeripaddr, AF_INET);
-
-       if ("" eq $peername) {
-           syslog('warning', "client without DNS entry connected from \[$peeripaddr\]");
-           $peername = "$peeripaddr";
-       }
+    my $sockaddr = getpeername($sockethandle);
+    if ($sockaddr) {
+        my $peerport;
+        ($peerport, $peeripaddr) = sockaddr_in($sockaddr);
+        $peername = gethostbyaddr($peeripaddr, AF_INET);
+    } elsif ($ENV{'REMOTE_ADDR'}) { # CGI variable
+        $peeripaddr = $ENV{'REMOTE_ADDR'};
+        $peeripaddr =~ m/(\d+).(\d+).(\d+).(\d+)/; # Untaint
+        $peeripaddr = "$1.$2.$3.$4";
+        $peername = gethostbyaddr($peeripaddr, AF_INET);
     } else {
         # Running on the command line, use test host
         $peeripaddr = "127.0.0.1";
         $peername = "localhost";
     }
+    if ("" eq $peername) {
+        syslog('warning', "%s", "client without DNS entry connected from \[$peeripaddr\]");
+        $peername = "$peeripaddr";
+    }
     return ($peeripaddr, $peername);
 }
Index: Makefile
===================================================================
--- Makefile    (revision 38710)
+++ Makefile    (working copy)
@@ -21,6 +21,7 @@
        collect.d/siteinfo

 SUMMARYSCRIPTS = \
+       agesinceseen-summary \
        site-summary \
        hostclass-summary \
        kernelversion-summary \



Reply to: