[Kimchi-devel] [RFC PATCH V2 14/31] Setup wok

Lucio Correia luciojhc at linux.vnet.ibm.com
Mon Jun 22 22:59:28 UTC 2015


- Add model.py for wok
- Add an empty json API to wok
- Move some basic Javascript APIs from kimchi
- Do not load tabs.xml anymore
- Disable wok authentication by default
- Rename KimchiRoot to WokRoot
- Update default_page to wok-ui.html
- Adapt 'sample' plugin
- Move hide-content css to wok

Signed-off-by: Lucio Correia <luciojhc at linux.vnet.ibm.com>
Signed-off-by: Gustavo Y. Ribeiro <gyr at linux.vnet.ibm.com>
---
 plugins/kimchi/ui/css/theme-default/storage.css |    4 -
 plugins/sample/__init__.py                      |    4 +-
 src/wok/API.json                                |    6 ++
 src/wok/config.py.in                            |    1 +
 src/wok/model/model.py                          |   49 ++++++++++++
 src/wok/root.py                                 |   10 +-
 src/wok/server.py                               |    8 +-
 src/wok/utils.py                                |    2 +-
 ui/css/theme-default/topbar.css                 |    4 +
 ui/js/src/wok.api.js                            |   91 +++++++++++++++++++++++
 ui/js/src/wok.main.js                           |    3 +-
 11 files changed, 164 insertions(+), 18 deletions(-)
 create mode 100644 src/wok/API.json
 create mode 100644 src/wok/model/model.py
 create mode 100644 ui/js/src/wok.api.js

diff --git a/plugins/kimchi/ui/css/theme-default/storage.css b/plugins/kimchi/ui/css/theme-default/storage.css
index 519a28b..d30a5a7 100644
--- a/plugins/kimchi/ui/css/theme-default/storage.css
+++ b/plugins/kimchi/ui/css/theme-default/storage.css
@@ -319,10 +319,6 @@
     border: 1px solid rgb(204, 204, 204);
 }
 
-.hide-content {
-    display: none!important;
-}
-
 .volumeslist {
     padding: 7px;
     max-height: 272px;
diff --git a/plugins/sample/__init__.py b/plugins/sample/__init__.py
index 786832f..3a309a5 100644
--- a/plugins/sample/__init__.py
+++ b/plugins/sample/__init__.py
@@ -26,7 +26,7 @@ from cherrypy import expose
 
 from wok.config import PluginPaths
 from wok.control.base import Collection, Resource
-from wok.root import Root
+from wok.root import WokRoot
 from plugins.sample.i18n import messages
 from plugins.sample.model import Model
 
@@ -34,7 +34,7 @@ from plugins.sample.model import Model
 model = Model()
 
 
-class Drawings(Root):
+class Drawings(WokRoot):
     def __init__(self):
         Resource.__init__(self, model)
         self.description = Description(model)
diff --git a/src/wok/API.json b/src/wok/API.json
new file mode 100644
index 0000000..8965db9
--- /dev/null
+++ b/src/wok/API.json
@@ -0,0 +1,6 @@
+{
+    "$schema": "http://json-schema.org/draft-03/schema#",
+    "title": "Wok API",
+    "description": "Json schema for Wok API",
+    "type": "object"
+}
diff --git a/src/wok/config.py.in b/src/wok/config.py.in
index 4c97840..390ba3b 100644
--- a/src/wok/config.py.in
+++ b/src/wok/config.py.in
@@ -180,6 +180,7 @@ class UIConfig(dict):
             ui_configs['/' + sub_dir] = {
                 'tools.staticdir.on': True,
                 'tools.staticdir.dir': os.path.join(paths.ui_dir, sub_dir),
+                'tools.wokauth.on': False,
                 'tools.nocache.on': False}
             if sub_dir != 'images':
                 ui_configs['/' + sub_dir].update({
diff --git a/src/wok/model/model.py b/src/wok/model/model.py
new file mode 100644
index 0000000..09c4c1e
--- /dev/null
+++ b/src/wok/model/model.py
@@ -0,0 +1,49 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-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 inspect
+import os
+
+from wok.basemodel import BaseModel
+from wok.objectstore import ObjectStore
+from wok.utils import import_module, listPathModules
+
+
+class Model(BaseModel):
+    def __init__(self, objstore_loc=None):
+
+        self.objstore = ObjectStore(objstore_loc)
+        kargs = {'objstore': self.objstore}
+
+        this = os.path.basename(__file__)
+        this_mod = os.path.splitext(this)[0]
+
+        models = []
+        for mod_name in listPathModules(os.path.dirname(__file__)):
+            if mod_name.startswith("_") or mod_name == this_mod:
+                continue
+
+            module = import_module('wok.model.' + mod_name)
+            members = inspect.getmembers(module, inspect.isclass)
+            for cls_name, instance in members:
+                if inspect.getmodule(instance) == module:
+                    if cls_name.endswith('Model'):
+                        models.append(instance(**kargs))
+
+        return super(Model, self).__init__(models)
diff --git a/src/wok/root.py b/src/wok/root.py
index a3b8be1..35620c7 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):
-    def __init__(self, model, dev_env):
-        super(KimchiRoot, self).__init__(model, dev_env)
-        self.default_page = 'kimchi-ui.html'
+class WokRoot(Root):
+    def __init__(self, model, dev_env=False):
+        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..ab941e7 100644
--- a/src/wok/server.py
+++ b/src/wok/server.py
@@ -28,10 +28,10 @@ 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.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
 
 
@@ -73,7 +73,7 @@ class Server(object):
             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,
@@ -141,7 +141,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 f5058d5..fc76620 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/css/theme-default/topbar.css b/ui/css/theme-default/topbar.css
index 9dd5ec1..4fce02c 100644
--- a/ui/css/theme-default/topbar.css
+++ b/ui/css/theme-default/topbar.css
@@ -208,3 +208,7 @@ a#btn-logout:hover {
     display: block;
     padding: 10px;
 }
+
+.hide-content {
+    display: none!important;
+}
diff --git a/ui/js/src/wok.api.js b/ui/js/src/wok.api.js
new file mode 100644
index 0000000..93a07ad
--- /dev/null
+++ b/ui/js/src/wok.api.js
@@ -0,0 +1,91 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var wok = {
+
+    widget: {},
+
+    /**
+     * A wrapper of jQuery.ajax function to allow custom bindings.
+     *
+     * @param settings an extended object to jQuery Ajax settings object
+     *   with some extra properties (see below)
+     *
+     *   resend: if the XHR has failed due to 401, the XHR can be resent
+     *     after user being authenticated successfully by setting resend
+     *     to true: settings = {resend: true}. It's useful for switching
+     *     pages (Guests, Templates, etc.).
+     *       e.g., the user wants to list guests by clicking Guests tab,
+     *     but he is told not authorized and a login window will pop up.
+     *     After login, the Ajax request for /vms will be resent without
+     *     user clicking the tab again.
+     *       Default to false.
+     */
+    requestJSON : function(settings) {
+        settings['originalError'] = settings['error'];
+        settings['error'] = null;
+        settings['wok'] = true;
+        return $.ajax(settings);
+    },
+
+    /**
+     * Get the i18 strings.
+     */
+    getI18n: function(suc, err, url, sync) {
+        wok.requestJSON({
+            url : url ? url : 'i18n.json',
+            type : 'GET',
+            resend: true,
+            dataType : 'json',
+            async : !sync,
+            success : suc,
+            error: err
+        });
+    },
+
+    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) {
+        wok.requestJSON({
+            url : 'logout',
+            type : 'POST',
+            contentType : "application/json",
+            dataType : "json"
+        }).done(suc).fail(err);
+    },
+
+    listPlugins : function(suc, err, sync) {
+        wok.requestJSON({
+            url : 'plugins',
+            type : 'GET',
+            contentType : 'application/json',
+            dataType : 'json',
+            resend: true,
+            async : !sync,
+            success : suc,
+            error : err
+        });
+     },
+};
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