Назад | Перейти на главную страницу

Проверка версии Pure Perl RPM

У меня есть машина, расположенная в безопасной среде, у которой нет доступа к Интернету. У меня есть базовая загрузка CentOS с несколькими дополнительными RPM. Это включает в себя базовую установку PERL без дополнительных модулей. Также не установлен GCC, поэтому я не могу устанавливать новые модули вручную или использовать CPAN для их установки. Поэтому мне нужно чистое решение Perl.

Меня попросили создать сценарий Perl, который будет проверять, что на машине установлен определенный список RPM и что они конкретной версии или новее.

Вот что у меня есть на данный момент:

#!/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);

Я нашел то, что кажется возможным решением, но не могу понять, как настроить код, соответствующий моему сценарию.

посмотреть здесь: http://www.perlmonks.org/bare/?node=240384

Я не могу использовать RPM :: VersionSort или несколько других модулей, связанных с RPM, из-за ограничений, о которых я упоминал выше.

Любая помощь будет очень признательна.

Спасибо!

Некоторые подсказки

Вам не нужен grep, например.

rpm -q radvd
radvd-1.9.2-9.el7.x86_64
echo $?
0

Если в пакете отсутствует $? 1

rpm -q nc 
package nc is not installed
echo $?
1

Вы можете получить версию установленного пакета rpm, используя --queryformat

rpm -q radvd --queryformat "%{VERSION}\n"
1.9.2

Вы можете сделать гораздо больше, используя только rpm - загляните на сайт rpm.org.

Возможно, вы даже сможете обойтись без использования perl, поэтому взгляните на ответ Денниса здесь на SO.

Хотя это не отвечает на мой первоначальный вопрос, я хотел бы рассказать, что у меня получилось. Мне удалось убедить власть предержащих разрешить мне установить модуль RPM :: VersionSort Perl. Так что это не чистое решение Perl, как я надеялся найти.

Вот что я сейчас использую для всех, кому интересно:

#!/usr/bin/perl

use strict;
use warnings;
use RPM::VersionSort;

my $cmd;
my $cmdResults;
my %installedRPMs; #This will hold a list of all the RPMs from the baseRPMs list that ARE currently installed on the machine.
my @missingRPMs; #This will hold a list of all the RPMs from the baseRPMs list that ARE NOT installed on the system.
my %baseRPMs; #This is the list of RPMs that should be installed on the system and their corresponding version numbers.

%baseRPMs = ("bwm-ng" => "0.6-6.el6.2",
        "celt051" => "0.5.1.3-0.el6",
        "device-mapper-multipath" => "0.4.9-87.el6",
        "device-mapper-multipath-libs" => "0.4.9-87.el6",
        "dhcp" => "4.1.1-49.P1.el6.centos",
        "dhcp-common" => "4.1.1-49.P1.el6.centos", 
        "ebtables" => "2.0.9-6.el6",
        "freeglut" => "2.6.0-1.el6",
        "glusterfs-api" => "3.4.0.57rhs-1.el6_5",
        "glusterfs-libs" => "3.4.0.57rhs-1.el6_5",
        "gnutls-utils" => "3.8.5-18.el6",
        "gpm" => "1.20.6-12.el6",
        "hmaccalc" => "0.9.12-2.el6",
        "iftop" => "1.0-0.7.pre4.el6",
        "iperf" => "2.0.5-11.el6",
        "ipsec-tools" => "0.8.0-25.3",
        "iptraf" => "3.0.1-14.el6",
        "iscsi-initiator-utils" => "6.2.0.873-14.el6",
        "libsysfs" => "2.1.0-7.el6",
        "lm_sensors" => "3.1.1-17.el6",
        "lm_sensors-libs" => "3.1.1-17.el6",
        "log4cpp" => "1.0-13.el6_5.1",
        "lrzsz" => "0.12.20-27.1.el6",
        "lzop" => "1.02-0.9.rc1.el6",
        "mcsctrans" => "0.3.1-4.el6",
        "minicom" => "2.3-6.1.el6",
        "nc" => "1.84-24.el6",
        "netcf-libs" => "0.2.4-3.el6",
        "net-snmp" => "5.5-54.el6",
        "net-snmp-libs" => "5.5-54.el6",
        "net-snmp-utils" => "5.5-54.el6",
        "omping" => "0.0.4-1.el6",
        "perl-AppConfig" => "1.66-6.el6",
        "perl-Pod-POM" => "0.25-2.el6",
        "perl-Template-Toolkit" => "2.22-5.el6",
        "pimd" => "2.3.0-1",
        "python-lxml" => "2.2.3-1.1.el6",
        "quagga" => "0.99.23.1-2014082501",
        "radvd" => "1.6-1.el6",
        "smcroute" => "2.0.0-0",
        "usbredir" => "0.5.1-2.el6",
        "yajl" => "1.0.7-3.el6",
    );

print "The following RPMs and version numbers will be checked against this system:\n";
foreach(keys %baseRPMs){
    print "\t" . $_ . ": " . %baseRPMs($_) . "\n";
}

print "Press any key to continue.";
<STDIN>;

#Loop through the %baseRPMs list and build both the %installedRPMs list as well as the @missingRPMs list.
for my $pkg (keys %baseRPMs){
    $cmd = "rpm -q " . $pkg . " --queryformat \"%{VERSION}-%{RELEASE}\"";
    $cmdResults = `$cmd`;
    if ($cmdResults =~ /not installed/) {
        push @missingRPMs, $pkg;
    } else {
        $installedRPMs{$pkg} = $cmdResults;
    }
}

#Loop through the %installedRPMs list and verify their version numbers against the %baseRPMs list.
foreach (keys %installedRPMs){
    if (exists $baseRPMs{$_}){
        print "Expected: " . $_ . ": " . $baseRPMs{$_} .  "\n";
        print "Installed: " . $_ . ": " . $installedRPMs{$_} .  "\n";
        if (rpmvercmp($installedRPMs{$_}, $baseRPMs{$_}) < 0 ) {
            print "RESULT: !!FAIL!! " . $_ . " version is OLDER than the specified version in the Functional Test Plan.\n";
        } else {
            print "RESULT: PASS. " . $_ . " version is equal to or newer than the specified version in the Functional Test Plan. \n";
        }
        print "-----------------------------------------------------------------------------------------------------\n\n";
    }
}

#Print the list of @missingRPMs.
if (@missingRPMs){
    print "The following RPMs are NOT installed as defined by the Functional Test Plan:\n";
    foreach(@missingRPMs){
        print "\t" . $_ . "\n";
    }
    print "\n*Any missing RPMs indicates the system is NOT built as defined by the Functional Test Plan.*\n";
}

print "\n";

exit(0)

;