On 14.12.2015 09:24, Martin Kosek wrote:
On 12/14/2015 07:21 AM, Jan Cholasta wrote:
On 11.12.2015 19:01, Tomas Babej wrote:

On 12/11/2015 09:36 AM, Martin Kosek wrote:
On 12/10/2015 05:09 PM, Martin Basti wrote:

On 10.12.2015 15:49, Tomas Babej wrote:
On 12/10/2015 11:23 AM, Martin Basti wrote:
On 10.12.2015 09:13, Lukas Slebodnik wrote:
On (09/12/15 19:22), Martin Basti wrote:
https://fedorahosted.org/freeipa/ticket/5535

Patch attached.
>From 8ef93485d61e8732166fb0c5b6c4559209740f3e Mon Sep 17 00:00:00
2001
From: Martin Basti <mba...@redhat.com>
Date: Wed, 9 Dec 2015 18:53:35 +0100
Subject: [PATCH] Fix version comparison

Use RPM library to compare vendor versions of IPA for redhat platform

https://fedorahosted.org/freeipa/ticket/5535
---
freeipa.spec.in             |  2 ++
ipaplatform/redhat/tasks.py | 19 +++++++++++++++++++
2 files changed, 21 insertions(+)

diff --git a/freeipa.spec.in b/freeipa.spec.in
index
9f82b3695fb10c4db65cc31278364b3b34e26098..09feba7b8324f5e645da3e8010de86b6c3ee5ab9



100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -166,6 +166,8 @@ Requires: %{etc_systemd_dir}
Requires: gzip
Requires: python-gssapi >= 1.1.0
Requires: custodia
+Requires: rpm-python
+Requires: rpmdevtools
Could you explain why do you need the 2nd package?
It does not contains any python modules
and I cannot see usage of any binary in this patch

LS
Thanks for this catch, it is actually located in yum package, I rather
copy stringToVersion function from there to IPA, to avoid dependency
hell

Updated patch attached.


Looking good. The __cmp__ function, however, is not available in Python
3. As we will eventually support python3 in RHEL as well, maybe we
should make sure even platform-dependent parts are python3 compatible?
For the future's sake.

Tomas

Thanks,

python 3 compatible patch attached.
I wonder why we have to add so much code here and reimplement RPM
version checking if it is already provided by rpmdevtools:

~~~
$ /usr/bin/rpmdev-vercmp ipa-4.2.0-15.el7 4.2.0-15.el7_2.3; echo $?
WARNING: hyphen in release1: 4.2.0-15.el7

rpmdev-vercmp <epoch1> <ver1> <release1> <epoch2> <ver2> <release2>
rpmdev-vercmp <EVR1> <EVR2>
rpmdev-vercmp # with no arguments, prompt

Exit status is 0 if the EVR's are equal, 11 if EVR1 is newer, and 12 if
EVR2
is newer.  Other exit statuses indicate problems.

ipa-4.2.0-15.el7 < 4.2.0-15.el7_2.3
12
~~~

which could be directly called from __eq__ or __lt__, since we are in
platform specific code anyway already.

Martin
Imho we should generally prefer reaching out to a Python library rather
launching a subprocess to compare the versions, it's unnecessary overhead.
I would not be too worried about miliseconds longer execution on a function
called during RPM upgrade.

That said, the main argument for the usage of rpm-python over
rpmdevtools I see is that rpm-python is very likely to be present on the
system (i.e. it is yum's own dependency), while rpmdevtools will not be
present by default.

  From the standpoint of trying to minimize the size of freeipa
installation (i.e recent wget -> curl migration), we should keep the
spirit here and do not introduce a dependency for a collection of
developer tools.

/2 cents
+1, also a single function is hardly "much code".
Ok then. If you all want to add yet another N-V-R parsing function in the
FreeIPA code, I can live with it (with raised eyebrows though).

Rebased patch attached.
From c15bb5a71a8a1fb065b4ffdaee0de0554569ec9f Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Wed, 9 Dec 2015 18:53:35 +0100
Subject: [PATCH] Fix version comparison

Use RPM library to compare vendor versions of IPA for redhat platform

https://fedorahosted.org/freeipa/ticket/5535
---
 freeipa.spec.in             |  1 +
 ipaplatform/redhat/tasks.py | 53 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/freeipa.spec.in b/freeipa.spec.in
index 09bd62a4f8ad7fd739d7422750bc0054a3afef9d..4002666df1952af59115da7f36386afc580f2ff4 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -204,6 +204,7 @@ Requires: python-pyasn1
 Requires: dbus-python
 Requires: python-dns >= 1.11.1
 Requires: python-kdcproxy >= 0.3
+Requires: rpm-python
 
 %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 94d2cb4e906965a20bcfdd55f38854005091c26f..c90e55f28cd492d43a98e4e0ee0476a23db8a099 100644
--- a/ipaplatform/redhat/tasks.py
+++ b/ipaplatform/redhat/tasks.py
@@ -30,11 +30,13 @@ import stat
 import socket
 import sys
 import base64
+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
@@ -47,6 +49,35 @@ 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)
+
+
 log = log_mgr.get_logger(__name__)
 
 
@@ -66,6 +97,21 @@ def selinux_enabled():
         return False
 
 
+@total_ordering
+class IPAVersion(object):
+
+    def __init__(self, version):
+        self.version_tuple = stringToVersion(version)
+
+    def __eq__(self, other):
+        assert isinstance(other, IPAVersion)
+        return rpm.labelCompare(self.version_tuple, other.version_tuple) == 0
+
+    def __lt__(self, other):
+        assert isinstance(other, IPAVersion)
+        return rpm.labelCompare(self.version_tuple, other.version_tuple) == -1
+
+
 class RedHatTaskNamespace(BaseTaskNamespace):
 
     def restore_context(self, filepath, restorecon=paths.SBIN_RESTORECON):
@@ -423,5 +469,12 @@ class RedHatTaskNamespace(BaseTaskNamespace):
         super(RedHatTaskNamespace, self).create_system_user(name, group,
             homedir, shell, uid, gid, comment, create_homedir)
 
+    def parse_ipa_version(self, version):
+        """
+        :param version: textual version
+        :return: object implementing proper __cmp__ method for version compare
+        """
+        return IPAVersion(version)
+
 
 tasks = RedHatTaskNamespace()
-- 
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