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

Stable update proposal: sitesummary 0.0.35



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.35.  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.  It also fixes a minor bug in the client, collecting locale
specific information the collector can't parse.

There is also a draft nagios config generator, but this is not yet
complete, and only provided to inspire those interested in further
work.  It is not used, and will probably need more work to be
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,56 @@
+sitesummary (0.0.35) unstable; urgency=low
+
+  [ Petter Reinholdtsen ]
+  * Recognice nagios2 as a nagios client/server indicator.
+
+  [ Daniel Hess ]
+  * Make get_peerinfo of sitesummary-collector.cgi return the
+    dotted decimal representation of the remote IP address even
+    with webservers that don't set REMOTE_ADDR but passes the
+    filedescriptor of the TCP socket.
+
+ -- Petter Reinholdtsen <pere@debian.org>  Mon,  3 Dec 2007 21:25:29 +0100
+
+sitesummary (0.0.34) unstable; urgency=low
+
+  * Prefer REMOTE_ADDR over the output from gethostbyaddr() in
+    get_peerinfo(), to avoid "Bad arg length" problem.  Rewrite
+    get_peerinfo() to look ip REMOTE_ADDR in DNS when creating
+    peerinfo.
+
+ -- Petter Reinholdtsen <pere@debian.org>  Sun,  2 Dec 2007 19:25:51 +0100
+
+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: 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,39 @@

     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 ($peeripstr, $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";
-       }
+    if ($ENV{'REMOTE_ADDR'}) { # CGI variable
+        $peeripstr = $ENV{'REMOTE_ADDR'};
+        $peeripstr =~ m/(\d+).(\d+).(\d+).(\d+)/; # Untaint
+        $peeripstr = "$1.$2.$3.$4";
+        $peeripaddr = inet_aton($peeripstr);
+        $peername = gethostbyaddr($peeripaddr, AF_INET);
+    } elsif (my $sockaddr = getpeername($sockethandle)) {
+        my $peerport;
+        ($peerport, $peeripaddr) = sockaddr_in($sockaddr);
+        $peername = gethostbyaddr($peeripaddr, AF_INET);
+        $peeripstr = inet_ntoa($peeripaddr);
     } else {
         # Running on the command line, use test host
-        $peeripaddr = "127.0.0.1";
+        $peeripstr = "127.0.0.1";
         $peername = "localhost";
     }
-    return ($peeripaddr, $peername);
+    if ("" eq $peername) {
+        syslog('warning', "%s", "client without DNS entry connected from \[$peeripstr\]");
+        $peername = "$peeripstr";
+    }
+    return ($peeripstr, $peername);
 }
Index: agesinceseen-summary
===================================================================
--- agesinceseen-summary        (revision 0)
+++ agesinceseen-summary        (revision 39602)
@@ -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: 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,18 @@
     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") ||
+        is_pkg_installed($hostid, "nagios2");
+}
+
 sub print_munin_list {
     for my $hostname (sort keys %hostnames) {
         next unless (is_munin_client($hostnames{$hostname}));
@@ -65,3 +79,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: 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: 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: