From 7bec8a246d6712f749ec331f5bf066e3357c4ce7 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Aug 19 2016 13:34:26 +0000 Subject: 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 Reviewed-By: Martin Basti --- diff --git a/freeipa.spec.in b/freeipa.spec.in index ea580a2..d55ab4f 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -873,6 +873,8 @@ mkdir -p %{buildroot}%{_sysconfdir}/cron.d mkdir -p %{buildroot}%{_sysconfdir}/ipa/custodia +mkdir -p %{buildroot}%{_usr}/share/ipa/schema.d + %endif # ONLY_CLIENT @@ -1250,7 +1252,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 df0a92f..f927a7a 100644 --- a/ipaplatform/base/paths.py +++ b/ipaplatform/base/paths.py @@ -355,6 +355,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 f29737f..26cd246 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -27,6 +27,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 fbe49bb..aec84dc 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -1818,6 +1818,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: