mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 07:33:27 -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:
parent
b7293a9184
commit
b82a2295b8
@ -25,6 +25,7 @@ system tasks.
|
||||
'''
|
||||
from __future__ import print_function
|
||||
|
||||
import ctypes
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
@ -36,7 +37,6 @@ from ctypes.util import find_library
|
||||
from functools import total_ordering
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
from cffi import FFI
|
||||
from pyasn1.error import PyAsn1Error
|
||||
from six.moves import urllib
|
||||
|
||||
@ -50,15 +50,6 @@ from ipaplatform.base.tasks import BaseTaskNamespace
|
||||
|
||||
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():
|
||||
"""
|
||||
@ -78,6 +69,21 @@ def selinux_enabled():
|
||||
|
||||
@total_ordering
|
||||
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):
|
||||
self._version = version
|
||||
@ -90,12 +96,12 @@ class IPAVersion(object):
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, IPAVersion):
|
||||
return NotImplemented
|
||||
return _librpm.rpmvercmp(self._bytes, other._bytes) == 0
|
||||
return self._rpmvercmp(self._bytes, other._bytes) == 0
|
||||
|
||||
def __lt__(self, other):
|
||||
if not isinstance(other, IPAVersion):
|
||||
return NotImplemented
|
||||
return _librpm.rpmvercmp(self._bytes, other._bytes) < 0
|
||||
return self._rpmvercmp(self._bytes, other._bytes) < 0
|
||||
|
||||
def __hash__(self):
|
||||
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
|
Loading…
Reference in New Issue
Block a user