Script to inform about new updates in CentOS

A couple days ago I shared my script for OpenSuSE. Now I've re-written that Perl script to speak the language of yum. The script below is intended to run periodically by cron and to send me an e-mail, if new updates have been found for the system. It's nothing extraordinary, yum-cron can this too. But an advantage of my Perl script is that the e-mail is sent only once. No email is sent, if the same updates are found again. The trick is that the Perl script saves the updates (if any) in a temporary file to compare its content then with the updates found at the current run.

Besides I wanted to see the installed and the available versions of a package side by side. I could unfortunately get this output with yum or repoquery directly.

Below is an example output of the script:


gmp                                  4.3.1-7.el6         4.3.1-7.el6_2.2
initscripts                 9.03.27-1.el6.centos  9.03.27-1.el6.centos.1
kernel                        2.6.32-220.4.2.el6      2.6.32-220.7.1.el6
kernel-firmware               2.6.32-220.4.2.el6      2.6.32-220.7.1.el6
module-init-tools                     3.9-17.el6            3.9-19.el6_2
nss                               3.13.1-6.el6_2          3.13.1-7.el6_2
nss-sysinit                       3.13.1-6.el6_2          3.13.1-7.el6_2
openssl                         1.0.0-20.el6_2.1        1.0.0-20.el6_2.2
selinux-policy                3.7.19-126.el6_2.9     3.7.19-126.el6_2.10
selinux-policy-targeted       3.7.19-126.el6_2.9     3.7.19-126.el6_2.10
systemtap-runtime                      1.6-4.el6             1.6-5.el6_2
tzdata                               2011l-4.el6             2011n-2.el6



#!/usr/bin/perl -w
#
# Written by Hermann Maurer (c) 2012
#

my $recipients = 'yourname@domain.com';
my $lstfile = "/var/lib/yum_pchk.lst";
my $rqucmd = "/usr/bin/repoquery -qa --pkgnarrow=updates --qf=\"%-24{name} %-10{arch} %-16{repoid} %{version}-%{release}\"";
my $rqicmd = "/usr/bin/repoquery -qa --pkgnarrow=installed --qf=\"%-24{name} %-10{arch} %-16{repoid} %{version}-%{release}\"";
my $mailxcmd = "mailx -s \"New updates available for `hostname --long`\" $recipients";

my %arr_new  = ();
my %arr_old  = ();
my %arr_save = ();
my %arr_installed  = ();
my $testflag = 0;
my $param = shift || '';
if ($param eq '--test') { $testflag = 1; }

# we try to read the current output
open RT, "$rqucmd |";
while (<RT>) {
    chomp; my $str = $_;
    next if m/^$/;
    my ($name, $arch, $repo, $version) = split ;
    next if (!defined($name) or !defined($version));
    $name =~ s/^\s+//; $name =~ s/\s+$//;
    $version  =~ s/^\s+//; $version  =~ s/\s+$//;
    if (!exists($arr_new{$name})) {
        $arr_new{$name} = $version;
        push @arr_save, $str;
    }
}
close RT;

# we try to read the saved output
if (!open RT, "<", "$lstfile") {
    open RT, ">", "$lstfile";
    close RT;
    open RT, "<", "$lstfile";
}
while (<RT>) {
    chomp;
    my $str = $_;
    next if m/^$/;
    my ($name, $arch, $repo, $version) = split ;
    next if (!defined($name) or !defined($version));
    $name =~ s/^\s+//; $name =~ s/\s+$//;
    $version  =~ s/^\s+//; $version  =~ s/\s+$//;
    if (!exists($arr_old{$name})) { $arr_old{$name} = $version; }
}
close RT;

# we compare the outputs
# only if there is a patch in arr_new, that has not been in arr_old yet, then
# we say, that there is a new update
my $nu_flag = 0;
if (scalar(%arr_new)) {
    foreach $key (keys %arr_new) {
        if (!defined($arr_old{$key})) { $nu_flag = 1; }
    }
}

# we save the current output to the file, if this is not a test run
if (!$testflag) {
    open RT, ">", "$lstfile";
    foreach (@arr_save) { print RT $_, "\n"; }
    close RT;
}

open RT, "$rqicmd |";
while (<RT>) {
    chomp;
    my $str = $_;
    next if m/^$/;

    my ($name, $arch, $repo, $version) = split ;
    next if (!defined($name) or !defined($version));
    $name =~ s/^\s+//; $name =~ s/\s+$//;
    $version  =~ s/^\s+//; $version  =~ s/\s+$//;
    $arr_installed{$name} = $version;
}
close RT;

# if we found new updates
if ($nu_flag) {
    open MAIL, "| $mailxcmd ";
    foreach $name (sort keys %arr_new) {
        printf MAIL "%-24s%24s%24s\n", $name,$arr_installed{$name},$arr_new{$name};
    }
    close MAIL;
    exit 1;
}

else { exit 0; }

I'm using the Perl script under CentOs 6.2, but other versions of CentOS (and may be other Linux distributions based on Red Hat) should work too.

0 Kommentare :: Script to inform about new updates in CentOS

Post a Comment