From faf3810a64f329adae8ff7cda46806afa1e0a68c Mon Sep 17 00:00:00 2001 From: Ilias Stamatis Date: Wed, 2 Aug 2017 16:58:48 +0300 Subject: [PATCH] Issue 46 - dsconf support for dynamic schema reload Description: Add dsconf support for dynamically reloading schema. Notes: Created new-style Schema sub-class of DSLdapObject. https://pagure.io/lib389/issue/46 Author: Ilias95 Review by: ??? --- lib389/cli_conf/schema.py | 17 ++++++++++++++--- lib389/schema.py | 22 ++++++++++++++++++++++ lib389/tasks.py | 7 +++++++ lib389/tests/schema_test.py | 13 ++++++++++++- 4 files changed, 55 insertions(+), 4 deletions(-) mode change 100644 => 100755 lib389/schema.py diff --git a/lib389/cli_conf/schema.py b/lib389/cli_conf/schema.py index 0e1f2a4..105e4d6 100644 --- a/lib389/cli_conf/schema.py +++ b/lib389/cli_conf/schema.py @@ -6,9 +6,9 @@ # See LICENSE for details. # --- END COPYRIGHT BLOCK --- -import argparse - from lib389.cli_base import _get_arg +from lib389.schema import SchemaNew + def list_attributetype(inst, basedn, log, args): for attributetype in inst.schema.get_attributetypes(): @@ -16,7 +16,7 @@ def list_attributetype(inst, basedn, log, args): def query_attributetype(inst, basedn, log, args): # Need the query type - attr = _get_arg( args.attr , msg="Enter attribute to query" ) + attr = _get_arg(args.attr, msg="Enter attribute to query") attributetype, must, may = inst.schema.query_attributetype(attr) print(attributetype) print("") @@ -28,6 +28,14 @@ def query_attributetype(inst, basedn, log, args): for oc in may: print(oc) +def reload_schema(inst, basedn, log, args): + schema = SchemaNew(inst) + log.info('Attempting to add task entry... This will fail if Schema Reload plug-in is not enabled.') + task = schema.reload(args.schemadir) + log.info('Successfully added task entry ' + task.dn) + log.info("To verify that the schema reload operation was successful, please check the error logs.") + + def create_parser(subparsers): schema_parser = subparsers.add_parser('schema', help='Query and manipulate schema') @@ -40,3 +48,6 @@ def create_parser(subparsers): query_attributetype_parser.set_defaults(func=query_attributetype) query_attributetype_parser.add_argument('attr', nargs='?', help='Attribute type to query') + reload_parser = subcommands.add_parser('reload', help='Dynamically reload schema while server is running') + reload_parser.set_defaults(func=reload_schema) + reload_parser.add_argument('-d', '--schemadir', help="directory where schema files are located") diff --git a/lib389/schema.py b/lib389/schema.py old mode 100644 new mode 100755 index 6e7f65c..bed4a45 --- a/lib389/schema.py +++ b/lib389/schema.py @@ -13,8 +13,30 @@ import glob import ldap from ldap.schema.models import AttributeType, ObjectClass, MatchingRule + from lib389._constants import * +from lib389._constants import DN_SCHEMA from lib389.utils import ds_is_newer +from lib389._mapped_object import DSLdapObject +from lib389.tasks import SchemaReloadTask + + +class SchemaNew(DSLdapObject): + def __init__(self, instance, batch=False): + super(SchemaNew, self).__init__(instance=instance, batch=batch) + self._dn = DN_SCHEMA + self._rdn_attribute = 'cn' + + def reload(self, schema_dir=None): + task = SchemaReloadTask(self._instance) + + task_properties = {} + if schema_dir is not None: + task_properties['schemadir'] = schema_dir + + task.create(properties=task_properties) + + return task class Schema(object): diff --git a/lib389/tasks.py b/lib389/tasks.py index 2c62dce..ec46145 100644 --- a/lib389/tasks.py +++ b/lib389/tasks.py @@ -90,6 +90,13 @@ class USNTombstoneCleanupTask(Task): return super(USNTombstoneCleanupTask, self)._validate(rdn, properties, basedn) +class SchemaReloadTask(Task): + def __init__(self, instance, dn=None, batch=False): + self.cn = 'schema_reload_' + Task._get_task_date() + dn = "cn=" + self.cn + ",cn=schema reload task," + DN_TASKS + + super(SchemaReloadTask, self).__init__(instance, dn, batch) + class Tasks(object): proxied_methods = 'search_s getEntry'.split() diff --git a/lib389/tests/schema_test.py b/lib389/tests/schema_test.py index 20c5a13..9b6b238 100644 --- a/lib389/tests/schema_test.py +++ b/lib389/tests/schema_test.py @@ -7,8 +7,10 @@ # --- END COPYRIGHT BLOCK --- # import pytest -from lib389._constants import * + from lib389 import DirSrv +from lib389._constants import SER_HOST, SER_PORT, SER_SERVERID_PROP, LOCALHOST +from lib389.schema import SchemaNew INSTANCE_PORT = 54321 INSTANCE_SERVERID = 'standalone' @@ -53,9 +55,18 @@ def test_schema(topology): assert topology.instance.schema.query_objectclass('account').names == \ ('account', ) +def test_schema_reload(topology): + """Test that the appropriate task entry is created when reloading schema.""" + schema = SchemaNew(topology.instance) + task = schema.reload() + assert task.exists() + task.wait() + assert task.get_exit_code() == 0 + if __name__ == '__main__': # Run isolated # -s for DEBUG mode + import os CURRENT_FILE = os.path.realpath(__file__) pytest.main("-s %s" % CURRENT_FILE) -- 2.13.3