URL: https://github.com/freeipa/freeipa/pull/397
Author: tiran
 Title: #397: Improve wheel building and provide ipaserver wheel for local 
testing
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/397/head:pr397
git checkout pr397
From 1075a7a2db5fa9fd6016daf49d77f80c38bd9ce5 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Tue, 17 Jan 2017 08:49:54 +0100
Subject: [PATCH 1/5] Conditionally import pyhbac

The pyhbac module is part of SSSD. It's not available as stand-alone
PyPI package. It would take a lot of effort to package it because the
code is deeply tight into SSSD.

Let's follow the example of other SSSD Python packages and make the
import of pyhbac conditionally. It's only necessary for caacl and
hbactest plugins.

I renamed convert_to_ipa_rule() to _convert_to_ipa_rule() because it
does not check for presence of pyhbac package itself. The check is
performed earlier in execute(). The prefix indicates that it is an
internal function and developers have to think twice before using it
in another place.

This makes it much easier to install ipaserver with instrumented build
of Python with a different ABI or in isolated virtual envs to profile
and debug the server.

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipaserver/plugins/caacl.py    | 11 ++++++++++-
 ipaserver/plugins/hbactest.py | 19 ++++++++++++++++---
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/ipaserver/plugins/caacl.py b/ipaserver/plugins/caacl.py
index a7817c4..691f4e9 100644
--- a/ipaserver/plugins/caacl.py
+++ b/ipaserver/plugins/caacl.py
@@ -2,7 +2,6 @@
 # Copyright (C) 2015  FreeIPA Contributors see COPYING for license
 #
 
-import pyhbac
 import six
 
 from ipalib import api, errors, output
@@ -17,6 +16,11 @@
 from ipalib import _, ngettext
 from ipapython.dn import DN
 
+try:
+    import pyhbac
+except ImportError:
+    pyhbac = None
+
 if six.PY3:
     unicode = str
 
@@ -152,6 +156,11 @@ def _acl_make_rule(principal_type, obj):
 
 
 def acl_evaluate(principal_type, principal, ca_id, profile_id):
+    if pyhbac is None:
+        raise errors.ValidationError(
+            name=_('missing pyhbac'),
+            error=_('pyhbac is not available on the server.')
+        )
     req = _acl_make_request(principal_type, principal, ca_id, profile_id)
     acls = api.Command.caacl_find(no_members=False)['result']
     rules = [_acl_make_rule(principal_type, obj) for obj in acls]
diff --git a/ipaserver/plugins/hbactest.py b/ipaserver/plugins/hbactest.py
index 626e894..e156568 100644
--- a/ipaserver/plugins/hbactest.py
+++ b/ipaserver/plugins/hbactest.py
@@ -29,9 +29,14 @@
     except ImportError:
         _dcerpc_bindings_installed = False
 
-import pyhbac
 import six
 
+try:
+    import pyhbac
+except ImportError:
+    pyhbac = None
+
+
 if six.PY3:
     unicode = str
 
@@ -210,7 +215,7 @@
 
 register = Registry()
 
-def convert_to_ipa_rule(rule):
+def _convert_to_ipa_rule(rule):
     # convert a dict with a rule to an pyhbac rule
     ipa_rule = pyhbac.HbacRule(rule['cn'][0])
     ipa_rule.enabled = rule['ipaenabledflag'][0]
@@ -309,6 +314,14 @@ def canonicalize(self, host):
         return host
 
     def execute(self, *args, **options):
+        if pyhbac is None:
+            raise errors.ValidationError(
+                name=_('missing pyhbac'),
+                error=_(
+                    'pyhbac is not available on the server.'
+                )
+            )
+
         # First receive all needed information:
         # 1. HBAC rules (whether enabled or disabled)
         # 2. Required options are (user, target host, service)
@@ -356,7 +369,7 @@ def execute(self, *args, **options):
         # --disabled will import all disabled rules
         # --rules will implicitly add the rules from a rule list
         for rule in hbacset:
-            ipa_rule = convert_to_ipa_rule(rule)
+            ipa_rule = _convert_to_ipa_rule(rule)
             if ipa_rule.name in testrules:
                 ipa_rule.enabled = True
                 rules.append(ipa_rule)

From c2a5039f71e3e3ba434a13be32a0159446bdd38c Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Tue, 17 Jan 2017 08:57:33 +0100
Subject: [PATCH 2/5] Add extra_requires for additional dependencies

ipaserver did not have extra_requires to state additional dependencies.

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipaserver/setup.py | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/ipaserver/setup.py b/ipaserver/setup.py
index 95ba5eb..acdae5a 100755
--- a/ipaserver/setup.py
+++ b/ipaserver/setup.py
@@ -60,12 +60,6 @@
             "pyldap",
             "python-nss",
             "six",
-            # not available on PyPI
-            # "python-libipa_hbac",
-            # "python-sss",
-            # "python-sss-murmur",
-            # "python-SSSDConfig",
-            # "samba-python",
         ],
         entry_points={
             'custodia.authorizers': [
@@ -75,4 +69,12 @@
                 'IPASecStore = ipaserver.secrets.store:IPASecStore',
             ],
         },
+        extras_require={
+            # These packages are currently not available on PyPI.
+            "caacl": ["pyhbac"],
+            "dcerpc": ["samba", "pysss", "pysss_nss_idmap"],
+            "hbactest": ["pyhbac"],
+            "install": ["SSSDConfig"],
+            "trust": ["pysss_murmur", "pysss_nss_idmap"],
+        }
     )

From 2561e03d39da444e227460ce83a587e657993138 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Tue, 17 Jan 2017 12:16:25 +0100
Subject: [PATCH 3/5] Add an option to build ipaserver wheels

To create a wheel bundle with ipaserver and its dependencies:

    make wheel_bundle IPA_SERVER_WHEELS=1

To include additional dependencies:

    make wheel_bundle IPA_EXTRA_WHEELS=ipatests[webui]

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 Makefile.am    | 20 +++++++++++++++++---
 configure.ac   |  6 ++++++
 ipasetup.py.in |  3 ++-
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index a35d18f..18d4871 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,7 +13,6 @@ IPACLIENT_SUBDIRS = ipaclient ipalib ipapython
 SUBDIRS = asn1 util client contrib po \
 	$(IPACLIENT_SUBDIRS) ipaplatform $(IPATESTS_SUBDIRS) $(SERVER_SUBDIRS)
 
-
 MOSTLYCLEANFILES = ipasetup.pyc ipasetup.pyo \
 		   ignore_import_errors.pyc ignore_import_errors.pyo \
 		   ipasetup.pyc ipasetup.pyo \
@@ -210,6 +209,14 @@ jslint-html:
 WHEELDISTDIR = $(top_builddir)/dist/wheels
 WHEELBUNDLEDIR = $(top_builddir)/dist/bundle
 
+@MK_IFEQ@ ($(IPA_SERVER_WHEELS),1)
+    IPA_WHEEL_PACKAGES @MK_ASSIGN@ $(IPACLIENT_SUBDIRS) ipaplatform ipaserver
+    IPA_OMIT_INSTALL @MK_ASSIGN@ 0
+@MK_ELSE@
+    IPA_WHEEL_PACKAGES @MK_ASSIGN@ $(IPACLIENT_SUBDIRS)
+    IPA_OMIT_INSTALL @MK_ASSIGN@ 1
+@MK_ENDIF@
+
 $(WHEELDISTDIR):
 	mkdir -p $(WHEELDISTDIR)
 
@@ -217,12 +224,19 @@ $(WHEELBUNDLEDIR):
 	mkdir -p $(WHEELBUNDLEDIR)
 
 bdist_wheel: $(WHEELDISTDIR)
-	for dir in $(IPACLIENT_SUBDIRS); do \
+	rm -f $(foreach item,$(IPA_WHEEL_PACKAGES) ipatests,$(WHEELDISTDIR)/$(item)-*.whl)
+	export IPA_OMIT_INSTALL=$(IPA_OMIT_INSTALL); \
+	for dir in $(IPA_WHEEL_PACKAGES) ipatests; do \
 	    $(MAKE) $(AM_MAKEFLAGS) -C $${dir} $@ || exit 1; \
 	done
 
 wheel_bundle: $(WHEELBUNDLEDIR) bdist_wheel
-	$(PYTHON) -m pip wheel --wheel-dir $(WHEELBUNDLEDIR) $(WHEELDISTDIR)/*.whl
+	rm -f $(foreach item,$(IPA_WHEEL_PACKAGES) ipatests,$(WHEELBUNDLEDIR)/$(item)-*.whl)
+	$(PYTHON) -m pip wheel \
+	    --find-links $(WHEELDISTDIR) \
+	    --find-links $(WHEELBUNDLEDIR) \
+	    --wheel-dir $(WHEELBUNDLEDIR) \
+		$(IPA_WHEEL_PACKAGES) $(IPA_EXTRA_WHEELS)
 
 .PHONY:
 strip-po:
diff --git a/configure.ac b/configure.ac
index 9ee281a..978f7c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -311,6 +311,12 @@ AC_SUBST([GIT_VERSION], [IPA_GIT_VERSION])
 # used by Makefile.am for files depending on templates
 AC_SUBST([CONFIG_STATUS])
 
+# workaround for syntax clash between make and automake
+AC_SUBST([MK_IFEQ], [ifeq])
+AC_SUBST([MK_ELSE], [else])
+AC_SUBST([MK_ENDIF], [endif])
+AC_SUBST([MK_ASSIGN], [=])
+
 dnl ---------------------------------------------------------------------------
 dnl Finish
 dnl ---------------------------------------------------------------------------
diff --git a/ipasetup.py.in b/ipasetup.py.in
index 915f0ed..8564a72 100644
--- a/ipasetup.py.in
+++ b/ipasetup.py.in
@@ -29,7 +29,8 @@ class build_py(setuptools_build_py):
 
     def finalize_options(self):
         setuptools_build_py.finalize_options(self)
-        if 'bdist_wheel' in self.distribution.commands:
+        omit = os.environ.get('IPA_OMIT_INSTALL', '0')
+        if omit == '1':
             distname = self.distribution.metadata.name
             self.skip_package = '{}.install'.format(distname)
             log.warn("bdist_wheel: Ignore package: %s",

From f3a9059501381a7a9a7a2e348541bae6f9de40cf Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Tue, 21 Feb 2017 17:13:12 +0100
Subject: [PATCH 4/5] caacl does not depend on pyhbac

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipaserver/setup.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/ipaserver/setup.py b/ipaserver/setup.py
index acdae5a..ddc86d8 100755
--- a/ipaserver/setup.py
+++ b/ipaserver/setup.py
@@ -71,7 +71,6 @@
         },
         extras_require={
             # These packages are currently not available on PyPI.
-            "caacl": ["pyhbac"],
             "dcerpc": ["samba", "pysss", "pysss_nss_idmap"],
             "hbactest": ["pyhbac"],
             "install": ["SSSDConfig"],

From ab6d1f1e4173025b4c1f1d16aedcce7488edb631 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Thu, 23 Feb 2017 10:00:05 +0100
Subject: [PATCH 5/5] hbactest: raise SkipPluginModule when pyhbac is not
 available

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipaserver/plugins/caacl.py    |  2 +-
 ipaserver/plugins/hbactest.py | 10 +---------
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/ipaserver/plugins/caacl.py b/ipaserver/plugins/caacl.py
index 691f4e9..87a2b06 100644
--- a/ipaserver/plugins/caacl.py
+++ b/ipaserver/plugins/caacl.py
@@ -159,7 +159,7 @@ def acl_evaluate(principal_type, principal, ca_id, profile_id):
     if pyhbac is None:
         raise errors.ValidationError(
             name=_('missing pyhbac'),
-            error=_('pyhbac is not available on the server.')
+            error=_('pyhbac is not installed.')
         )
     req = _acl_make_request(principal_type, principal, ca_id, profile_id)
     acls = api.Command.caacl_find(no_members=False)['result']
diff --git a/ipaserver/plugins/hbactest.py b/ipaserver/plugins/hbactest.py
index e156568..9c39b9a 100644
--- a/ipaserver/plugins/hbactest.py
+++ b/ipaserver/plugins/hbactest.py
@@ -34,7 +34,7 @@
 try:
     import pyhbac
 except ImportError:
-    pyhbac = None
+    raise errors.SkipPluginModule(reason=_('pyhbac is not installed.'))
 
 
 if six.PY3:
@@ -314,14 +314,6 @@ def canonicalize(self, host):
         return host
 
     def execute(self, *args, **options):
-        if pyhbac is None:
-            raise errors.ValidationError(
-                name=_('missing pyhbac'),
-                error=_(
-                    'pyhbac is not available on the server.'
-                )
-            )
-
         # First receive all needed information:
         # 1. HBAC rules (whether enabled or disabled)
         # 2. Required options are (user, target host, service)
-- 
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