[Kimchi-devel] [PATCH 18/38] Setup kimchi plugin

Lucio Correia luciojhc at linux.vnet.ibm.com
Thu May 21 21:33:31 UTC 2015


- Create kimchi.conf and config.py in plugin
- Move kimchi specific config/API to plugin
- Rename Kimchi{Config,Root} to Wok{Config,Root}
- Create root.py in plugin with new KimchiRoot
- Adjust tabs-ext.xml and do not load tabs.xml anymore
- Drop login/logout functions from plugin API
---
 plugins/kimchi/__init__.py             |   21 +++++++
 plugins/kimchi/config.py.in            |   74 ++++++++++++++++++++++++
 plugins/kimchi/kimchi.conf             |   67 +++++++++++++++++++++
 plugins/kimchi/root.py                 |   57 ++++++++++++++++++
 plugins/kimchi/ui/config/tab-ext.xml   |   14 ++--
 plugins/kimchi/ui/js/src/kimchi.api.js |   19 ------
 src/wok/config.py.in                   |   99 --------------------------------
 src/wok/root.py                        |    8 +-
 src/wok/server.py                      |   20 ++----
 src/wok/utils.py                       |    2 +-
 ui/js/src/wok.main.js                  |    3 +-
 11 files changed, 239 insertions(+), 145 deletions(-)
 create mode 100644 plugins/kimchi/__init__.py
 create mode 100644 plugins/kimchi/config.py.in
 create mode 100644 plugins/kimchi/kimchi.conf
 create mode 100644 plugins/kimchi/root.py

diff --git a/plugins/kimchi/__init__.py b/plugins/kimchi/__init__.py
new file mode 100644
index 0000000..9330044
--- /dev/null
+++ b/plugins/kimchi/__init__.py
@@ -0,0 +1,21 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# 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
+
+from root import KimchiRoot
+__all__ = [KimchiRoot]
diff --git a/plugins/kimchi/config.py.in b/plugins/kimchi/config.py.in
new file mode 100644
index 0000000..fdf360a
--- /dev/null
+++ b/plugins/kimchi/config.py.in
@@ -0,0 +1,74 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# 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 libvirt
+import os
+import platform
+import threading
+
+from wok.config import PluginPaths
+from wok.xmlutils.utils import xpath_get_text
+
+kimchiLock = threading.Lock()
+
+# Storage pool constant for read-only pool types
+READONLY_POOL_TYPE = ['iscsi', 'scsi', 'mpath']
+
+
+def get_distros_store():
+    return os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d')
+
+
+def get_debugreports_path():
+    return os.path.join(PluginPaths('kimchi').state_dir, 'debugreports')
+
+
+def get_screenshot_path():
+    return os.path.join(PluginPaths('kimchi').state_dir, 'screenshots')
+
+
+def find_qemu_binary(find_emulator=False):
+    try:
+        connect = libvirt.open(None)
+    except Exception, e:
+        raise Exception("Unable to get qemu binary location: %s" % e)
+    try:
+        xml = connect.getCapabilities()
+
+        # On Little Endian system, the qemu binary is
+        # qemu-system-ppc64, not qemu-system-ppc64le as expected
+        arch = platform.machine()
+        if arch == "ppc64le":
+            arch = "ppc64"
+
+        if find_emulator:
+            expr = "/capabilities/guest/arch[@name='%s']\
+                    /emulator" % arch
+        else:
+            expr = "/capabilities/guest/arch[@name='%s']\
+                    /domain[@type='kvm']/emulator" % arch
+        res = xpath_get_text(xml, expr)
+        location = res[0]
+    except Exception, e:
+        raise Exception("Unable to get qemu binary location: %s" % e)
+    finally:
+        connect.close()
+    return location
+
diff --git a/plugins/kimchi/kimchi.conf b/plugins/kimchi/kimchi.conf
new file mode 100644
index 0000000..07ade54
--- /dev/null
+++ b/plugins/kimchi/kimchi.conf
@@ -0,0 +1,67 @@
+[wok]
+enable = True
+plugin_class = "KimchiRoot"
+uri = "/plugins/kimchi"
+
+[/]
+tools.trailing_slash.on = False
+request.methods_with_bodies = ('POST', 'PUT')
+tools.nocache.on = True
+tools.proxy.on = True
+tools.sessions.on = True
+tools.sessions.name = 'wok'
+tools.sessions.secure = True
+tools.sessions.httponly = True
+tools.sessions.locking = 'explicit'
+tools.sessions.storage_type = 'ram'
+tools.sessions.timeout = 10
+tools.wokauth.on = True
+
+[/novnc]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').novnc_dir
+tools.nocache.on = True
+tools.wokauth.on = True
+
+[/spice_auto.html]
+tools.staticfile.on = True
+tools.staticfile.filename = wok.config.PluginPaths('kimchi').spice_file
+tools.nocache.on = True
+tools.wokauth.on = True
+
+[/spice-html5]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').spice_dir
+tools.nocache.on = True
+
+[/spice-html5/spice.css]
+tools.staticfile.on = True
+tools.staticfile.filename = wok.config.PluginPaths('kimchi').spice_css_file
+tools.nocache.on = True
+
+[/data/screenshots]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir + '/screenshots'
+tools.nocache.on = False
+
+[/data/debugreports]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir + '/debugreports'
+tools.nocache.on = False
+tools.wokauth.on = True
+tools.staticdir.content_types = {'xz': 'application/x-xz'}
+
+[/favicon.ico]
+tools.staticfile.on = True
+tools.staticfile.filename = wok.config.PluginPaths('kimchi').ui_dir + '/images/logo.ico'
+
+[/robots.txt]
+tools.staticfile.on = True
+tools.staticfile.filename = wok.config.PluginPaths('kimchi').ui_dir + '/robots.txt'
+
+[/help]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').ui_dir + '/pages/help'
+tools.nocache.on = True
+tools.staticdir.index = 'en_US/index.html'
+
diff --git a/plugins/kimchi/root.py b/plugins/kimchi/root.py
new file mode 100644
index 0000000..c05a6cb
--- /dev/null
+++ b/plugins/kimchi/root.py
@@ -0,0 +1,57 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# 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 json
+import os
+
+
+import config
+from control import sub_nodes
+from wok.i18n import messages
+from wok.config import PluginPaths
+from model import model as kimchiModel
+from wok.root import WokRoot
+
+
+class KimchiRoot(WokRoot):
+    def __init__(self, model=None, dev_env=False):
+        if not model:
+            self.model = kimchiModel.Model()
+        else:
+            self.model = model
+        super(KimchiRoot, self).__init__(self.model, dev_env)
+
+        for ident, node in sub_nodes.items():
+            setattr(self, ident, node(self.model))
+
+        self.api_schema = json.load(open(os.path.join(os.path.dirname(
+                                    os.path.abspath(__file__)), 'API.json')))
+        self.paths = PluginPaths('kimchi')
+        self.domain = 'kimchi'
+        self.messages = messages
+
+        make_dirs = [
+            os.path.abspath(config.get_distros_store()),
+            os.path.abspath(config.get_debugreports_path()),
+            os.path.abspath(config.get_screenshot_path())
+        ]
+        for directory in make_dirs:
+            if not os.path.isdir(directory):
+                os.makedirs(directory)
+
diff --git a/plugins/kimchi/ui/config/tab-ext.xml b/plugins/kimchi/ui/config/tab-ext.xml
index f79684c..ee88c88 100644
--- a/plugins/kimchi/ui/config/tab-ext.xml
+++ b/plugins/kimchi/ui/config/tab-ext.xml
@@ -1,38 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
-<tabs>
+<tabs-ext>
     <tab>
         <access role="admin" mode="admin"/>
         <access role="user" mode="none"/>
 
         <title>Host</title>
-        <path>tabs/host.html</path>
+        <path>plugins/kimchi/host.html</path>
     </tab>
     <tab>
         <access role="admin" mode="admin"/>
         <access role="user" mode="byInstance"/>
 
         <title>Guests</title>
-        <path>tabs/guests.html</path>
+        <path>plugins/kimchi/guests.html</path>
     </tab>
     <tab>
         <access role="admin" mode="admin"/>
         <access role="user" mode="none"/>
 
         <title>Templates</title>
-        <path>tabs/templates.html</path>
+        <path>plugins/kimchi/templates.html</path>
     </tab>
     <tab>
         <access role="admin" mode="admin"/>
         <access role="user" mode="read-only"/>
 
         <title>Storage</title>
-        <path>tabs/storage.html</path>
+        <path>plugins/kimchi/storage.html</path>
     </tab>
     <tab>
         <access role="admin" mode="admin"/>
         <access role="user" mode="read-only"/>
 
         <title>Network</title>
-        <path>tabs/network.html</path>
+        <path>plugins/kimchi/network.html</path>
     </tab>
-</tabs>
+</tabs-ext>
diff --git a/plugins/kimchi/ui/js/src/kimchi.api.js b/plugins/kimchi/ui/js/src/kimchi.api.js
index a74d660..ba1b762 100644
--- a/plugins/kimchi/ui/js/src/kimchi.api.js
+++ b/plugins/kimchi/ui/js/src/kimchi.api.js
@@ -547,25 +547,6 @@ var kimchi = {
         });
     },
 
-    login : function(settings, suc, err) {
-        $.ajax({
-            url : "login",
-            type : "POST",
-            contentType : "application/json",
-            data : JSON.stringify(settings),
-            dataType : "json"
-        }).done(suc).fail(err);
-    },
-
-    logout : function(suc, err) {
-        kimchi.requestJSON({
-            url : 'logout',
-            type : 'POST',
-            contentType : "application/json",
-            dataType : "json"
-        }).done(suc).fail(err);
-    },
-
     deleteStoragePool : function(poolName, suc, err) {
         $.ajax({
             url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName),
diff --git a/src/wok/config.py.in b/src/wok/config.py.in
index 390ba3b..2951539 100644
--- a/src/wok/config.py.in
+++ b/src/wok/config.py.in
@@ -18,78 +18,27 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 #
 
-import libvirt
 import os
-import platform
-import threading
 
 
 from ConfigParser import SafeConfigParser
 
 
-from kimchi.xmlutils.utils import xpath_get_text
-
 __version__ = "@wokversion@"
 __release__ = "@wokrelease@"
 __with_spice__ = "@withspice@"
 
 DEFAULT_LOG_LEVEL = "debug"
 
-kimchiLock = threading.Lock()
-
-# Storage pool constant for read-only pool types
-READONLY_POOL_TYPE = ['iscsi', 'scsi', 'mpath']
-
 
 def get_object_store():
     return os.path.join(paths.state_dir, 'objectstore')
 
 
-def get_distros_store():
-    return os.path.join(paths.conf_dir, 'distros.d')
-
-
-def get_screenshot_path():
-    return os.path.join(paths.state_dir, 'screenshots')
-
-
-def get_debugreports_path():
-    return os.path.join(paths.state_dir, 'debugreports')
-
-
 def get_version():
     return "-".join([__version__, __release__])
 
 
-def find_qemu_binary(find_emulator=False):
-    try:
-        connect = libvirt.open(None)
-    except Exception, e:
-        raise Exception("Unable to get qemu binary location: %s" % e)
-    try:
-        xml = connect.getCapabilities()
-
-        # On Little Endian system, the qemu binary is
-        # qemu-system-ppc64, not qemu-system-ppc64le as expected
-        arch = platform.machine()
-        if arch == "ppc64le":
-            arch = "ppc64"
-
-        if find_emulator:
-            expr = "/capabilities/guest/arch[@name='%s']\
-                    /emulator" % arch
-        else:
-            expr = "/capabilities/guest/arch[@name='%s']\
-                    /domain[@type='kvm']/emulator" % arch
-        res = xpath_get_text(xml, expr)
-        location = res[0]
-    except Exception, e:
-        raise Exception("Unable to get qemu binary location: %s" % e)
-    finally:
-        connect.close()
-    return location
-
-
 class Paths(object):
 
     def __init__(self):
@@ -214,57 +163,9 @@ class WokConfig(dict):
             'tools.nocache.on': True,
             'tools.wokauth.on': True
         },
-        '/spice_auto.html': {
-            'tools.staticfile.on': True,
-            'tools.staticfile.filename': paths.spice_file,
-            'tools.nocache.on': True,
-            'tools.kimchiauth.on': True
-        },
-        '/spice-html5': {
-            'tools.staticdir.on': True,
-            'tools.staticdir.dir': paths.spice_dir,
-            'tools.nocache.on': True
-        },
-        '/spice-html5/spice.css': {
-            'tools.staticfile.on': True,
-            'tools.staticfile.filename': paths.spice_css_file,
-            'tools.nocache.on': True,
-        },
         '/wok-ui.html': {
             'tools.wokauth.on': True
         },
-        '/data/screenshots': {
-            'tools.staticdir.on': True,
-            'tools.staticdir.dir': get_screenshot_path(),
-            'tools.nocache.on': False
-        },
-        '/data/debugreports': {
-            'tools.staticdir.on': True,
-            'tools.staticdir.dir': get_debugreports_path(),
-            'tools.nocache.on': False,
-            'tools.kimchiauth.on': True,
-            'tools.staticdir.content_types': {'xz': 'application/x-xz'}
-        },
-        '/config/ui/tabs.xml': {
-            'tools.staticfile.on': True,
-            'tools.staticfile.filename': '%s/config/ui/tabs.xml' %
-                                         paths.prefix,
-            'tools.nocache.on': True
-        },
-        '/favicon.ico': {
-            'tools.staticfile.on': True,
-            'tools.staticfile.filename': '%s/images/logo.ico' % paths.ui_dir
-        },
-        '/robots.txt': {
-            'tools.staticfile.on': True,
-            'tools.staticfile.filename': '%s/robots.txt' % paths.ui_dir
-        },
-        '/help': {
-            'tools.staticdir.on': True,
-            'tools.staticdir.dir': '%s/ui/pages/help' % paths.prefix,
-            'tools.staticdir.index': 'en_US/index.html',
-            'tools.nocache.on': True
-        }
     }
 
     def __init__(self):
diff --git a/src/wok/root.py b/src/wok/root.py
index a3b8be1..2b4ad44 100644
--- a/src/wok/root.py
+++ b/src/wok/root.py
@@ -114,16 +114,16 @@ class Root(Resource):
         raise cherrypy.HTTPError(404)
 
 
-class KimchiRoot(Root):
+class WokRoot(Root):
     def __init__(self, model, dev_env):
-        super(KimchiRoot, self).__init__(model, dev_env)
-        self.default_page = 'kimchi-ui.html'
+        super(WokRoot, self).__init__(model, dev_env)
+        self.default_page = 'wok-ui.html'
         for ident, node in sub_nodes.items():
             setattr(self, ident, node(model))
         with open(os.path.join(paths.src_dir, 'API.json')) as f:
             self.api_schema = json.load(f)
         self.paths = paths
-        self.domain = 'kimchi'
+        self.domain = 'wok'
         self.messages = messages
 
     @cherrypy.expose
diff --git a/src/wok/server.py b/src/wok/server.py
index 0f99663..711c24f 100644
--- a/src/wok/server.py
+++ b/src/wok/server.py
@@ -25,13 +25,12 @@ import os
 
 from wok import auth
 from wok import config
-from wok.model import model
-from wok import mockmodel
 from wok import vnc
-from wok.config import KimchiConfig, PluginConfig
+from wok.model import model
+from wok.config import WokConfig, PluginConfig
 from wok.control import sub_nodes
 from wok.proxy import start_proxy, terminate_proxy
-from wok.root import KimchiRoot
+from wok.root import WokRoot
 from wok.utils import get_enabled_plugins, import_class
 
 
@@ -64,16 +63,13 @@ class Server(object):
         make_dirs = [
             os.path.dirname(os.path.abspath(options.access_log)),
             os.path.dirname(os.path.abspath(options.error_log)),
-            os.path.dirname(os.path.abspath(config.get_object_store())),
-            os.path.abspath(config.get_screenshot_path()),
-            os.path.abspath(config.get_debugreports_path()),
-            os.path.abspath(config.get_distros_store())
+            os.path.dirname(os.path.abspath(config.get_object_store()))
         ]
         for directory in make_dirs:
             if not os.path.isdir(directory):
                 os.makedirs(directory)
 
-        self.configObj = KimchiConfig()
+        self.configObj = WokConfig()
         # We'll use the session timeout (= 10 minutes) and the
         # nginx timeout (= 10 minutes). This monitor isn't involved
         # in anything other than monitor the timeout of the connection,
@@ -126,12 +122,10 @@ class Server(object):
 
         if hasattr(options, 'model'):
             model_instance = options.model
-        elif options.test:
-            model_instance = mockmodel.MockModel()
         else:
             model_instance = model.Model()
 
-        if isinstance(model_instance, model.Model):
+        if isinstance(model_instance, model.Model) and not options.test:
             vnc_ws_proxy = vnc.new_ws_proxy()
             cherrypy.engine.subscribe('exit', vnc_ws_proxy.terminate)
 
@@ -141,7 +135,7 @@ class Server(object):
                 ident = "/%s" % ident
                 cfg[ident] = {'tools.wokauth.on': True}
 
-        self.app = cherrypy.tree.mount(KimchiRoot(model_instance, dev_env),
+        self.app = cherrypy.tree.mount(WokRoot(model_instance, dev_env),
                                        config=self.configObj)
         self._load_plugins()
 
diff --git a/src/wok/utils.py b/src/wok/utils.py
index 267cd3e..42e753d 100644
--- a/src/wok/utils.py
+++ b/src/wok/utils.py
@@ -113,7 +113,7 @@ def get_enabled_plugins():
 
 
 def get_all_tabs():
-    files = [os.path.join(paths.prefix, 'config/ui/tabs.xml')]
+    files = []
 
     for plugin, _ in get_enabled_plugins():
         files.append(os.path.join(PluginPaths(plugin).ui_dir,
diff --git a/ui/js/src/wok.main.js b/ui/js/src/wok.main.js
index 089b523..5b1f1bc 100644
--- a/ui/js/src/wok.main.js
+++ b/ui/js/src/wok.main.js
@@ -90,12 +90,11 @@ wok.main = function() {
         return tabs;
     };
 
-    var tabConfigUrl = 'config/ui/tabs.xml';
     var pluginConfigUrl = 'plugins/{plugin}/ui/config/tab-ext.xml';
     var pluginI18nUrl = 'plugins/{plugin}/i18n.json';
     var DEFAULT_HASH;
     var buildTabs = function(callback) {
-        var tabs = retrieveTabs(tabConfigUrl);
+        var tabs = [];
         wok.listPlugins(function(plugins) {
             $(plugins).each(function(i, p) {
                 var url = wok.substitute(pluginConfigUrl, {
-- 
1.7.1




More information about the Kimchi-devel mailing list