summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Babinsky <mbabinsk@redhat.com>2016-01-11 16:22:40 +0100
committerJan Cholasta <jcholast@redhat.com>2016-01-11 17:54:36 +0100
commit7cd99e852053710c64dcb66cd5b15fc8ed4da5de (patch)
treed6ba908f1c4d824644ad19e27ea3f68dea2e5b3a
parentbc6543efae9bb1bf7c5e792e30b1ea396607f57e (diff)
downloadfreeipa-7cd99e852053710c64dcb66cd5b15fc8ed4da5de.tar.gz
freeipa-7cd99e852053710c64dcb66cd5b15fc8ed4da5de.tar.xz
freeipa-7cd99e852053710c64dcb66cd5b15fc8ed4da5de.zip
use FFI call to rpmvercmp function for version comparison
Stop using rpm-python to compare package versions since the implicit NSS initialization upon the module import breaks NSS handling in IPA code. Call rpm-libs C-API function via CFFI instead. Big thanks to Martin Kosek <mkosek@redhat.com> for sharing the code snippet that spurred this patch. https://fedorahosted.org/freeipa/ticket/5572 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-rw-r--r--freeipa.spec.in2
-rw-r--r--ipaplatform/redhat/tasks.py44
2 files changed, 13 insertions, 33 deletions
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 7e956538d..de3ae2f03 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -214,7 +214,7 @@ Requires: python-pyasn1
Requires: dbus-python
Requires: python-dns >= 1.11.1
Requires: python-kdcproxy >= 0.3
-Requires: rpm-python
+Requires: rpm-libs
%description -n python2-ipaserver
IPA is an integrated solution to provide centrally managed Identity (users,
diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
index a0b4060cb..638048679 100644
--- a/ipaplatform/redhat/tasks.py
+++ b/ipaplatform/redhat/tasks.py
@@ -30,13 +30,14 @@ import stat
import socket
import sys
import base64
+from cffi import FFI
+from ctypes.util import find_library
from functools import total_ordering
from subprocess import CalledProcessError
from nss.error import NSPRError
from pyasn1.error import PyAsn1Error
from six.moves import urllib
-import rpm
from ipapython.ipa_log_manager import root_logger, log_mgr
from ipapython import ipautil
@@ -48,35 +49,14 @@ from ipaplatform.paths import paths
from ipaplatform.redhat.authconfig import RedHatAuthConfig
from ipaplatform.base.tasks import BaseTaskNamespace
+_ffi = FFI()
+_ffi.cdef("""
+int rpmvercmp (const char *a, const char *b);
+""")
-# 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)
-
+# use ctypes loader to get correct librpm.so library version according to
+# https://cffi.readthedocs.org/en/latest/overview.html#id8
+_librpm = _ffi.dlopen(find_library("rpm"))
log = log_mgr.get_logger(__name__)
@@ -101,15 +81,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 _librpm.rpmvercmp(self.version, other.version) == 0
def __lt__(self, other):
assert isinstance(other, IPAVersion)
- return rpm.labelCompare(self.version_tuple, other.version_tuple) == -1
+ return _librpm.rpmvercmp(self.version, other.version) < 0
class RedHatTaskNamespace(BaseTaskNamespace):