From 5386802ebc96ef0c2bc4a3bfa260ee83a6d7fe5f Mon Sep 17 00:00:00 2001
From: David Kupka <dkupka@redhat.com>
Date: Tue, 2 Aug 2016 08:16:30 +0200
Subject: [PATCH] schema: Generate bits for help load them on request
Store name, summary, topic_topic and exclude in single entry in cache
for all commands. These data are needed for help and storing and
loading them together allows fast help response.
https://fedorahosted.org/freeipa/ticket/6048
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
---
ipaclient/remote_plugins/schema.py | 54 +++++++++++++++++++++++++++++---------
1 file changed, 42 insertions(+), 12 deletions(-)
diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
index d7c018e3de1cc79ffc086e3576542ce993ebc87a..5264d4cc177ba457c517f93f203e0baca7b0ac01 100644
--- a/ipaclient/remote_plugins/schema.py
+++ b/ipaclient/remote_plugins/schema.py
@@ -23,7 +23,7 @@ from ipapython.dn import DN
from ipapython.dnsutil import DNSName
from ipapython.ipa_log_manager import log_mgr
-FORMAT = '0'
+FORMAT = '1'
if six.PY3:
unicode = str
@@ -113,9 +113,11 @@ class _SchemaPlugin(object):
if self._class is not None:
return self._class.summary
else:
- if self.doc is not None:
- return self.doc.split('\n\n', 1)[0].strip()
- else:
+ self._schema.load_help()
+ schema = self._schema[self.schema_key][self.full_name]
+ try:
+ return schema['summary']
+ except KeyError:
return u'<%s>' % self.full_name
def _create_default_from(self, api, name, keys):
@@ -241,6 +243,7 @@ class _SchemaCommandPlugin(_SchemaPlugin):
if self._class is not None:
return self._class.topic
else:
+ self._schema.load_help()
schema = self._schema[self.schema_key][self.full_name]
try:
return str(schema['topic_topic']).partition('/')[0]
@@ -252,6 +255,7 @@ class _SchemaCommandPlugin(_SchemaPlugin):
if self._class is not None:
return self._class.NO_CLI
else:
+ self._schema.load_help()
schema = self._schema[self.schema_key][self.full_name]
return 'cli' in schema.get('exclude', [])
@@ -432,7 +436,6 @@ class Schema(object):
"""
namespaces = {'classes', 'commands', 'topics'}
- schema_info_path = 'schema'
_DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'schema')
def __init__(self, api, server_info, client):
@@ -488,8 +491,7 @@ class Schema(object):
if fmt != FORMAT:
raise RuntimeError('invalid format')
- schema_info = json.loads(schema.read(self.schema_info_path))
- return schema_info['fingerprint']
+ return json.loads(schema.read('fingerprint'))
def _fetch(self, client):
if not client.isconnected():
@@ -522,6 +524,7 @@ class Schema(object):
else:
fp = schema['fingerprint']
ttl = schema.pop('ttl', 0)
+ schema.pop('version', None)
for key, value in schema.items():
if key in self.namespaces:
@@ -534,8 +537,6 @@ class Schema(object):
def _read_schema(self):
with self._open_schema(self._fingerprint, 'r') as schema:
self._dict['fingerprint'] = self._get_schema_fingerprint(schema)
- schema_info = json.loads(schema.read(self.schema_info_path))
- self._dict['version'] = schema_info['version']
for name in schema.namelist():
ns, _slash, key = name.partition('/')
@@ -548,6 +549,27 @@ class Schema(object):
except KeyError:
return self._dict[key]
+ def _generate_help(self, schema):
+ halp = {}
+
+ for namespace in ('commands', 'topics'):
+ halp[namespace] = {}
+
+ for member_schema in schema[namespace].values():
+ member_full_name = member_schema['full_name']
+
+ topic = halp[namespace].setdefault(member_full_name, {})
+ topic['name'] = member_schema['name']
+ if 'doc' in member_schema:
+ topic['summary'] = (
+ member_schema['doc'].split('\n\n', 1)[0].strip())
+ if 'topic_topic' in member_schema:
+ topic['topic_topic'] = member_schema['topic_topic']
+ if 'exclude' in member_schema:
+ topic['exclude'] = member_schema['exclude']
+
+ return halp
+
def _write_schema(self):
try:
os.makedirs(self._DIR)
@@ -557,7 +579,6 @@ class Schema(object):
return
with self._open_schema(self._fingerprint, 'w') as schema:
- schema_info = {}
for key, value in self._dict.items():
if key in self.namespaces:
ns = value
@@ -565,9 +586,10 @@ class Schema(object):
path = '{}/{}'.format(key, member)
schema.writestr(path, json.dumps(ns[member]))
else:
- schema_info[key] = value
+ schema.writestr(key, json.dumps(value))
- schema.writestr(self.schema_info_path, json.dumps(schema_info))
+ schema.writestr('_help',
+ json.dumps(self._generate_help(self._dict)))
def _read(self, path):
with self._open_schema(self._fingerprint, 'r') as zf:
@@ -587,6 +609,14 @@ class Schema(object):
def iter_namespace(self, namespace):
return iter(self._dict[namespace])
+ def load_help(self):
+ if not self._help:
+ self._help = self._read('_help')
+
+ for ns in self._help:
+ for member in self._help[ns]:
+ self._dict[ns][member].update(self._help[ns][member])
+
def get_package(api, client):
try:
--
2.7.4