- 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(a)linux.vnet.ibm.com>
Signed-off-by: Gustavo Y. Ribeiro <gyr(a)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