diff options
author | Martin Babinsky <mbabinsk@redhat.com> | 2016-01-11 16:22:40 +0100 |
---|---|---|
committer | Jan Cholasta <jcholast@redhat.com> | 2016-01-11 17:54:36 +0100 |
commit | 7cd99e852053710c64dcb66cd5b15fc8ed4da5de (patch) | |
tree | d6ba908f1c4d824644ad19e27ea3f68dea2e5b3a | |
parent | bc6543efae9bb1bf7c5e792e30b1ea396607f57e (diff) | |
download | freeipa-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.in | 2 | ||||
-rw-r--r-- | ipaplatform/redhat/tasks.py | 44 |
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): |