Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I compare Rpm versions in python

Tags:

python

regex

rpm

I'm trying to find out how I can compare 2 lists of RPMS (Currently installed) and (Available in local repository) and see which RPMS are out of date. I've been tinkering with regex but there are so many different naming standards for RPMS that i can't get a good list to work with. I don't have the actual RPMS on my drive so i can't do rpm -qif.

pattern1 = re.compile(r'^([a-zA-Z0-9_\-\+]*)-([a-zA-Z0-9_\.]*)-([a-zA-Z0-9_\.]*)\.(.*)')
for rpm in listOfRpms:
     packageInfo = pattern1.search(rpm[0]).groups()
     print packageInfo

This works for a vast majority but not all (2300 / 2400)

  yum-metadata-parser-1.1.2-2.el5
('yum-metadata-parser', '1.1.2', '2', 'el5') **What I need

But none these work for instance unless I break some others that worked before..

  • wvdial-1.54.0-3
  • xdelta-1.1.3-20
  • xdelta-1.1.3-20_2
  • xmlsec1-1.2.6-3
  • xmlsec1-1.2.6-3_2
  • ypbind-1.17.2-13
  • ypbind-1.17.2-8
  • ypserv-2.13-14
  • zip-2.3-27
  • zlib-1.2.3-3
  • zlib-1.2.3-3_2
  • zsh-4.2.6-1
like image 896
Adam Avatar asked Jul 08 '10 17:07

Adam


2 Answers

RPM has python bindings, which lets you use rpmUtils.miscutils.compareEVR. The first and third arguments of the tuple are the package name and the packaging version. The middle is the version. In the example below, I'm trying to figure out where 3.7.4a gets sorted.

[root@rhel56 ~]# python
Python 2.4.3 (#1, Dec 10 2010, 17:24:35) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import rpmUtils.miscutils
>>> rpmUtils.miscutils.compareEVR(("foo", "3.7.4", "1"), ("foo", "3.7.4", "1"))
0
>>> rpmUtils.miscutils.compareEVR(("foo", "3.7.4", "1"), ("foo", "3.7.4a", "1")) 
-1
>>> rpmUtils.miscutils.compareEVR(("foo", "3.7.4a", "1"), ("foo", "3.7.4", "1")) 
1
like image 95
Philip Z Avatar answered Sep 25 '22 22:09

Philip Z


Here's a working program based off of rpmdev-vercmp from the rpmdevtools package. You shouldn't need anything special installed but yum (which provides the rpmUtils.miscutils python module) for it to work.

The advantage over the other answers is you don't need to parse anything out, just feed it full RPM name-version strings like:

$ ./rpmcmp.py bash-3.2-32.el5_9.1 bash-3.2-33.el5.1
0:bash-3.2-33.el5.1 is newer
$ echo $?
12

Exit status 11 means the first one is newer, 12 means the second one is newer.

#!/usr/bin/python

import rpm
import sys
from rpmUtils.miscutils import stringToVersion

if len(sys.argv) != 3:
    print "Usage: %s <rpm1> <rpm2>"
    sys.exit(1)

def vercmp((e1, v1, r1), (e2, v2, r2)):
    return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))

(e1, v1, r1) = stringToVersion(sys.argv[1])
(e2, v2, r2) = stringToVersion(sys.argv[2])

rc = vercmp((e1, v1, r1), (e2, v2, r2))
if rc > 0:
    print "%s:%s-%s is newer" % (e1, v1, r1)
    sys.exit(11)

elif rc == 0:
    print "These are equal"
    sys.exit(0)

elif rc < 0:
    print "%s:%s-%s is newer" % (e2, v2, r2)
    sys.exit(12)
like image 30
Steve Kehlet Avatar answered Sep 25 '22 22:09

Steve Kehlet