I have a machine located in a secure environment that does not have access to the internet. I has a base load of CentOS with a handful of additional RPMs. This includes a basic install of PERL with no additional modules. Nor does it have GCC installed so I can't install new modules manually nor use CPAN to install them. Therefore, I need a pure Perl solution.
I've been asked to create a Perl script that will validate that the machine has a specific list of RPMs installed and that they're a specific version or newer.
Here's what I have so far:
#!/usr/bin/perl
use strict;
use warnings;
# This is the list of RPMs to look for on the machine.
my @RPMs = ("bwm-ng",
"celt051",
"device-mapper-multipath",
"device-mapper-multipath-libs",
"dhcp",
"dhcp-common",
"ebtables",
"freeglut",
"glusterfs-api",
"glusterfs-libs",
"gnutls-utils",
"gpm",
"hmaccalc",
"iftop",
"iperf",
"ipsec-tools",
"iptraf",
"iscsi-initiator-utils",
"libsysfs",
"lm_sensors",
"lm_sensors-libs",
"log4cpp",
"lrzsz",
"lzop",
"mcsctrans",
"minicom",
"nc",
"netcf-libs",
"net-snmp",
"net-snmp-libs",
"net-snmp-utils",
"omping",
"perl-AppConfig",
"perl-Pod-POM",
"perl-Template-Toolkit",
"pimd",
"python-lxml",
"quagga",
"radvd",
"smcroute",
"usbredir",
"yajl");
# These are the RPM versions that they should be equal to or newer than.
my @RPMVersions = ("bwm-ng-0.6-6.el6.2.x86_64",
"celt051-0.5.1.3-0.el6.x86_64",
"device-mapper-multipath-0.4.9-87.el6.x86_64",
"device-mapper-multipath-libs-0.4.9-87.el6.x86_64",
"dhcp-4.1.1-49.P1.el6.centos.x86_64",
"dhcp-common-4.1.1-49.P1.el6.centos.x86_64",
"ebtables-2.0.9-6.el6.x86_64",
"freeglut-2.6.0-1.el6.x86_64",
"glusterfs-api-3.4.0.57rhs-1.el6_5.x86_64",
"glusterfs-libs-3.4.0.57rhs-1.el6_5.x86_64",
"gnutls-utils-2.8.5-18.el6.x86_64",
"gpm-1.20.6-12.el6.x86_64",
"hmaccalc-0.9.12-2.el6.x86_64",
"iftop-1.0-0.7.pre4.el6.x86_64",
"iperf-2.0.5-11.el6.x86_64",
"ipsec-tools-0.8.0-25.3.x86_64",
"iptraf-3.0.1-14.el6.x86_64",
"iscsi-initiator-utils-6.2.0.873-14.el6.x86_64",
"libsysfs-2.1.0-7.el6.x86_64",
"lm_sensors-3.1.1-17.el6.x86_64",
"lm_sensors-libs-3.1.1-17.el6.x86_64",
"log4cpp-1.0-13.el6_5.1.x86_64",
"lrzsz-0.12.20-27.1.el6.x86_64",
"lzop-1.02-0.9.rc1.el6.x86_64",
"mcsctrans-0.3.1-4.el6.x86_64",
"minicom-2.3-6.1.el6.x86_64",
"nc-1.84-24.el6.x86_64",
"netcf-libs-0.2.4-3.el6.x86_64",
"net-snmp-5.5-54.el6.x86_64",
"net-snmp-libs-5.5-54.el6.x86_64",
"net-snmp-utils-5.5-54.el6.x86_64",
"omping-0.0.4-1.el6.x86_64",
"perl-AppConfig-1.66-6.el6.x86_64",
"perl-Pod-POM-0.25-2.el6.x86_64",
"perl-Template-Toolkit-2.22-5.el6.x86_64",
"pimd-2.3.0-1.x86_64",
"python-lxml-2.2.3-1.1.el6.x86_64",
"quagga-0.99.23.1-2014082501.x86_64",
"radvd-1.6-1.el6.x86_64",
"smcroute-2.0.0-0.x86_64",
"usbredir-0.5.1-2.el6.x86_64",
"yajl-1.0.7-3.el6.x86_64");
my $RPMname; #This reprepsents an individual RPM name within the @RPMs array.
foreach $RPMname (@RPMs){ # Loop through the @RPMs array and query the RPM database for each RPM.
my $cmd = "rpm -qa | grep " . $RPMname;
my @cmdResults = `$cmd`;
if (! @cmdResults){
print "\tMissing RPM: " . $RPMname . "\n\n"; # If the RPM isn't installed; inform the user.
} else {
foreach(@cmdResults){
print "\t" . $_ . "\n"; # Print the version of the RPM that's currently installed.
# Compare the RPM version that's installed with the corresponding version that should be installed
# as listed in the @RPMVersions array.
# write some magic here. <------
}
}
}
exit(0);
I've found what appears to be a possible solution but I can't seem to figure out how to adjust the code of fit my scenario.
see here: http://www.perlmonks.org/bare/?node=240384
I can't use RPM::VersionSort or several of the other RPM related modules because of the restrictions that I mentioned above.
Any help would be hugely appreciated.
Thanks!
Some hints
You do't need grep e.g.
If a package is missing $? is 1
You can get the version of an installed rpm package using --queryformat
There is much more you can do with just rpm - have a look at the rpm.org site.
You may even be able to get away without using perl so take a look at Dennis's answer here on SO.
While this doesn't answer my original question I'd like to provide what I ended up with. I've been able to convince those in power to allow me to install the RPM::VersionSort Perl module. So this isn't a Pure Perl solution as I was hoping to find.
Here's what I'm using now for anyone who's interested:
;