mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Load librpm on demand for IPAVersion
ctypes.util.find_library() is costly and slows down startup of ipa CLI. ipaplatform.redhat.tasks now defers loading of librpm until its needed. CFFI has been replaced with ctypes, too. See: https://pagure.io/freeipa/issue/6851 Signed-off-by: Christian Heimes <cheimes@redhat.com> Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
@@ -25,6 +25,7 @@ system tasks.
|
|||||||
'''
|
'''
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import ctypes
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
@@ -36,7 +37,6 @@ from ctypes.util import find_library
|
|||||||
from functools import total_ordering
|
from functools import total_ordering
|
||||||
from subprocess import CalledProcessError
|
from subprocess import CalledProcessError
|
||||||
|
|
||||||
from cffi import FFI
|
|
||||||
from pyasn1.error import PyAsn1Error
|
from pyasn1.error import PyAsn1Error
|
||||||
from six.moves import urllib
|
from six.moves import urllib
|
||||||
|
|
||||||
@@ -50,15 +50,6 @@ from ipaplatform.base.tasks import BaseTaskNamespace
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
_ffi = FFI()
|
|
||||||
_ffi.cdef("""
|
|
||||||
int rpmvercmp (const char *a, const char *b);
|
|
||||||
""")
|
|
||||||
|
|
||||||
# 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"))
|
|
||||||
|
|
||||||
|
|
||||||
def selinux_enabled():
|
def selinux_enabled():
|
||||||
"""
|
"""
|
||||||
@@ -78,6 +69,21 @@ def selinux_enabled():
|
|||||||
|
|
||||||
@total_ordering
|
@total_ordering
|
||||||
class IPAVersion(object):
|
class IPAVersion(object):
|
||||||
|
_rpmvercmp_func = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _rpmvercmp(cls, a, b):
|
||||||
|
"""Lazy load and call librpm's rpmvercmp
|
||||||
|
"""
|
||||||
|
rpmvercmp_func = cls._rpmvercmp_func
|
||||||
|
if rpmvercmp_func is None:
|
||||||
|
librpm = ctypes.CDLL(find_library('rpm'))
|
||||||
|
rpmvercmp_func = librpm.rpmvercmp
|
||||||
|
# int rpmvercmp(const char *a, const char *b)
|
||||||
|
rpmvercmp_func.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
|
||||||
|
rpmvercmp_func.restype = ctypes.c_int
|
||||||
|
cls._rpmvercmp_func = rpmvercmp_func
|
||||||
|
return rpmvercmp_func(a, b)
|
||||||
|
|
||||||
def __init__(self, version):
|
def __init__(self, version):
|
||||||
self._version = version
|
self._version = version
|
||||||
@@ -90,12 +96,12 @@ class IPAVersion(object):
|
|||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not isinstance(other, IPAVersion):
|
if not isinstance(other, IPAVersion):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
return _librpm.rpmvercmp(self._bytes, other._bytes) == 0
|
return self._rpmvercmp(self._bytes, other._bytes) == 0
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
if not isinstance(other, IPAVersion):
|
if not isinstance(other, IPAVersion):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
return _librpm.rpmvercmp(self._bytes, other._bytes) < 0
|
return self._rpmvercmp(self._bytes, other._bytes) < 0
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self._version)
|
return hash(self._version)
|
||||||
|
|||||||
28
ipatests/test_ipaplatform/test_tasks.py
Normal file
28
ipatests/test_ipaplatform/test_tasks.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2017 FreeIPA Contributors see COPYING for license
|
||||||
|
#
|
||||||
|
|
||||||
|
from ipaplatform.tasks import tasks
|
||||||
|
|
||||||
|
|
||||||
|
def test_ipa_version():
|
||||||
|
v3 = tasks.parse_ipa_version('3.0')
|
||||||
|
assert v3.version == u'3.0'
|
||||||
|
if hasattr(v3, '_rpmvercmp'):
|
||||||
|
assert v3._rpmvercmp_func is None
|
||||||
|
v3._rpmvercmp(b'1', b'2')
|
||||||
|
assert v3._rpmvercmp_func is not None
|
||||||
|
|
||||||
|
v4 = tasks.parse_ipa_version('4.0')
|
||||||
|
assert v4.version == u'4.0'
|
||||||
|
if hasattr(v4, '_rpmvercmp'):
|
||||||
|
assert v4._rpmvercmp_func is not None
|
||||||
|
|
||||||
|
assert v3 < v4
|
||||||
|
assert v3 <= v4
|
||||||
|
assert v3 <= v3
|
||||||
|
assert v3 != v4
|
||||||
|
assert v3 == v3
|
||||||
|
assert not v3 == v4
|
||||||
|
assert v4 > v3
|
||||||
|
assert v4 >= v3
|
||||||
Reference in New Issue
Block a user