On 01/08/2016 02:14 PM, Jan Cholasta wrote:
On 8.1.2016 14:09, Martin Basti wrote:


On 08.01.2016 14:00, Martin Kosek wrote:
On 01/08/2016 01:45 PM, Martin Basti wrote:
Hello all,

fix for ticket https://fedorahosted.org/freeipa/ticket/5535
requires to import rpm module

This import somehow breaks nsslib in IPA
https://fedorahosted.org/freeipa/ticket/5572


We have 2 ways how to fix it:

1) move import rpm to body of methods (attached patch)
We are not sure how stable is this solution.

2) use solution with rpmdevtools proposed here:
https://www.redhat.com/archives/freeipa-devel/2016-January/msg00092.html

This should be rock stable but it needs many dependencies (rpm-python
too, perl)

The second way looks safer, so I would like to reimplement it, do you
all agree
or do you have better idea?
Feedback welcome, please ASAP.

Martin^2
Since it's Friday, I invested 15 minutes to practice my C skills and
use the
python-cffi library to call rpm rpmvercmp library call directly
(attached):

$ python rpm.py 4.2.0-15.el7 4.2.0-15.el7_2.3
4.2.0-15.el7 < 4.2.0-15.el7_2.3

This would not introduce any additional dependency besides rpm-devel,
right? :-)

Not rpm-devel, but rpm-libs (you should dlopen "librpm.so.3").

I'm afraid that this can cause the same issue as import rpm, because the
nsslib is used from C library

I would be surprised if NSS was used in this particular function.


If it would work then we could compare version like in this quickly hacked and untested patch.

--
Martin^3 Babinsky
From 32ebf02d38b7174816f81579aab6ebbe26e80f64 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Fri, 8 Jan 2016 14:17:14 +0100
Subject: [PATCH] use rpmvercmp via python-cffi for version comparison

---
 ipaplatform/redhat/tasks.py | 45 ++++++++++++++-------------------------------
 1 file changed, 14 insertions(+), 31 deletions(-)

diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
index a0b4060..66ca3ad 100644
--- a/ipaplatform/redhat/tasks.py
+++ b/ipaplatform/redhat/tasks.py
@@ -36,7 +36,7 @@ from subprocess import CalledProcessError
 from nss.error import NSPRError
 from pyasn1.error import PyAsn1Error
 from six.moves import urllib
-import rpm
+from cffi import FFI
 
 from ipapython.ipa_log_manager import root_logger, log_mgr
 from ipapython import ipautil
@@ -49,33 +49,16 @@ from ipaplatform.redhat.authconfig import RedHatAuthConfig
 from ipaplatform.base.tasks import BaseTaskNamespace
 
 
-# copied from rpmUtils/miscutils.py
-def stringToVersion(verstring):
-    if verstring in [None, '']:
-        return (None, None, None)
-    i = verstring.find(':')
-    if i != -1:
-        try:
-            epoch = str(long(verstring[:i]))
-        except ValueError:
-            # look, garbage in the epoch field, how fun, kill it
-            epoch = '0' # this is our fallback, deal
-    else:
-        epoch = '0'
-    j = verstring.find('-')
-    if j != -1:
-        if verstring[i + 1:j] == '':
-            version = None
-        else:
-            version = verstring[i + 1:j]
-        release = verstring[j + 1:]
-    else:
-        if verstring[i + 1:] == '':
-            version = None
-        else:
-            version = verstring[i + 1:]
-        release = None
-    return (epoch, version, release)
+def compare_rpm_versions(ver1, ver2):
+    ffi = FFI()
+    ffi.cdef("""
+int rpmvercmp (const char *a, const char *b);
+""")
+    C = ffi.dlopen("rpmlib.so.3")
+    arg1 = ffi.new("char[]", ver1)
+    arg2 = ffi.new("char[]", ver2)
+
+    return C.rpmvercmp(arg1, arg2)
 
 
 log = log_mgr.get_logger(__name__)
@@ -101,15 +84,15 @@ def selinux_enabled():
 class IPAVersion(object):
 
     def __init__(self, version):
-        self.version_tuple = stringToVersion(version)
+        self.version = version
 
     def __eq__(self, other):
         assert isinstance(other, IPAVersion)
-        return rpm.labelCompare(self.version_tuple, other.version_tuple) == 0
+        return compare_rpm_versions(self.version, other.version) == 0
 
     def __lt__(self, other):
         assert isinstance(other, IPAVersion)
-        return rpm.labelCompare(self.version_tuple, other.version_tuple) == -1
+        return compare_rpm_versions(self.version, other.version) == -1
 
 
 class RedHatTaskNamespace(BaseTaskNamespace):
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to