[PATCH] [Kimchi] Bug fix: Use 256MB of memory on feature tests due restriction on Power machines
by Aline Manera
On Power machines the amount of memory must be aligned with 256MB.
So adjust all feature tests according to it to avoid issues.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
model/featuretests.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/model/featuretests.py b/model/featuretests.py
index ba728e1..23e7eeb 100644
--- a/model/featuretests.py
+++ b/model/featuretests.py
@@ -34,7 +34,7 @@ FEATURETEST_POOL_NAME = "FEATURETEST_POOL"
ISO_STREAM_XML = """
<domain type='%(domain)s'>
<name>%(name)s</name>
- <memory unit='KiB'>1048576</memory>
+ <memory unit='MiB'>256</memory>
<os>
<type arch='%(arch)s'>hvm</type>
<boot dev='cdrom'/>
@@ -56,7 +56,7 @@ ISO_STREAM_XML = """
SIMPLE_VM_XML = """
<domain type='%(domain)s'>
<name>%(name)s</name>
- <memory unit='KiB'>10240</memory>
+ <memory unit='MiB'>256</memory>
<os>
<type arch='%(arch)s'>hvm</type>
<boot dev='hd'/>
@@ -66,15 +66,15 @@ SIMPLE_VM_XML = """
MAXMEM_VM_XML = """
<domain type='%(domain)s'>
<name>%(name)s</name>
- <maxMemory slots='1' unit='KiB'>20480</maxMemory>
- <memory unit='KiB'>10240</memory>
+ <maxMemory slots='1' unit='MiB'>512</maxMemory>
+ <memory unit='MiB'>256</memory>
<os>
<type arch='%(arch)s'>hvm</type>
<boot dev='hd'/>
</os>
<cpu>
<numa>
- <cell id='0' cpus='0' memory='10240' unit='KiB'/>
+ <cell id='0' cpus='0' memory='256' unit='MiB'/>
</numa>
</cpu>
<features>
@@ -85,7 +85,7 @@ MAXMEM_VM_XML = """
DEV_MEM_XML = """
<memory model='dimm'>
<target>
- <size unit='KiB'>10240</size>
+ <size unit='MiB'>256</size>
<node>0</node>
</target>
</memory>"""
--
2.5.5
8 years, 8 months
[PATCH V2] [Wok] Fix errors in Ginger/Gingerbase/Gingers390x tests
by Lucio Correia
Do not try to translate message when app is not found.
Signed-off-by: Lucio Correia <luciojhc(a)linux.vnet.ibm.com>
---
src/wok/message.py | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
Changes in V2: applied review.
diff --git a/src/wok/message.py b/src/wok/message.py
index 7ea5711..a3794d0 100644
--- a/src/wok/message.py
+++ b/src/wok/message.py
@@ -45,11 +45,11 @@ class WokMessage(object):
self.plugin = plugin
def _get_translation(self):
- wok_app = cherrypy.tree.apps['']
+ wok_app = cherrypy.tree.apps.get('', None)
# get app from plugin path if specified
if self.plugin:
- app = cherrypy.tree.apps[self.plugin]
+ app = cherrypy.tree.apps.get(self.plugin, None)
# if on request, try to get app from it
elif cherrypy.request.app:
app = cherrypy.request.app
@@ -57,9 +57,12 @@ class WokMessage(object):
else:
app = wok_app
+ if app is None:
+ return self.code
+
# fallback to Wok message in case plugins raise Wok exceptions
- text = app.root.messages.get(self.code, None)
- if text is None:
+ text = app.root.messages.get(self.code, self.code)
+ if text == self.code and wok_app is not None:
app = wok_app
text = app.root.messages.get(self.code, self.code)
--
1.9.1
8 years, 8 months
[PATCH] [Wok] Fix errors in Ginger/Gingerbase/Gingers390x tests
by Lucio Correia
Do not try to translate message when app is not found.
Signed-off-by: Lucio Correia <luciojhc(a)linux.vnet.ibm.com>
---
src/wok/message.py | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/wok/message.py b/src/wok/message.py
index 7ea5711..e4ee640 100644
--- a/src/wok/message.py
+++ b/src/wok/message.py
@@ -45,11 +45,11 @@ class WokMessage(object):
self.plugin = plugin
def _get_translation(self):
- wok_app = cherrypy.tree.apps['']
+ wok_app = cherrypy.tree.apps.get('', None)
# get app from plugin path if specified
if self.plugin:
- app = cherrypy.tree.apps[self.plugin]
+ app = cherrypy.tree.apps.get(self.plugin, None)
# if on request, try to get app from it
elif cherrypy.request.app:
app = cherrypy.request.app
@@ -57,11 +57,13 @@ class WokMessage(object):
else:
app = wok_app
+ if app is None:
+ return self.code
+
# fallback to Wok message in case plugins raise Wok exceptions
- text = app.root.messages.get(self.code, None)
- if text is None:
- app = wok_app
- text = app.root.messages.get(self.code, self.code)
+ text = app.root.messages.get(self.code, self.code)
+ if text == self.code and wok_app is not None:
+ text = wok_app.root.messages.get(self.code, self.code)
# do translation
domain = app.root.domain
--
1.9.1
8 years, 8 months
[PATCH V3] [Wok] Implement Asynchronous Notifications backend
by Lucio Correia
* There is no POST method: a notification is
added through add_notification() method.
* Notifications are always stored in Wok object store under
'notification' type, even if added by a plugin.
* Every time Wok is started, all notifications are erased,
since this is a UI feature, intended to be showed to the
user asynchronously, independent of which tab is opened.
Signed-off-by: Lucio Correia <luciojhc(a)linux.vnet.ibm.com>
---
docs/API/notifications.md | 36 ++++++++++++++++++++++++++
src/wok/control/notifications.py | 37 ++++++++++++++++++++++++++
src/wok/i18n.py | 3 +++
src/wok/model/notifications.py | 56 ++++++++++++++++++++++++++++++++++++++++
src/wok/objectstore.py | 36 ++++++++++++++++++++++++++
src/wok/server.py | 4 +++
6 files changed, 172 insertions(+)
create mode 100644 docs/API/notifications.md
create mode 100644 src/wok/control/notifications.py
create mode 100644 src/wok/model/notifications.py
Changes in V3:
- applied code review suggestions
diff --git a/docs/API/notifications.md b/docs/API/notifications.md
new file mode 100644
index 0000000..85e8463
--- /dev/null
+++ b/docs/API/notifications.md
@@ -0,0 +1,36 @@
+## REST API Specification for Notifications
+
+### Collection: Notifications
+
+**URI:** /notifications
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of current Notifications
+
+#### Examples
+GET /notifications
+[{Notification1}, {Notification2}, ...]
+
+### Resource: Notification
+
+**URI:** /notifications/*:id*
+
+A notification represents an asynchronous warning message sent to the web UI.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of the Notification
+ * code: message ID
+ * message: message text already translated
+ * timestamp: first time notification was emitted
+
+* **DELETE**: Delete the Notification
+
+#### Examples
+GET /notifications/KCHLIBVIRT0001W
+{
+ code: "KCHLIBVIRT0001W",
+ message: "KCHLIBVIRT0001W: Lack of storage space in guest vm-1",
+ timestamp: first time notification was emitted
+}
diff --git a/src/wok/control/notifications.py b/src/wok/control/notifications.py
new file mode 100644
index 0000000..37d45f2
--- /dev/null
+++ b/src/wok/control/notifications.py
@@ -0,0 +1,37 @@
+#
+# Project Wok
+#
+# Copyright IBM Corp, 2016
+#
+# 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 wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode('notifications', True)
+class Notifications(Collection):
+ def __init__(self, model):
+ super(Notifications, self).__init__(model)
+ self.resource = Notification
+
+
+class Notification(Resource):
+ def __init__(self, model, id):
+ super(Notification, self).__init__(model, id)
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/i18n.py b/src/wok/i18n.py
index e6087f4..5a2876f 100644
--- a/src/wok/i18n.py
+++ b/src/wok/i18n.py
@@ -45,6 +45,9 @@ messages = {
"WOKLOG0001E": _("Invalid filter parameter. Filter parameters allowed: %(filters)s"),
"WOKLOG0002E": _("Creation of log file failed: %(err)s"),
+ "WOKNOT0001E": _("Unable to find notification %(id)s"),
+ "WOKNOT0002E": _("Unable to delete notification %(id)s: %(message)s"),
+
"WOKOBJST0001E": _("Unable to find %(item)s in datastore"),
"WOKUTILS0001E": _("Unable to reach %(url)s. Make sure it is accessible and try again."),
diff --git a/src/wok/model/notifications.py b/src/wok/model/notifications.py
new file mode 100644
index 0000000..77184db
--- /dev/null
+++ b/src/wok/model/notifications.py
@@ -0,0 +1,56 @@
+#
+# Project Wok
+#
+# Copyright IBM Corp, 2016
+#
+# 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 wok.exception import NotFoundError, OperationFailed
+from wok.message import WokMessage
+
+
+class NotificationsModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+
+ def get_list(self):
+ with self.objstore as session:
+ return session.get_list('notification')
+
+
+class NotificationModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+
+ def lookup(self, id):
+ with self.objstore as session:
+ notification = session.get('notification', str(id))
+
+ # use WokMessage to translate the notification
+ if notification:
+ timestamp = notification['timestamp']
+ plugin = notification.pop('_plugin_name', None)
+ message = WokMessage(id, notification, plugin).get_text()
+ return {"code": id, "message": message, "timestamp": timestamp}
+
+ raise NotFoundError("WOKNOT0001E", {'id': str(id)})
+
+ def delete(self, id):
+ try:
+ with self.objstore as session:
+ session.delete('notification', str(id))
+ except Exception as e:
+ raise OperationFailed("WOKNOT0002E", {'id': str(id),
+ 'msg': e.msg()})
diff --git a/src/wok/objectstore.py b/src/wok/objectstore.py
index 59354f3..ff3796c 100644
--- a/src/wok/objectstore.py
+++ b/src/wok/objectstore.py
@@ -23,6 +23,8 @@ import sqlite3
import threading
import traceback
+from datetime import datetime
+
try:
from collections import OrderedDict
except ImportError:
@@ -144,3 +146,37 @@ class ObjectStore(object):
# exception again
wok_log.error(traceback.format_exc())
return False
+
+
+def add_notification(code, args={}, plugin_name=None):
+ if not code:
+ wok_log.error("Unable to add notification: invalid code '%(code)s'" %
+ {'code': str(code)})
+ return
+
+ try:
+ with ObjectStore() as session:
+ notification = session.get('notification', code)
+ except NotFoundError:
+ notification = None
+
+ try:
+ # do not update timestamp if notification already exists
+ timestamp = datetime.now().isoformat() if notification is None else \
+ notification['timestamp']
+ args.update({"_plugin_name": plugin_name, "timestamp": timestamp})
+
+ with ObjectStore() as session:
+ session.store('notification', code, args)
+ except Exception as e:
+ wok_log.error("Unable to store notification: %s" % e.message)
+
+
+def clean_notifications():
+ try:
+ with ObjectStore() as session:
+ notifications = session.get_list('notification')
+ for item in notifications:
+ session.delete('notification', item)
+ except Exception as e:
+ wok_log.error("Unable to clean notifications: %s" % e.message)
diff --git a/src/wok/server.py b/src/wok/server.py
index 902d4bf..a329ed4 100644
--- a/src/wok/server.py
+++ b/src/wok/server.py
@@ -33,6 +33,7 @@ from wok.config import config as configParser
from wok.config import paths, PluginConfig, WokConfig
from wok.control import sub_nodes
from wok.model import model
+from wok.objectstore import clean_notifications
from wok.proxy import start_proxy, terminate_proxy
from wok.reqlogger import RequestLogger
from wok.root import WokRoot
@@ -106,6 +107,9 @@ class Server(object):
if dev_env:
cherrypy.log.screen = True
+ # clean object store notifications
+ clean_notifications()
+
# close standard file handlers because we are going to use a
# watchedfiled handler, otherwise we will have two file handlers
# pointing to the same file, duplicating log enries
--
1.9.1
8 years, 8 months
[PATCH] [Wok] Updating Makefile.am to pick fedora spec for the KVMIBM envirnment
by jkatta@linux.vnet.ibm.com
From: Jayavardhan Katta <jkatta(a)linux.vnet.ibm.com>
Signed-off-by: Jayavardhan Katta <jkatta(a)linux.vnet.ibm.com>
---
Makefile.am | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 86d83a0..325d0c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -106,6 +106,8 @@ deb: contrib/make-deb.sh
wok.spec: contrib/wok.spec.fedora contrib/wok.spec.suse
@if test -e /etc/redhat-release; then \
ln -sf contrib/wok.spec.fedora $@ ; \
+ elif test -e /etc/system-release; then \
+ ln -sf contrib/wok.spec.fedora $@ ; \
elif test -e /etc/SuSE-release; then \
ln -sf contrib/wok.spec.suse $@ ; \
else \
--
2.4.3
8 years, 8 months
Patch "Implement WokMessage class" broke Ginger, Ginger-base and Gingers390x unit tests
by Daniel Henrique Barboza
The following WoK patch:
"Implement WokMessage class"
Broke one test case of Ginger 'test_create_existing_user_fails' with the
error message below. With a similar error message, It also broke two
unit tests in Gingerbase and 42 tests in Gingers390x.
======================================================================
ERROR: test_create_existing_user_fails (test_libuser.UserAdmTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File
"/home/danielhb/kimchi/wok_ginger/src/wok/plugins/ginger/tests/test_libuser.py",
line 68, in test_create_existing_user_fails
users.create_user(user, passwd)
File
"/home/danielhb/kimchi/wok_ginger/src/wok/plugins/ginger/model/users.py", line
157, in create_user
raise OperationFailed('GINUSER0008E', {'user': name})
File "/home/danielhb/kimchi/wok_ginger/src/wok/exception.py", line
30, in __init__
msg = WokMessage(code, args).get_text()
File "/home/danielhb/kimchi/wok_ginger/src/wok/message.py", line 79,
in get_text
msg = self._get_translation()
File "/home/danielhb/kimchi/wok_ginger/src/wok/message.py", line 48,
in _get_translation
wok_app = cherrypy.tree.apps['']
KeyError: ''
Unless it is strictly necessary, I would rather not change the code in all
those cases due to this WoK patch and WoK handle this error scenario
by itself. If plug-in changes are required, please advise so I can fix
them as fast as possible.
Regards,
Daniel
8 years, 8 months
[PATCH V2] [Wok] Implement Asynchronous Notifications backend
by Lucio Correia
* There is no POST method: a notification is
added through add_notification() method.
* Notifications are always stored in Wok object store under
'notification' type, even if added by a plugin.
* Every time Wok is started, all notifications are erased,
since this is a UI feature, intended to be showed to the
user asynchronously, independent of which tab is opened.
Signed-off-by: Lucio Correia <luciojhc(a)linux.vnet.ibm.com>
---
docs/API/notifications.md | 34 ++++++++++++++++++++++++
src/wok/control/notifications.py | 37 ++++++++++++++++++++++++++
src/wok/i18n.py | 3 +++
src/wok/model/notifications.py | 56 ++++++++++++++++++++++++++++++++++++++++
src/wok/objectstore.py | 39 ++++++++++++++++++++++++++++
src/wok/server.py | 4 +++
6 files changed, 173 insertions(+)
create mode 100644 docs/API/notifications.md
create mode 100644 src/wok/control/notifications.py
create mode 100644 src/wok/model/notifications.py
Changes in V2:
- added timestamp
- code as required parameter in add_notification
- added DELETE api for notification
This patch depends on WokMessage V3 patch
diff --git a/docs/API/notifications.md b/docs/API/notifications.md
new file mode 100644
index 0000000..851352f
--- /dev/null
+++ b/docs/API/notifications.md
@@ -0,0 +1,34 @@
+## REST API Specification for Notifications
+
+### Collection: Notifications
+
+**URI:** /notifications
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of current Notifications
+
+#### Examples
+GET /notifications
+[{Notification1}, {Notification2}, ...]
+
+### Resource: Notification
+
+**URI:** /notifications/*:id*
+
+A task represents an asynchronous operation that is being performed by the
+server.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of the Notification
+ * code: message ID
+ * message: message text already translated
+
+#### Examples
+GET /notifications/KCHLIBVIRT0001W
+{
+ id: "KCHLIBVIRT0001W",
+ message: "KCHLIBVIRT0001W: Lack of storage space in guest vm-1",
+ timestamp: first time notification was emitted
+}
diff --git a/src/wok/control/notifications.py b/src/wok/control/notifications.py
new file mode 100644
index 0000000..37d45f2
--- /dev/null
+++ b/src/wok/control/notifications.py
@@ -0,0 +1,37 @@
+#
+# Project Wok
+#
+# Copyright IBM Corp, 2016
+#
+# 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 wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode('notifications', True)
+class Notifications(Collection):
+ def __init__(self, model):
+ super(Notifications, self).__init__(model)
+ self.resource = Notification
+
+
+class Notification(Resource):
+ def __init__(self, model, id):
+ super(Notification, self).__init__(model, id)
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/i18n.py b/src/wok/i18n.py
index e6087f4..5a2876f 100644
--- a/src/wok/i18n.py
+++ b/src/wok/i18n.py
@@ -45,6 +45,9 @@ messages = {
"WOKLOG0001E": _("Invalid filter parameter. Filter parameters allowed: %(filters)s"),
"WOKLOG0002E": _("Creation of log file failed: %(err)s"),
+ "WOKNOT0001E": _("Unable to find notification %(id)s"),
+ "WOKNOT0002E": _("Unable to delete notification %(id)s: %(message)s"),
+
"WOKOBJST0001E": _("Unable to find %(item)s in datastore"),
"WOKUTILS0001E": _("Unable to reach %(url)s. Make sure it is accessible and try again."),
diff --git a/src/wok/model/notifications.py b/src/wok/model/notifications.py
new file mode 100644
index 0000000..77184db
--- /dev/null
+++ b/src/wok/model/notifications.py
@@ -0,0 +1,56 @@
+#
+# Project Wok
+#
+# Copyright IBM Corp, 2016
+#
+# 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 wok.exception import NotFoundError, OperationFailed
+from wok.message import WokMessage
+
+
+class NotificationsModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+
+ def get_list(self):
+ with self.objstore as session:
+ return session.get_list('notification')
+
+
+class NotificationModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+
+ def lookup(self, id):
+ with self.objstore as session:
+ notification = session.get('notification', str(id))
+
+ # use WokMessage to translate the notification
+ if notification:
+ timestamp = notification['timestamp']
+ plugin = notification.pop('_plugin_name', None)
+ message = WokMessage(id, notification, plugin).get_text()
+ return {"code": id, "message": message, "timestamp": timestamp}
+
+ raise NotFoundError("WOKNOT0001E", {'id': str(id)})
+
+ def delete(self, id):
+ try:
+ with self.objstore as session:
+ session.delete('notification', str(id))
+ except Exception as e:
+ raise OperationFailed("WOKNOT0002E", {'id': str(id),
+ 'msg': e.msg()})
diff --git a/src/wok/objectstore.py b/src/wok/objectstore.py
index 59354f3..dbc3ee3 100644
--- a/src/wok/objectstore.py
+++ b/src/wok/objectstore.py
@@ -23,6 +23,8 @@ import sqlite3
import threading
import traceback
+from datetime import datetime
+
try:
from collections import OrderedDict
except ImportError:
@@ -144,3 +146,40 @@ class ObjectStore(object):
# exception again
wok_log.error(traceback.format_exc())
return False
+
+
+def add_notification(code, args={}, plugin_name=None):
+ if not code:
+ wok_log.error("Unable to add notification: invalide code '%(code)s'" %
+ {'code': str(code)})
+ return
+
+ found = True
+ try:
+ with ObjectStore() as session:
+ notification = session.get('notification', code)
+ except NotFoundError:
+ found = False
+
+ try:
+ args.update({"_plugin_name": plugin_name,
+ "timestamp": datetime.now().isoformat()})
+
+ # do not update timestamp if notification already exists
+ if found:
+ args["timestamp"] = notification["timestamp"]
+
+ with ObjectStore() as session:
+ session.store('notification', code, args)
+ except Exception as e:
+ wok_log.error("Unable to store notification: %s" % e.message)
+
+
+def clean_notifications():
+ try:
+ with ObjectStore() as session:
+ notifications = session.get_list('notification')
+ for item in notifications:
+ session.delete('notification', item)
+ except Exception as e:
+ wok_log.error("Unable to clean notifications: %s" % e.message)
diff --git a/src/wok/server.py b/src/wok/server.py
index 902d4bf..a329ed4 100644
--- a/src/wok/server.py
+++ b/src/wok/server.py
@@ -33,6 +33,7 @@ from wok.config import config as configParser
from wok.config import paths, PluginConfig, WokConfig
from wok.control import sub_nodes
from wok.model import model
+from wok.objectstore import clean_notifications
from wok.proxy import start_proxy, terminate_proxy
from wok.reqlogger import RequestLogger
from wok.root import WokRoot
@@ -106,6 +107,9 @@ class Server(object):
if dev_env:
cherrypy.log.screen = True
+ # clean object store notifications
+ clean_notifications()
+
# close standard file handlers because we are going to use a
# watchedfiled handler, otherwise we will have two file handlers
# pointing to the same file, duplicating log enries
--
1.9.1
8 years, 8 months
[PATCH] [Wok] Remove unnecessary IDs from navbar
by peterpnns@gmail.com
From: peterpennings <peterpnns(a)gmail.com>
This patch removes unnecessary IDs from navbar to avoid warnings in HTML
peterpennings (1):
Remove unnecessary IDs from navbar
ui/js/src/wok.main.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--
2.5.0
8 years, 8 months
[PATCH V3] [Wok] Implement WokMessage class
by Lucio Correia
WokMessage is a generic message implementation, which looks
up and translates error messages for all plugins and Wok
itself.
Lookup and translation code was adapted from WokException
class, which now just uses WokMessage.
WokMessage is intended to be used by other modules dealing
with messages, such as User Request Log and future feature
Asynchronous Notifications.
Signed-off-by: Lucio Correia <luciojhc(a)linux.vnet.ibm.com>
---
src/wok/exception.py | 45 +++--------------------------
src/wok/message.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+), 41 deletions(-)
create mode 100644 src/wok/message.py
Changes in V3:
- Aline's review
diff --git a/src/wok/exception.py b/src/wok/exception.py
index 023334b..52f007e 100644
--- a/src/wok/exception.py
+++ b/src/wok/exception.py
@@ -20,53 +20,16 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import cherrypy
-import gettext
-from wok.i18n import messages as _messages
-from wok.template import get_lang, validate_language
+from wok.message import WokMessage
class WokException(Exception):
def __init__(self, code='', args={}):
self.code = code
-
- for key, value in args.iteritems():
- if isinstance(value, unicode):
- continue
-
- # value is not unicode: convert it
- try:
- # In case the value formats itself to an ascii string.
- args[key] = unicode(str(value), 'utf-8')
- except UnicodeEncodeError:
- # In case the value is a WokException or it formats
- # itself to a unicode string.
- args[key] = unicode(value)
-
- # First, check if it is a Wok error message, then search in plugin
- # error messages list
- msg = _messages.get(code, code)
- if (msg == code) and (cherrypy.request.app):
- msg = self._get_translation()
-
- msg = unicode(msg, 'utf-8') % args
- pattern = "%s: %s" % (code, msg)
- cherrypy.log.error_log.error(pattern)
- Exception.__init__(self, pattern)
-
- def _get_translation(self):
- lang = validate_language(get_lang())
- paths = cherrypy.request.app.root.paths
- domain = cherrypy.request.app.root.domain
- messages = cherrypy.request.app.root.messages
- text = messages.get(self.code, self.code)
-
- try:
- translation = gettext.translation(domain, paths.mo_dir, [lang])
- except:
- translation = gettext
-
- return translation.gettext(text)
+ msg = WokMessage(code, args).get_text()
+ cherrypy.log.error_log.error(msg)
+ Exception.__init__(self, msg)
class NotFoundError(WokException):
diff --git a/src/wok/message.py b/src/wok/message.py
new file mode 100644
index 0000000..414788c
--- /dev/null
+++ b/src/wok/message.py
@@ -0,0 +1,81 @@
+#
+# Project Wok
+#
+# Copyright IBM Corp, 2015-2016
+#
+# Code derived from Project Kimchi
+#
+# 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 cherrypy
+import gettext
+
+from wok.template import get_lang, validate_language
+
+
+class WokMessage(object):
+ def __init__(self, code='', args={}, plugin=None):
+ # make all args unicode
+ for key, value in args.iteritems():
+ if isinstance(value, unicode):
+ continue
+
+ try:
+ # In case the value formats itself to an ascii string.
+ args[key] = unicode(str(value), 'utf-8')
+ except UnicodeEncodeError:
+ # In case the value is a WokException or it formats
+ # itself to a unicode string.
+ args[key] = unicode(value)
+
+ self.code = code
+ self.args = args
+ self.plugin = plugin
+
+ def _get_translation(self):
+ wok_app = cherrypy.tree.apps['']
+
+ # get app from plugin path if specified
+ if self.plugin:
+ app = cherrypy.tree.apps[self.plugin]
+ # if on request, try to get app from it
+ elif cherrypy.request.app:
+ app = cherrypy.request.app
+ # fallback: get root app (WokRoot)
+ else:
+ app = wok_app
+
+ # fallback to Wok message in case plugins raise Wok exceptions
+ text = app.root.messages.get(self.code, None)
+ if text is None:
+ app = wok_app
+ text = app.root.messages.get(self.code, self.code)
+
+ # do translation
+ domain = app.root.domain
+ paths = app.root.paths
+ lang = validate_language(get_lang())
+
+ try:
+ translation = gettext.translation(domain, paths.mo_dir, [lang])
+ except:
+ translation = gettext
+
+ return translation.gettext(text)
+
+ def get_text(self):
+ msg = self._get_translation()
+ msg = unicode(msg, 'utf-8') % self.args
+ return "%s: %s" % (self.code, msg)
--
1.9.1
8 years, 8 months