[Freeipa-devel] [PATCH 0214] Support schema files for external plugins
Alexander Bokovoy
abokovoy at redhat.com
Mon Aug 8 10:26:26 UTC 2016
On Mon, 08 Aug 2016, Alexander Bokovoy wrote:
>Hi!
>
>Attached patch is what is needed to allow external plugins for FreeIPA
>framework to be functional if they need to extend a schema.
>
>The idea is that we would have a separate directory as
>/usr/share/ipa/schema.d and will allow to use schema (*.ldif) files from
>it and its subdirectories during install and upgrade stages.
>
>Without the patch only selected schema files from /usr/share/ipa are
>used during install and upgrade. This leads to a failure to install IPA
>server (or upgrade it) if a new plugin is added. If plugin defines
>managed permissions, upgrade tool will generate ACIs which will fail to
>be inserted into LDAP store due to references to missing attributes and
>object classes.
>
>The patch adds a directory to be installed and a helper utility that
>loads files from the directory and adds them to the list of schema files
>used during update of dsinstance and upgrade of the server.
>
>With this patch I'm successfully managed to make FleetCommander
>integration plugin completely independent of FreeIPA.
Patch attached now. ;)
--
/ Alexander Bokovoy
-------------- next part --------------
From 045c7b38c387c362358d1ac2aa19a6fe07d18be5 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Fri, 5 Aug 2016 13:04:19 +0300
Subject: [PATCH 3/5] support schema files from third-party plugins
Allow upgrade process to include schema files from third-party plugins
installed in /usr/share/ipa/schema.d/*.schema.
The directory /usr/shar/eipa/schema.d is owned by the server-common
subpackage and therefore third-party plugins should depend on
freeipa-server-common (ipa-server-common) package in their package
dependencies.
Resolves: https://fedorahosted.org/freeipa/ticket/5864
---
freeipa.spec.in | 5 ++++-
install/configure.ac | 1 +
install/share/Makefile.am | 1 +
install/share/schema.d/Makefile.am | 16 ++++++++++++++++
install/share/schema.d/README | 14 ++++++++++++++
ipaplatform/base/paths.py | 1 +
ipaserver/install/dsinstance.py | 15 ++++++++++++++-
ipaserver/install/server/upgrade.py | 3 +++
8 files changed, 54 insertions(+), 2 deletions(-)
create mode 100644 install/share/schema.d/Makefile.am
create mode 100644 install/share/schema.d/README
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 135e9c9..8acb3fc 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -871,6 +871,8 @@ mkdir -p %{buildroot}%{_sysconfdir}/cron.d
mkdir -p %{buildroot}%{_sysconfdir}/ipa/custodia
+mkdir -p %{buildroot}%{_usr}/share/ipa/schema.d
+
%endif # ONLY_CLIENT
@@ -1248,7 +1250,8 @@ fi
%ghost %{_localstatedir}/lib/ipa/pki-ca/publish
%ghost %{_localstatedir}/named/dyndb-ldap/ipa
%dir %attr(0700,root,root) %{_sysconfdir}/ipa/custodia
-
+%dir %{_usr}/share/ipa/schema.d
+%attr(0644,root,root) %{_usr}/share/ipa/schema.d/README
%files server-dns
%defattr(-,root,root,-)
diff --git a/install/configure.ac b/install/configure.ac
index b5f77bf..81f17b9 100644
--- a/install/configure.ac
+++ b/install/configure.ac
@@ -88,6 +88,7 @@ AC_CONFIG_FILES([
share/advise/Makefile
share/advise/legacy/Makefile
share/profiles/Makefile
+ share/schema.d/Makefile
ui/Makefile
ui/css/Makefile
ui/src/Makefile
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index cd1c164..d8845ee 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -3,6 +3,7 @@ NULL =
SUBDIRS = \
advise \
profiles \
+ schema.d \
$(NULL)
appdir = $(IPA_DATA_DIR)
diff --git a/install/share/schema.d/Makefile.am b/install/share/schema.d/Makefile.am
new file mode 100644
index 0000000..0fef87f
--- /dev/null
+++ b/install/share/schema.d/Makefile.am
@@ -0,0 +1,16 @@
+NULL =
+
+SUBDIRS = \
+ $(NULL)
+
+appdir = $(IPA_DATA_DIR)/schema.d
+app_DATA = README \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(app_DATA) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in
diff --git a/install/share/schema.d/README b/install/share/schema.d/README
new file mode 100644
index 0000000..19e3e68
--- /dev/null
+++ b/install/share/schema.d/README
@@ -0,0 +1,14 @@
+This directory is indended to store schema files for 3rd-party plugins.
+
+Each schema file should be named NN-description.ldif where NN is a number 00..90.
+
+The schema files from this directory are merged together with the core IPA
+schema files during the run of ipa-server-upgrade utility. Therefore, they are
+also installed when upgrade happens within the process of ipa-server-install.
+
+The directory is installed as /usr/share/ipa/schema.d and is owned by a
+freeipa-server-common package. Therefore, a 3rd-party plugin would need to
+depend on the freeipa-server-common package if it delivers the schema file(s).
+
+You may place your schema files in a subdirectory too, the code that loads
+schema files processes recursively all subdirectories of schema.d.
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index b1fedf5..fff55a3 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -354,6 +354,7 @@ class BasePathNamespace(object):
IPA_CUSTODIA_SOCKET = '/run/httpd/ipa-custodia.sock'
IPA_CUSTODIA_AUDIT_LOG = '/var/log/ipa-custodia.audit.log'
IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab'
+ EXTERNAL_SCHEMA_DIR = '/usr/share/ipa/schema.d'
@property
def USER_CACHE_PATH(self):
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index c93b3b4..4d372ee 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -28,6 +28,7 @@ import re
import time
import tempfile
import stat
+import fnmatch
import ldap
@@ -180,6 +181,16 @@ def get_domain_level(api=api):
return int(entry.single_value['ipaDomainLevel'])
+def get_all_external_schema_files(root):
+ """Get all schema files"""
+ f = []
+ for path, subdirs, files in os.walk(root):
+ for name in files:
+ if fnmatch.fnmatch(name, "*.ldif"):
+ f.append(os.path.join(path, name))
+ return f
+
+
INF_TEMPLATE = """
[General]
FullMachineName= $FQDN
@@ -656,7 +667,9 @@ class DsInstance(service.Service):
conn.unbind()
def apply_updates(self):
- data_upgrade = upgradeinstance.IPAUpgrade(self.realm)
+ schema_files = get_all_external_schema_files(paths.EXTERNAL_SCHEMA_DIR)
+ data_upgrade = upgradeinstance.IPAUpgrade(self.realm,
+ schema_files=schema_files)
try:
data_upgrade.create_instance()
except Exception as e:
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 4342717..2d6b8cb 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1817,6 +1817,9 @@ def upgrade():
realm = api.env.realm
schema_files = [os.path.join(ipautil.SHARE_DIR, f) for f
in dsinstance.ALL_SCHEMA_FILES]
+
+ schema_files.extend(dsinstance.get_all_external_schema_files(
+ paths.EXTERNAL_SCHEMA_DIR))
data_upgrade = IPAUpgrade(realm, schema_files=schema_files)
try:
--
2.7.4
More information about the Freeipa-devel
mailing list