[PATCH 0/3] Allow plugin use kimchi s ui handler

This series of patches reorganize kimchi's path vars generation code to allow plugin use kimchi s ui handler. Mark Wu (3): Reorganize the kimchi's paths gereneration code Add test cases for paths generation code Allow plugin use kimchi's ui handler src/kimchi/cachebust.py | 4 +- src/kimchi/config.py.in | 164 ++++++++++++++++++++---------------------------- src/kimchi/root.py | 39 +++++++----- src/kimchi/server.py | 14 +++-- src/kimchi/template.py | 17 +++-- src/kimchi/utils.py | 6 +- src/kimchid.in | 7 ++- tests/test_config.py | 73 +++++++++++++++++++++ tests/test_plugin.py | 4 +- 9 files changed, 196 insertions(+), 132 deletions(-) create mode 100644 tests/test_config.py -- 1.8.4.2

This patch reorganizes kimchi's paths generation code to make the user of path vars can work with both kimchi root app and plugin app. Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com> --- src/kimchi/cachebust.py | 4 +- src/kimchi/config.py.in | 164 ++++++++++++++++++++---------------------------- src/kimchi/root.py | 6 +- src/kimchi/server.py | 10 +-- src/kimchi/template.py | 14 +++-- src/kimchi/utils.py | 6 +- src/kimchid.in | 7 ++- tests/test_plugin.py | 4 +- 8 files changed, 100 insertions(+), 115 deletions(-) diff --git a/src/kimchi/cachebust.py b/src/kimchi/cachebust.py index 9a71f4f..7844695 100644 --- a/src/kimchi/cachebust.py +++ b/src/kimchi/cachebust.py @@ -23,11 +23,11 @@ import os -from kimchi.config import get_prefix +from kimchi.config import paths def href(url): # for error.html, url is absolute path - f = os.path.join(get_prefix(), 'ui', url.lstrip("/")) + f = os.path.join(paths.ui_dir, url.lstrip("/")) mtime = os.path.getmtime(f) return "%s?cacheBust=%s" % (url, mtime) diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in index 22fe614..53c8e42 100644 --- a/src/kimchi/config.py.in +++ b/src/kimchi/config.py.in @@ -28,7 +28,6 @@ import platform from ConfigParser import SafeConfigParser -from glob import iglob from kimchi.xmlutils import xpath_get_text @@ -37,86 +36,24 @@ from kimchi.xmlutils import xpath_get_text DEFAULT_LOG_LEVEL = "debug" -def get_prefix(): - if __file__[0] == '/': - base = os.path.dirname(__file__) - else: - base = os.path.dirname('./%s' % __file__) - - if os.access('%s/../../src/kimchi/config.py' % base, os.F_OK): - return '%s/../..' % base - else: - return '@pkgdatadir@' - - -def without_installation(): - return get_prefix() != '@pkgdatadir@' - - -def get_config_dir(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return '@sysconfdir@/kimchi' - else: - return os.path.join(prefix, 'src') - - -def _get_kimchi_src_dir(): - prefix = get_prefix() - return ('@kimchidir@' if prefix == '@pkgdatadir@' - else os.path.join(prefix, 'src/kimchi')) - - -def get_api_schema_file(): - return os.path.join(_get_kimchi_src_dir(), 'API.json') - - -def get_default_log_dir(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return "@localstatedir@/log/kimchi" - - return os.path.join(prefix, 'log') - - -def get_state_path(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return "@localstatedir@/lib/kimchi" - - return os.path.join(prefix, 'data') - - def get_session_path(): - return os.path.join(get_state_path(), 'sessions') + return os.path.join(paths.state_dir, 'sessions') def get_object_store(): - return os.path.join(get_prefix(), 'data', 'objectstore') + return os.path.join(paths.state_dir, 'objectstore') def get_distros_store(): - return os.path.join(get_config_dir(), 'distros.d') - - -def get_template_path(resource): - return '%s/ui/pages/%s.tmpl' % (get_prefix(), resource) + return os.path.join(paths.conf_dir, 'distros.d') def get_screenshot_path(): - return "%s/data/screenshots" % get_prefix() - + return os.path.join(paths.state_dir, 'screenshots') -def get_mo_path(): - return '%s/mo' % get_prefix() - -def get_support_language(): - mopath = "%s/*" % get_mo_path() - return [path.rsplit('/', 1)[1] for path in iglob(mopath)] +def get_debugreports_path(): + return os.path.join(paths.state_dir, 'debugreports') def find_qemu_binary(): @@ -137,37 +74,74 @@ def find_qemu_binary(): return location -def get_debugreports_path(): - return os.path.join(get_prefix(), 'data', 'debugreports') +class Paths(object): + + def __init__(self): + self.prefix = self.get_prefix() + self.installed = (self.prefix == '@pkgdatadir@') + + if self.installed: + self.state_dir = '@localstatedir@/lib/kimchi' + self.log_dir = '@localstatedir@/log/kimchi' + self.conf_dir = '@sysconfdir@/kimchi' + self.src_dir = '@kimchidir@' + self.plugins_dir = '@kimchidir@' + else: + self.state_dir = self.add_prefix('data') + self.log_dir = self.add_prefix('log') + self.conf_dir = self.add_prefix('src') + self.src_dir = self.add_prefix('src/kimchi') + self.plugins_dir = self.add_prefix('plugins') + + self.ui_dir = self.add_prefix('ui') + self.mo_dir = self.add_prefix('mo') + + def get_prefix(self): + if __file__[0] == '/': + base = os.path.dirname(__file__) + else: + base = os.path.dirname('./%s' % __file__) + + if os.access('%s/../../src/kimchi/config.py' % base, os.F_OK): + return os.path.abspath('%s/../..' % base) + else: + return '@pkgdatadir@' + + def add_prefix(self, subdir): + return os.path.join(self.prefix, subdir) + + def get_template_path(self, resource): + return os.path.join(self.ui_dir, 'pages/%s.tmpl' % resource) + + +paths = Paths() + +class PluginPaths(Paths): -def get_plugins_dir(): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - prefix = '@kimchidir@' - return os.path.join(prefix, 'plugins') + def __init__(self, name): + super(PluginPaths, self).__init__() + self.plugin_dir = os.path.join('plugins', name) + if self.installed: + self.conf_dir = '@sysconfdir@/kimchi/plugins.d' + self.src_dir = os.path.join('@kimchidir@', self.plugin_dir) + else: + self.conf_dir = self.add_prefix(self.plugin_dir) + self.src_dir = self.add_prefix(self.plugin_dir) -def get_plugin_config(name): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - base_dir = '@sysconfdir@/kimchi/plugins.d/' - else: - base_dir = os.path.join(prefix, 'plugins') - return os.path.join(base_dir, '%s/%s.conf' % (name, name)) + self.ui_dir = self.add_prefix(os.path.join(self.plugin_dir, 'ui')) + self.mo_dir = self.add_prefix(os.path.join(self.plugin_dir, 'mo')) + self.conf_file = os.path.join(self.conf_dir, '%s.conf' % name) -def _get_plugin_ui_dir(name): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - base_dir = '@pkgdatadir@/plugins/' - else: - base_dir = os.path.join(prefix, 'plugins') - return os.path.join(base_dir, '%s/ui' % name) +_plugin_paths = {} -def get_plugin_tab_xml(name): - return os.path.join(_get_plugin_ui_dir(name), 'config/tab-ext.xml') +def plugin_paths(plugin_name): + if plugin_name not in _plugin_paths: + _plugin_paths[plugin_name] = PluginPaths(plugin_name) + return _plugin_paths[plugin_name] def _get_config(): @@ -180,12 +154,12 @@ def _get_config(): config.set("server", "ssl_key", "") config.set("server", "environment", "development") config.add_section("logging") - config.set("logging", "log_dir", get_default_log_dir()) + config.set("logging", "log_dir", paths.log_dir) config.set("logging", "log_level", DEFAULT_LOG_LEVEL) config.add_section("display") config.set("display", "display_proxy_port", "64667") - config_file = os.path.join(get_config_dir(), 'kimchi.conf') + config_file = os.path.join(paths.conf_dir, 'kimchi.conf') if os.path.exists(config_file): config.read(config_file) return config @@ -195,4 +169,4 @@ config = _get_config() if __name__ == '__main__': - print get_prefix() + print paths.prefix diff --git a/src/kimchi/root.py b/src/kimchi/root.py index 3cc6321..ae9fd0e 100644 --- a/src/kimchi/root.py +++ b/src/kimchi/root.py @@ -23,11 +23,12 @@ import cherrypy import json +import os from kimchi import auth from kimchi import template -from kimchi.config import get_api_schema_file +from kimchi.config import paths from kimchi.control.base import Resource from kimchi.control.config import Config from kimchi.control.debugreports import DebugReports @@ -67,7 +68,8 @@ class Root(Resource): self.host = Host(model) self.debugreports = DebugReports(model) self.plugins = Plugins(model) - self.api_schema = json.load(open(get_api_schema_file())) + self.api_schema = json.load(open(os.path.join(paths.src_dir, + 'API.json'))) def error_production_handler(self, status, message, traceback, version): data = {'code': status, 'reason': message} diff --git a/src/kimchi/server.py b/src/kimchi/server.py index b820263..58b082b 100644 --- a/src/kimchi/server.py +++ b/src/kimchi/server.py @@ -33,6 +33,7 @@ from kimchi import config from kimchi import model from kimchi import mockmodel from kimchi import vnc +from kimchi.config import paths, plugin_paths from kimchi.root import Root from kimchi.utils import get_enabled_plugins, import_class @@ -63,8 +64,8 @@ class Server(object): CACHEEXPIRES = 31536000 configObj = { '/': {'tools.trailing_slash.on': False, - 'tools.staticdir.root': config.get_prefix(), - 'tools.staticfile.root': config.get_prefix(), + 'tools.staticdir.root': paths.prefix, + 'tools.staticfile.root': paths.prefix, 'request.methods_with_bodies': ('POST', 'PUT'), 'tools.nocache.on': True, 'tools.sessions.on': True, @@ -211,7 +212,8 @@ class Server(object): plugin_config['/ui/config/tab-ext.xml'] = { 'tools.staticfile.on': True, 'tools.staticfile.filename': - config.get_plugin_tab_xml(plugin_name), + os.path.join(plugin_paths(plugin_name).ui_dir, + 'config/tab-ext.xml'), 'tools.nocache.on': True} except KeyError: continue @@ -233,7 +235,7 @@ class Server(object): cert = options.ssl_cert key = options.ssl_key if not cert or not key: - config_dir = config.get_config_dir() + config_dir = paths.conf_dir cert = '%s/kimchi-cert.pem' % config_dir key = '%s/kimchi-key.pem' % config_dir diff --git a/src/kimchi/template.py b/src/kimchi/template.py index 1f19c4a..1740997 100644 --- a/src/kimchi/template.py +++ b/src/kimchi/template.py @@ -28,9 +28,10 @@ import os from Cheetah.Template import Template +from glob import iglob -from kimchi import config +from kimchi.config import paths def get_lang(): @@ -54,8 +55,13 @@ def get_lang(): return langs +def get_support_languages(): + mopath = "%s/*" % paths.mo_dir + return [path.rsplit('/', 1)[1] for path in iglob(mopath)] + + def validate_language(langs): - supportLangs = config.get_support_language() + supportLangs = get_support_languages() for lang in langs: if lang in supportLangs: return lang @@ -88,12 +94,12 @@ def render(resource, data): separators=(',', ':'), encoding='iso-8859-1') elif can_accept_html(): - filename = config.get_template_path(resource) + filename = paths.get_template_path(resource) try: params = {'data': data} lang = validate_language(get_lang()) gettext_conf = {'domain': 'kimchi', - 'localedir': config.get_mo_path(), + 'localedir': paths.mo_dir, 'lang': [lang]} params['lang'] = gettext_conf return Template(file=filename, searchList=params).respond() diff --git a/src/kimchi/utils.py b/src/kimchi/utils.py index 5d6e8ea..7077b3b 100644 --- a/src/kimchi/utils.py +++ b/src/kimchi/utils.py @@ -28,10 +28,10 @@ import urllib2 from cherrypy.lib.reprconf import Parser +from kimchi.config import paths, plugin_paths from kimchi.exception import TimeoutExpired -from kimchi import config from threading import Timer @@ -48,7 +48,7 @@ def is_digit(value): def _load_plugin_conf(name): - plugin_conf = config.get_plugin_config(name) + plugin_conf = plugin_paths(name).conf_file if not os.path.exists(plugin_conf): cherrypy.log.error_log.error("Plugin configuration file %s" " doesn't exist." % plugin_conf) @@ -62,7 +62,7 @@ def _load_plugin_conf(name): def get_enabled_plugins(): - plugin_dir = config.get_plugins_dir() + plugin_dir = paths.plugins_dir try: dir_contents = os.listdir(plugin_dir) except OSError: diff --git a/src/kimchid.in b/src/kimchid.in index 548fa52..eebc017 100644 --- a/src/kimchid.in +++ b/src/kimchid.in @@ -30,12 +30,13 @@ sys.path.insert(1, '@pythondir@') import kimchi.server import kimchi.config -if kimchi.config.without_installation(): - sys.path.append(kimchi.config.get_prefix()) -from kimchi.config import config +from kimchi.config import config, paths from optparse import OptionParser +if not paths.installed: + sys.path.append(paths.prefix) + ACCESS_LOG = "kimchi-access.log" ERROR_LOG = "kimchi-error.log" diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 42c87a9..e5c9053 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -32,7 +32,7 @@ from functools import partial import kimchi.mockmodel import kimchi.server import utils -from kimchi import config +from kimchi.config import paths test_server = None @@ -48,7 +48,7 @@ def setUpModule(): host = '127.0.0.1' port = utils.get_free_port('http') ssl_port = None - sys.path.append(config.get_prefix()) + sys.path.append(paths.prefix) test_server = utils.run_server(host, port, ssl_port, test_mode=True, model=model) -- 1.8.4.2

Reviewed-by: Crístian Viana <vianac@linux.vnet.ibm.com> Am 22-01-2014 03:48, schrieb Mark Wu:
This patch reorganizes kimchi's paths generation code to make the user of path vars can work with both kimchi root app and plugin app.
Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com>

On 01/22/2014 03:48 AM, Mark Wu wrote:
This patch reorganizes kimchi's paths generation code to make the user of path vars can work with both kimchi root app and plugin app.
Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com> --- src/kimchi/cachebust.py | 4 +- src/kimchi/config.py.in | 164 ++++++++++++++++++++---------------------------- src/kimchi/root.py | 6 +- src/kimchi/server.py | 10 +-- src/kimchi/template.py | 14 +++-- src/kimchi/utils.py | 6 +- src/kimchid.in | 7 ++- tests/test_plugin.py | 4 +- 8 files changed, 100 insertions(+), 115 deletions(-)
diff --git a/src/kimchi/cachebust.py b/src/kimchi/cachebust.py index 9a71f4f..7844695 100644 --- a/src/kimchi/cachebust.py +++ b/src/kimchi/cachebust.py @@ -23,11 +23,11 @@ import os
-from kimchi.config import get_prefix +from kimchi.config import paths
def href(url): # for error.html, url is absolute path - f = os.path.join(get_prefix(), 'ui', url.lstrip("/")) + f = os.path.join(paths.ui_dir, url.lstrip("/")) mtime = os.path.getmtime(f) return "%s?cacheBust=%s" % (url, mtime) diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in index 22fe614..53c8e42 100644 --- a/src/kimchi/config.py.in +++ b/src/kimchi/config.py.in @@ -28,7 +28,6 @@ import platform
from ConfigParser import SafeConfigParser -from glob import iglob
from kimchi.xmlutils import xpath_get_text @@ -37,86 +36,24 @@ from kimchi.xmlutils import xpath_get_text DEFAULT_LOG_LEVEL = "debug"
-def get_prefix(): - if __file__[0] == '/': - base = os.path.dirname(__file__) - else: - base = os.path.dirname('./%s' % __file__) - - if os.access('%s/../../src/kimchi/config.py' % base, os.F_OK): - return '%s/../..' % base - else: - return '@pkgdatadir@' - - -def without_installation(): - return get_prefix() != '@pkgdatadir@' - - -def get_config_dir(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return '@sysconfdir@/kimchi' - else: - return os.path.join(prefix, 'src') - - -def _get_kimchi_src_dir(): - prefix = get_prefix() - return ('@kimchidir@' if prefix == '@pkgdatadir@' - else os.path.join(prefix, 'src/kimchi')) - - -def get_api_schema_file(): - return os.path.join(_get_kimchi_src_dir(), 'API.json') - - -def get_default_log_dir(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return "@localstatedir@/log/kimchi" - - return os.path.join(prefix, 'log') - - -def get_state_path(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return "@localstatedir@/lib/kimchi" - - return os.path.join(prefix, 'data') - - def get_session_path(): - return os.path.join(get_state_path(), 'sessions') + return os.path.join(paths.state_dir, 'sessions')
def get_object_store(): - return os.path.join(get_prefix(), 'data', 'objectstore') + return os.path.join(paths.state_dir, 'objectstore')
def get_distros_store(): - return os.path.join(get_config_dir(), 'distros.d') - - -def get_template_path(resource): - return '%s/ui/pages/%s.tmpl' % (get_prefix(), resource) + return os.path.join(paths.conf_dir, 'distros.d')
def get_screenshot_path(): - return "%s/data/screenshots" % get_prefix() - + return os.path.join(paths.state_dir, 'screenshots')
-def get_mo_path(): - return '%s/mo' % get_prefix()
- -def get_support_language(): - mopath = "%s/*" % get_mo_path() - return [path.rsplit('/', 1)[1] for path in iglob(mopath)] +def get_debugreports_path(): + return os.path.join(paths.state_dir, 'debugreports')
def find_qemu_binary(): @@ -137,37 +74,74 @@ def find_qemu_binary(): return location
-def get_debugreports_path(): - return os.path.join(get_prefix(), 'data', 'debugreports') +class Paths(object): + + def __init__(self): + self.prefix = self.get_prefix() + self.installed = (self.prefix == '@pkgdatadir@') + + if self.installed: + self.state_dir = '@localstatedir@/lib/kimchi' + self.log_dir = '@localstatedir@/log/kimchi' + self.conf_dir = '@sysconfdir@/kimchi' + self.src_dir = '@kimchidir@' + self.plugins_dir = '@kimchidir@' + else: + self.state_dir = self.add_prefix('data') + self.log_dir = self.add_prefix('log') + self.conf_dir = self.add_prefix('src') + self.src_dir = self.add_prefix('src/kimchi') + self.plugins_dir = self.add_prefix('plugins') + + self.ui_dir = self.add_prefix('ui') + self.mo_dir = self.add_prefix('mo') + + def get_prefix(self): + if __file__[0] == '/': + base = os.path.dirname(__file__) + else: + base = os.path.dirname('./%s' % __file__) + + if os.access('%s/../../src/kimchi/config.py' % base, os.F_OK): + return os.path.abspath('%s/../..' % base) + else: + return '@pkgdatadir@' + + def add_prefix(self, subdir): + return os.path.join(self.prefix, subdir) + + def get_template_path(self, resource): + return os.path.join(self.ui_dir, 'pages/%s.tmpl' % resource) + +
+paths = Paths() +
Move it to the constants section
+class PluginPaths(Paths):
-def get_plugins_dir(): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - prefix = '@kimchidir@' - return os.path.join(prefix, 'plugins') + def __init__(self, name): + super(PluginPaths, self).__init__() + self.plugin_dir = os.path.join('plugins', name)
+ if self.installed: + self.conf_dir = '@sysconfdir@/kimchi/plugins.d' + self.src_dir = os.path.join('@kimchidir@', self.plugin_dir) + else: + self.conf_dir = self.add_prefix(self.plugin_dir) + self.src_dir = self.add_prefix(self.plugin_dir)
-def get_plugin_config(name): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - base_dir = '@sysconfdir@/kimchi/plugins.d/' - else: - base_dir = os.path.join(prefix, 'plugins') - return os.path.join(base_dir, '%s/%s.conf' % (name, name)) + self.ui_dir = self.add_prefix(os.path.join(self.plugin_dir, 'ui')) + self.mo_dir = self.add_prefix(os.path.join(self.plugin_dir, 'mo')) + self.conf_file = os.path.join(self.conf_dir, '%s.conf' % name)
-def _get_plugin_ui_dir(name): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - base_dir = '@pkgdatadir@/plugins/' - else: - base_dir = os.path.join(prefix, 'plugins') - return os.path.join(base_dir, '%s/ui' % name)
+_plugin_paths = {}
Why is it needed?
-def get_plugin_tab_xml(name): - return os.path.join(_get_plugin_ui_dir(name), 'config/tab-ext.xml') +def plugin_paths(plugin_name): + if plugin_name not in _plugin_paths: + _plugin_paths[plugin_name] = PluginPaths(plugin_name) + return _plugin_paths[plugin_name]
def _get_config(): @@ -180,12 +154,12 @@ def _get_config(): config.set("server", "ssl_key", "") config.set("server", "environment", "development") config.add_section("logging") - config.set("logging", "log_dir", get_default_log_dir()) + config.set("logging", "log_dir", paths.log_dir) config.set("logging", "log_level", DEFAULT_LOG_LEVEL) config.add_section("display") config.set("display", "display_proxy_port", "64667")
- config_file = os.path.join(get_config_dir(), 'kimchi.conf') + config_file = os.path.join(paths.conf_dir, 'kimchi.conf') if os.path.exists(config_file): config.read(config_file) return config @@ -195,4 +169,4 @@ config = _get_config()
if __name__ == '__main__': - print get_prefix() + print paths.prefix diff --git a/src/kimchi/root.py b/src/kimchi/root.py index 3cc6321..ae9fd0e 100644 --- a/src/kimchi/root.py +++ b/src/kimchi/root.py @@ -23,11 +23,12 @@
import cherrypy import json +import os
from kimchi import auth from kimchi import template -from kimchi.config import get_api_schema_file +from kimchi.config import paths from kimchi.control.base import Resource from kimchi.control.config import Config from kimchi.control.debugreports import DebugReports @@ -67,7 +68,8 @@ class Root(Resource): self.host = Host(model) self.debugreports = DebugReports(model) self.plugins = Plugins(model) - self.api_schema = json.load(open(get_api_schema_file())) + self.api_schema = json.load(open(os.path.join(paths.src_dir, + 'API.json')))
def error_production_handler(self, status, message, traceback, version): data = {'code': status, 'reason': message} diff --git a/src/kimchi/server.py b/src/kimchi/server.py index b820263..58b082b 100644 --- a/src/kimchi/server.py +++ b/src/kimchi/server.py @@ -33,6 +33,7 @@ from kimchi import config from kimchi import model from kimchi import mockmodel from kimchi import vnc +from kimchi.config import paths, plugin_paths from kimchi.root import Root from kimchi.utils import get_enabled_plugins, import_class
@@ -63,8 +64,8 @@ class Server(object): CACHEEXPIRES = 31536000 configObj = { '/': {'tools.trailing_slash.on': False, - 'tools.staticdir.root': config.get_prefix(), - 'tools.staticfile.root': config.get_prefix(), + 'tools.staticdir.root': paths.prefix, + 'tools.staticfile.root': paths.prefix, 'request.methods_with_bodies': ('POST', 'PUT'), 'tools.nocache.on': True, 'tools.sessions.on': True, @@ -211,7 +212,8 @@ class Server(object): plugin_config['/ui/config/tab-ext.xml'] = { 'tools.staticfile.on': True, 'tools.staticfile.filename': - config.get_plugin_tab_xml(plugin_name), + os.path.join(plugin_paths(plugin_name).ui_dir, + 'config/tab-ext.xml'), 'tools.nocache.on': True} except KeyError: continue @@ -233,7 +235,7 @@ class Server(object): cert = options.ssl_cert key = options.ssl_key if not cert or not key: - config_dir = config.get_config_dir() + config_dir = paths.conf_dir cert = '%s/kimchi-cert.pem' % config_dir key = '%s/kimchi-key.pem' % config_dir
diff --git a/src/kimchi/template.py b/src/kimchi/template.py index 1f19c4a..1740997 100644 --- a/src/kimchi/template.py +++ b/src/kimchi/template.py @@ -28,9 +28,10 @@ import os
from Cheetah.Template import Template +from glob import iglob
-from kimchi import config +from kimchi.config import paths
def get_lang(): @@ -54,8 +55,13 @@ def get_lang(): return langs
+def get_support_languages(): + mopath = "%s/*" % paths.mo_dir + return [path.rsplit('/', 1)[1] for path in iglob(mopath)] + + def validate_language(langs): - supportLangs = config.get_support_language() + supportLangs = get_support_languages() for lang in langs: if lang in supportLangs: return lang @@ -88,12 +94,12 @@ def render(resource, data): separators=(',', ':'), encoding='iso-8859-1') elif can_accept_html(): - filename = config.get_template_path(resource) + filename = paths.get_template_path(resource) try: params = {'data': data} lang = validate_language(get_lang()) gettext_conf = {'domain': 'kimchi', - 'localedir': config.get_mo_path(), + 'localedir': paths.mo_dir, 'lang': [lang]} params['lang'] = gettext_conf return Template(file=filename, searchList=params).respond() diff --git a/src/kimchi/utils.py b/src/kimchi/utils.py index 5d6e8ea..7077b3b 100644 --- a/src/kimchi/utils.py +++ b/src/kimchi/utils.py @@ -28,10 +28,10 @@ import urllib2
from cherrypy.lib.reprconf import Parser +from kimchi.config import paths, plugin_paths from kimchi.exception import TimeoutExpired
-from kimchi import config from threading import Timer
@@ -48,7 +48,7 @@ def is_digit(value):
def _load_plugin_conf(name): - plugin_conf = config.get_plugin_config(name) + plugin_conf = plugin_paths(name).conf_file if not os.path.exists(plugin_conf): cherrypy.log.error_log.error("Plugin configuration file %s" " doesn't exist." % plugin_conf) @@ -62,7 +62,7 @@ def _load_plugin_conf(name):
def get_enabled_plugins(): - plugin_dir = config.get_plugins_dir() + plugin_dir = paths.plugins_dir try: dir_contents = os.listdir(plugin_dir) except OSError: diff --git a/src/kimchid.in b/src/kimchid.in index 548fa52..eebc017 100644 --- a/src/kimchid.in +++ b/src/kimchid.in @@ -30,12 +30,13 @@ sys.path.insert(1, '@pythondir@')
import kimchi.server import kimchi.config -if kimchi.config.without_installation(): - sys.path.append(kimchi.config.get_prefix())
-from kimchi.config import config +from kimchi.config import config, paths from optparse import OptionParser
+if not paths.installed: + sys.path.append(paths.prefix) + ACCESS_LOG = "kimchi-access.log" ERROR_LOG = "kimchi-error.log"
diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 42c87a9..e5c9053 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -32,7 +32,7 @@ from functools import partial import kimchi.mockmodel import kimchi.server import utils -from kimchi import config +from kimchi.config import paths
test_server = None @@ -48,7 +48,7 @@ def setUpModule(): host = '127.0.0.1' port = utils.get_free_port('http') ssl_port = None - sys.path.append(config.get_prefix()) + sys.path.append(paths.prefix) test_server = utils.run_server(host, port, ssl_port, test_mode=True, model=model)

On 01/24/2014 09:37 AM, Aline Manera wrote:
On 01/22/2014 03:48 AM, Mark Wu wrote:
This patch reorganizes kimchi's paths generation code to make the user of path vars can work with both kimchi root app and plugin app.
Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com> --- src/kimchi/cachebust.py | 4 +- src/kimchi/config.py.in | 164 ++++++++++++++++++++---------------------------- src/kimchi/root.py | 6 +- src/kimchi/server.py | 10 +-- src/kimchi/template.py | 14 +++-- src/kimchi/utils.py | 6 +- src/kimchid.in | 7 ++- tests/test_plugin.py | 4 +- 8 files changed, 100 insertions(+), 115 deletions(-)
diff --git a/src/kimchi/cachebust.py b/src/kimchi/cachebust.py index 9a71f4f..7844695 100644 --- a/src/kimchi/cachebust.py +++ b/src/kimchi/cachebust.py @@ -23,11 +23,11 @@ import os
-from kimchi.config import get_prefix +from kimchi.config import paths
def href(url): # for error.html, url is absolute path - f = os.path.join(get_prefix(), 'ui', url.lstrip("/")) + f = os.path.join(paths.ui_dir, url.lstrip("/")) mtime = os.path.getmtime(f) return "%s?cacheBust=%s" % (url, mtime) diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in index 22fe614..53c8e42 100644 --- a/src/kimchi/config.py.in +++ b/src/kimchi/config.py.in @@ -28,7 +28,6 @@ import platform
from ConfigParser import SafeConfigParser -from glob import iglob
from kimchi.xmlutils import xpath_get_text @@ -37,86 +36,24 @@ from kimchi.xmlutils import xpath_get_text DEFAULT_LOG_LEVEL = "debug"
-def get_prefix(): - if __file__[0] == '/': - base = os.path.dirname(__file__) - else: - base = os.path.dirname('./%s' % __file__) - - if os.access('%s/../../src/kimchi/config.py' % base, os.F_OK): - return '%s/../..' % base - else: - return '@pkgdatadir@' - - -def without_installation(): - return get_prefix() != '@pkgdatadir@' - - -def get_config_dir(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return '@sysconfdir@/kimchi' - else: - return os.path.join(prefix, 'src') - - -def _get_kimchi_src_dir(): - prefix = get_prefix() - return ('@kimchidir@' if prefix == '@pkgdatadir@' - else os.path.join(prefix, 'src/kimchi')) - - -def get_api_schema_file(): - return os.path.join(_get_kimchi_src_dir(), 'API.json') - - -def get_default_log_dir(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return "@localstatedir@/log/kimchi" - - return os.path.join(prefix, 'log') - - -def get_state_path(): - prefix = get_prefix() - - if prefix == '@pkgdatadir@': - return "@localstatedir@/lib/kimchi" - - return os.path.join(prefix, 'data') - - def get_session_path(): - return os.path.join(get_state_path(), 'sessions') + return os.path.join(paths.state_dir, 'sessions')
def get_object_store(): - return os.path.join(get_prefix(), 'data', 'objectstore') + return os.path.join(paths.state_dir, 'objectstore')
def get_distros_store(): - return os.path.join(get_config_dir(), 'distros.d') - - -def get_template_path(resource): - return '%s/ui/pages/%s.tmpl' % (get_prefix(), resource) + return os.path.join(paths.conf_dir, 'distros.d')
def get_screenshot_path(): - return "%s/data/screenshots" % get_prefix() - + return os.path.join(paths.state_dir, 'screenshots')
-def get_mo_path(): - return '%s/mo' % get_prefix()
- -def get_support_language(): - mopath = "%s/*" % get_mo_path() - return [path.rsplit('/', 1)[1] for path in iglob(mopath)] +def get_debugreports_path(): + return os.path.join(paths.state_dir, 'debugreports')
def find_qemu_binary(): @@ -137,37 +74,74 @@ def find_qemu_binary(): return location
-def get_debugreports_path(): - return os.path.join(get_prefix(), 'data', 'debugreports') +class Paths(object): + + def __init__(self): + self.prefix = self.get_prefix() + self.installed = (self.prefix == '@pkgdatadir@') + + if self.installed: + self.state_dir = '@localstatedir@/lib/kimchi' + self.log_dir = '@localstatedir@/log/kimchi' + self.conf_dir = '@sysconfdir@/kimchi' + self.src_dir = '@kimchidir@' + self.plugins_dir = '@kimchidir@' + else: + self.state_dir = self.add_prefix('data') + self.log_dir = self.add_prefix('log') + self.conf_dir = self.add_prefix('src') + self.src_dir = self.add_prefix('src/kimchi') + self.plugins_dir = self.add_prefix('plugins') + + self.ui_dir = self.add_prefix('ui') + self.mo_dir = self.add_prefix('mo') + + def get_prefix(self): + if __file__[0] == '/': + base = os.path.dirname(__file__) + else: + base = os.path.dirname('./%s' % __file__) + + if os.access('%s/../../src/kimchi/config.py' % base, os.F_OK): + return os.path.abspath('%s/../..' % base) + else: + return '@pkgdatadir@' + + def add_prefix(self, subdir): + return os.path.join(self.prefix, subdir) + + def get_template_path(self, resource): + return os.path.join(self.ui_dir, 'pages/%s.tmpl' % resource) + +
+paths = Paths() +
Move it to the constants section We have to put it after the definition of class Paths. If you insist on it, we will have to move the class Path to a new module. But it's still not clean to have paths related definition in two files.
+class PluginPaths(Paths):
-def get_plugins_dir(): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - prefix = '@kimchidir@' - return os.path.join(prefix, 'plugins') + def __init__(self, name): + super(PluginPaths, self).__init__() + self.plugin_dir = os.path.join('plugins', name)
+ if self.installed: + self.conf_dir = '@sysconfdir@/kimchi/plugins.d' + self.src_dir = os.path.join('@kimchidir@', self.plugin_dir) + else: + self.conf_dir = self.add_prefix(self.plugin_dir) + self.src_dir = self.add_prefix(self.plugin_dir)
-def get_plugin_config(name): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - base_dir = '@sysconfdir@/kimchi/plugins.d/' - else: - base_dir = os.path.join(prefix, 'plugins') - return os.path.join(base_dir, '%s/%s.conf' % (name, name)) + self.ui_dir = self.add_prefix(os.path.join(self.plugin_dir, 'ui')) + self.mo_dir = self.add_prefix(os.path.join(self.plugin_dir, 'mo')) + self.conf_file = os.path.join(self.conf_dir, '%s.conf' % name)
-def _get_plugin_ui_dir(name): - prefix = get_prefix() - if prefix == '@pkgdatadir@': - base_dir = '@pkgdatadir@/plugins/' - else: - base_dir = os.path.join(prefix, 'plugins') - return os.path.join(base_dir, '%s/ui' % name)
+_plugin_paths = {}
Why is it needed? It was kind of cache to avoid
instantiation many times. but it just have a few, so remove it in v2.
-def get_plugin_tab_xml(name): - return os.path.join(_get_plugin_ui_dir(name), 'config/tab-ext.xml') +def plugin_paths(plugin_name): + if plugin_name not in _plugin_paths: + _plugin_paths[plugin_name] = PluginPaths(plugin_name) + return _plugin_paths[plugin_name]
def _get_config(): @@ -180,12 +154,12 @@ def _get_config(): config.set("server", "ssl_key", "") config.set("server", "environment", "development") config.add_section("logging") - config.set("logging", "log_dir", get_default_log_dir()) + config.set("logging", "log_dir", paths.log_dir) config.set("logging", "log_level", DEFAULT_LOG_LEVEL) config.add_section("display") config.set("display", "display_proxy_port", "64667")
- config_file = os.path.join(get_config_dir(), 'kimchi.conf') + config_file = os.path.join(paths.conf_dir, 'kimchi.conf') if os.path.exists(config_file): config.read(config_file) return config @@ -195,4 +169,4 @@ config = _get_config()
if __name__ == '__main__': - print get_prefix() + print paths.prefix diff --git a/src/kimchi/root.py b/src/kimchi/root.py index 3cc6321..ae9fd0e 100644 --- a/src/kimchi/root.py +++ b/src/kimchi/root.py @@ -23,11 +23,12 @@
import cherrypy import json +import os
from kimchi import auth from kimchi import template -from kimchi.config import get_api_schema_file +from kimchi.config import paths from kimchi.control.base import Resource from kimchi.control.config import Config from kimchi.control.debugreports import DebugReports @@ -67,7 +68,8 @@ class Root(Resource): self.host = Host(model) self.debugreports = DebugReports(model) self.plugins = Plugins(model) - self.api_schema = json.load(open(get_api_schema_file())) + self.api_schema = json.load(open(os.path.join(paths.src_dir, + 'API.json')))
def error_production_handler(self, status, message, traceback, version): data = {'code': status, 'reason': message} diff --git a/src/kimchi/server.py b/src/kimchi/server.py index b820263..58b082b 100644 --- a/src/kimchi/server.py +++ b/src/kimchi/server.py @@ -33,6 +33,7 @@ from kimchi import config from kimchi import model from kimchi import mockmodel from kimchi import vnc +from kimchi.config import paths, plugin_paths from kimchi.root import Root from kimchi.utils import get_enabled_plugins, import_class
@@ -63,8 +64,8 @@ class Server(object): CACHEEXPIRES = 31536000 configObj = { '/': {'tools.trailing_slash.on': False, - 'tools.staticdir.root': config.get_prefix(), - 'tools.staticfile.root': config.get_prefix(), + 'tools.staticdir.root': paths.prefix, + 'tools.staticfile.root': paths.prefix, 'request.methods_with_bodies': ('POST', 'PUT'), 'tools.nocache.on': True, 'tools.sessions.on': True, @@ -211,7 +212,8 @@ class Server(object): plugin_config['/ui/config/tab-ext.xml'] = { 'tools.staticfile.on': True, 'tools.staticfile.filename': - config.get_plugin_tab_xml(plugin_name), + os.path.join(plugin_paths(plugin_name).ui_dir, + 'config/tab-ext.xml'), 'tools.nocache.on': True} except KeyError: continue @@ -233,7 +235,7 @@ class Server(object): cert = options.ssl_cert key = options.ssl_key if not cert or not key: - config_dir = config.get_config_dir() + config_dir = paths.conf_dir cert = '%s/kimchi-cert.pem' % config_dir key = '%s/kimchi-key.pem' % config_dir
diff --git a/src/kimchi/template.py b/src/kimchi/template.py index 1f19c4a..1740997 100644 --- a/src/kimchi/template.py +++ b/src/kimchi/template.py @@ -28,9 +28,10 @@ import os
from Cheetah.Template import Template +from glob import iglob
-from kimchi import config +from kimchi.config import paths
def get_lang(): @@ -54,8 +55,13 @@ def get_lang(): return langs
+def get_support_languages(): + mopath = "%s/*" % paths.mo_dir + return [path.rsplit('/', 1)[1] for path in iglob(mopath)] + + def validate_language(langs): - supportLangs = config.get_support_language() + supportLangs = get_support_languages() for lang in langs: if lang in supportLangs: return lang @@ -88,12 +94,12 @@ def render(resource, data): separators=(',', ':'), encoding='iso-8859-1') elif can_accept_html(): - filename = config.get_template_path(resource) + filename = paths.get_template_path(resource) try: params = {'data': data} lang = validate_language(get_lang()) gettext_conf = {'domain': 'kimchi', - 'localedir': config.get_mo_path(), + 'localedir': paths.mo_dir, 'lang': [lang]} params['lang'] = gettext_conf return Template(file=filename, searchList=params).respond() diff --git a/src/kimchi/utils.py b/src/kimchi/utils.py index 5d6e8ea..7077b3b 100644 --- a/src/kimchi/utils.py +++ b/src/kimchi/utils.py @@ -28,10 +28,10 @@ import urllib2
from cherrypy.lib.reprconf import Parser +from kimchi.config import paths, plugin_paths from kimchi.exception import TimeoutExpired
-from kimchi import config from threading import Timer
@@ -48,7 +48,7 @@ def is_digit(value):
def _load_plugin_conf(name): - plugin_conf = config.get_plugin_config(name) + plugin_conf = plugin_paths(name).conf_file if not os.path.exists(plugin_conf): cherrypy.log.error_log.error("Plugin configuration file %s" " doesn't exist." % plugin_conf) @@ -62,7 +62,7 @@ def _load_plugin_conf(name):
def get_enabled_plugins(): - plugin_dir = config.get_plugins_dir() + plugin_dir = paths.plugins_dir try: dir_contents = os.listdir(plugin_dir) except OSError: diff --git a/src/kimchid.in b/src/kimchid.in index 548fa52..eebc017 100644 --- a/src/kimchid.in +++ b/src/kimchid.in @@ -30,12 +30,13 @@ sys.path.insert(1, '@pythondir@')
import kimchi.server import kimchi.config -if kimchi.config.without_installation(): - sys.path.append(kimchi.config.get_prefix())
-from kimchi.config import config +from kimchi.config import config, paths from optparse import OptionParser
+if not paths.installed: + sys.path.append(paths.prefix) + ACCESS_LOG = "kimchi-access.log" ERROR_LOG = "kimchi-error.log"
diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 42c87a9..e5c9053 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -32,7 +32,7 @@ from functools import partial import kimchi.mockmodel import kimchi.server import utils -from kimchi import config +from kimchi.config import paths
test_server = None @@ -48,7 +48,7 @@ def setUpModule(): host = '127.0.0.1' port = utils.get_free_port('http') ssl_port = None - sys.path.append(config.get_prefix()) + sys.path.append(paths.prefix) test_server = utils.run_server(host, port, ssl_port, test_mode=True, model=model)

This patch adds test cases for paths generation code. Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com> --- tests/test_config.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 tests/test_config.py diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..4ad88f0 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,73 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2013 +# +# Authors: +# Mark Wu <wudxw@linux.vnet.ibm.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import unittest + + +from kimchi.config import Paths, PluginPaths + + +class ConfigTests(unittest.TestCase): + def test_installed_paths(self): + Paths.get_prefix = lambda self: '/usr/share/kimchi' + paths = Paths() + self.assertEquals(paths.state_dir, '/var/lib/kimchi') + self.assertEquals(paths.log_dir, '/var/log/kimchi') + self.assertEquals(paths.conf_dir, '/etc/kimchi') + self.assertEquals(paths.src_dir, + '/usr/lib/python2.7/site-packages/kimchi') + self.assertEquals(paths.plugins_dir, + '/usr/lib/python2.7/site-packages/kimchi') + self.assertEquals(paths.ui_dir, '/usr/share/kimchi/ui') + self.assertEquals(paths.mo_dir, '/usr/share/kimchi/mo') + + def test_uninstalled_paths(self): + Paths.get_prefix = lambda self: '/home/user/kimchi' + paths = Paths() + self.assertEquals(paths.state_dir, '/home/user/kimchi/data') + self.assertEquals(paths.log_dir, '/home/user/kimchi/log') + self.assertEquals(paths.conf_dir, '/home/user/kimchi/src') + self.assertEquals(paths.src_dir, '/home/user/kimchi/src/kimchi') + self.assertEquals(paths.plugins_dir, '/home/user/kimchi/plugins') + self.assertEquals(paths.ui_dir, '/home/user/kimchi/ui') + self.assertEquals(paths.mo_dir, '/home/user/kimchi/mo') + + def test_installed_plugin_paths(self): + PluginPaths.get_prefix = lambda self: '/usr/share/kimchi' + paths = PluginPaths('sample') + self.assertEquals(paths.conf_dir, '/etc/kimchi/plugins.d') + self.assertEquals(paths.conf_file, '/etc/kimchi/plugins.d/sample.conf') + self.assertEquals( + paths.src_dir, + '/usr/lib/python2.7/site-packages/kimchi/plugins/sample') + self.assertEquals(paths.ui_dir, '/usr/share/kimchi/plugins/sample/ui') + self.assertEquals(paths.mo_dir, '/usr/share/kimchi/plugins/sample/mo') + + def test_uninstalled_plugin_paths(self): + PluginPaths.get_prefix = lambda self: '/home/user/kimchi' + paths = PluginPaths('sample') + self.assertEquals(paths.conf_dir, '/home/user/kimchi/plugins/sample') + self.assertEquals( + paths.conf_file, '/home/user/kimchi/plugins/sample/sample.conf') + self.assertEquals(paths.src_dir, '/home/user/kimchi/plugins/sample') + self.assertEquals(paths.ui_dir, '/home/user/kimchi/plugins/sample/ui') + self.assertEquals(paths.mo_dir, '/home/user/kimchi/plugins/sample/mo') -- 1.8.4.2

To make kimchi's error handler and tabs handler resued for plugin, this patch moves the resource related code into a subclass. With this change, the plugin can have error handler and tabs handler by inheriting from this class. Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com> --- src/kimchi/root.py | 37 ++++++++++++++++++++++--------------- src/kimchi/server.py | 4 ++-- src/kimchi/template.py | 5 ++--- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/kimchi/root.py b/src/kimchi/root.py index ae9fd0e..4f30c0d 100644 --- a/src/kimchi/root.py +++ b/src/kimchi/root.py @@ -45,7 +45,8 @@ from kimchi.exception import OperationFailed class Root(Resource): - def __init__(self, model, dev_env): + def __init__(self, model, dev_env=False): + super(Root, self).__init__(model) self._handled_error = ['error_page.400', 'error_page.404', 'error_page.405', 'error_page.406', 'error_page.415', 'error_page.500'] @@ -57,19 +58,6 @@ class Root(Resource): self._cp_config = dict([(key, self.error_development_handler) for key in self._handled_error]) - Resource.__init__(self, model) - self.vms = VMs(model) - self.templates = Templates(model) - self.storagepools = StoragePools(model) - self.interfaces = Interfaces(model) - self.networks = Networks(model) - self.tasks = Tasks(model) - self.config = Config(model) - self.host = Host(model) - self.debugreports = DebugReports(model) - self.plugins = Plugins(model) - self.api_schema = json.load(open(os.path.join(paths.src_dir, - 'API.json'))) def error_production_handler(self, status, message, traceback, version): data = {'code': status, 'reason': message} @@ -87,7 +75,7 @@ class Root(Resource): return res def get(self): - return self.default('kimchi-ui.html') + return self.default(self.default_page) @cherrypy.expose def default(self, page, **kwargs): @@ -101,6 +89,25 @@ class Root(Resource): return template.render('tabs/' + page, None) raise cherrypy.HTTPError(404) + +class KimchiRoot(Root): + def __init__(self, model, dev_env): + super(KimchiRoot, self).__init__(model, dev_env) + self.default_page = 'kimchi-ui.html' + self.vms = VMs(model) + self.templates = Templates(model) + self.storagepools = StoragePools(model) + self.interfaces = Interfaces(model) + self.networks = Networks(model) + self.tasks = Tasks(model) + self.config = Config(model) + self.host = Host(model) + self.debugreports = DebugReports(model) + self.plugins = Plugins(model) + self.api_schema = json.load(open(os.path.join(paths.src_dir, + 'API.json'))) + self.paths = paths + @cherrypy.expose def login(self, *args): params = parse_request() diff --git a/src/kimchi/server.py b/src/kimchi/server.py index 58b082b..3c429d3 100644 --- a/src/kimchi/server.py +++ b/src/kimchi/server.py @@ -34,7 +34,7 @@ from kimchi import model from kimchi import mockmodel from kimchi import vnc from kimchi.config import paths, plugin_paths -from kimchi.root import Root +from kimchi.root import KimchiRoot from kimchi.utils import get_enabled_plugins, import_class @@ -194,7 +194,7 @@ class Server(object): vnc_ws_proxy = vnc.new_ws_proxy() cherrypy.engine.subscribe('exit', vnc_ws_proxy.kill) - self.app = cherrypy.tree.mount(Root(model_instance, dev_env), + self.app = cherrypy.tree.mount(KimchiRoot(model_instance, dev_env), config=self.configObj) self._load_plugins() diff --git a/src/kimchi/template.py b/src/kimchi/template.py index 1740997..0a3b067 100644 --- a/src/kimchi/template.py +++ b/src/kimchi/template.py @@ -31,9 +31,6 @@ from Cheetah.Template import Template from glob import iglob -from kimchi.config import paths - - def get_lang(): cookie = cherrypy.request.cookie if "kimchiLang" in cookie.keys(): @@ -56,6 +53,7 @@ def get_lang(): def get_support_languages(): + paths = cherrypy.request.app.root.paths mopath = "%s/*" % paths.mo_dir return [path.rsplit('/', 1)[1] for path in iglob(mopath)] @@ -88,6 +86,7 @@ def can_accept_html(): can_accept('*/*') def render(resource, data): + paths = cherrypy.request.app.root.paths if can_accept('application/json'): cherrypy.response.headers['Content-Type'] = 'application/json;charset=utf-8' return json.dumps(data, indent=2, -- 1.8.4.2

Reviewed-by: Crístian Viana <vianac@linux.vnet.ibm.com> Am 22-01-2014 03:48, schrieb Mark Wu:
To make kimchi's error handler and tabs handler resued for plugin, this patch moves the resource related code into a subclass. With this change, the plugin can have error handler and tabs handler by inheriting from this class.
Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com>

Also needs to rebase the whole patch set On 01/22/2014 03:48 AM, Mark Wu wrote:
This series of patches reorganize kimchi's path vars generation code to allow plugin use kimchi s ui handler.
Mark Wu (3): Reorganize the kimchi's paths gereneration code Add test cases for paths generation code Allow plugin use kimchi's ui handler
src/kimchi/cachebust.py | 4 +- src/kimchi/config.py.in | 164 ++++++++++++++++++++---------------------------- src/kimchi/root.py | 39 +++++++----- src/kimchi/server.py | 14 +++-- src/kimchi/template.py | 17 +++-- src/kimchi/utils.py | 6 +- src/kimchid.in | 7 ++- tests/test_config.py | 73 +++++++++++++++++++++ tests/test_plugin.py | 4 +- 9 files changed, 196 insertions(+), 132 deletions(-) create mode 100644 tests/test_config.py
participants (3)
-
Aline Manera
-
Crístian Viana
-
Mark Wu