| Category: | Linux System Administration |
| Author/Contact Info | |
| Description: | I have to keep updated a few RedHat 7.2 boxes, and wanted some simple automation to do it. I have a two liner bash script for wget-ting the updates from RH (and other sites) into the dirs 'rh/' and 'non_rh/' (I basically mirror RedHat updates for 7.2, plus a few packages, for local use). The following Perl script then checks the local repository for RPMs, and compares the versions found with those on the boxes I maintain, using ssh connections (set up for requiring no password to the account I run this script on). I'm sure it could be written better... so everybody's welcome to use it and improve it; and if you add something nice, add a comment and let other monks learn! |
#!/usr/bin/perl
use strict;
use warnings;
use RPM qw(vercmp);
my $RPM_CMD=q(rpm -q --qf '%{NAME}:%{VERSION}:%{RELEASE}:%{ARCH}\n');
sub rpm{ my($n,$v,$r,$a)=@_[0..3]; return "$n-$v-$r.$a.rpm"; }
# use your local accounts here, I've left
# only this one just to show the idea
my @accounts=(
"root\@localhost",
);
#this is a complete hack, but a whole lot faster than using
#readdir and RPM:: over each file
my %updates=();
print "Checking for available updates... ";
chomp(
my @vers=`ls rh/*.rpm non_rh/*.rpm|xargs $RPM_CMD -p`
);
# here we compute the split version numbers,
# keeping track only of the most recent update
for(@vers){
my($name,$version,$release,$arch)=split(':');
if(
!defined($updates{$name})||
vercmp(($version,$release),@{$updates{$name}}[0..1])>0
){
$updates{$name}=[$version, $release, $arch];
}
}
print "done\n";
# let's dance, then: connect to servers, get the rpm's list
# and compare versions to find if there's something to be
# updated
for my $acct (@accounts){
my ($user,$server)=split('@',$acct);
print "Checking for installed packages on $server... ";
#connect via a passwordless ssh account (authentication
# is done via an ssh key previously set up)
chomp(
my @inst=`ssh -l $user $server "$RPM_CMD -a"`
);
print "done\n";
print "######### updates for $server ############\n";
my %new=();
for(sort @inst){
my ($name,$version,$release,$arch)=split(':');
if($updates{$name}){
my ($v,$r,$a)=@{$updates{$name}};
if(vercmp(($version,$release),($v,$r))<0){
print
rpm($name,$v,$r,$a).
" (updates ".rpm($name,$version,$release,$arch).")\n";
}
}
} print "######### done with $server ############\n";
}
|
|
|
|---|