[Kimchi-devel] [PATCH V3] Fix Kimchi model

Lucio Correia luciojhc at linux.vnet.ibm.com
Tue Oct 20 16:43:16 UTC 2015


With the Kimchi/Wok split, the Tasks model is now outside of
Kimchi's model tree and needs to be imported separately. This
patch does that and creates function get_instances() to
avoid code duplication.

It also fixes related documentation and URIs to use
/plugins/kimchi/tasks, which is now exported by Kimchi.

Signed-off-by: Lucio Correia <luciojhc at linux.vnet.ibm.com>
---
 src/wok/plugins/kimchi/docs/API.md                 | 33 ++++++++++++++++++++++
 src/wok/plugins/kimchi/model/model.py              | 28 +++++++++++++-----
 src/wok/plugins/kimchi/tests/test_host.py          |  4 +--
 .../plugins/kimchi/tests/test_mock_storagepool.py  |  2 +-
 .../kimchi/tests/test_model_storagevolume.py       |  8 +++---
 src/wok/plugins/kimchi/tests/test_rest.py          | 24 ++++++++--------
 src/wok/plugins/kimchi/ui/js/src/kimchi.api.js     |  4 +--
 7 files changed, 75 insertions(+), 28 deletions(-)

diff --git a/src/wok/plugins/kimchi/docs/API.md b/src/wok/plugins/kimchi/docs/API.md
index ccc843f..e7f399b 100644
--- a/src/wok/plugins/kimchi/docs/API.md
+++ b/src/wok/plugins/kimchi/docs/API.md
@@ -35,6 +35,39 @@ the following general conventions:
     * Variable segments in the URI begin with a ':' and should replaced with the
       appropriate resource identifier.
 
+
+### Collection: Tasks
+
+**URI:** /plugins/kimchi/tasks
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of current Kimchi specific Tasks (stored
+in Kimchi's object store)
+
+### Resource: Task
+
+**URI:** /plugins/kimchi/tasks/*:id*
+
+A task represents an asynchronous operation that is being performed by the
+server.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of the Task
+    * id: The Task ID is used to identify this Task in the API.
+    * status: The current status of the Task
+        * running: The task is running
+        * finished: The task has finished successfully
+        * failed: The task failed
+    * message: Human-readable details about the Task status
+    * target_uri: Resource URI related to the Task
+* **POST**: *See Task Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
 ### Collection: Virtual Machines
 
 **URI:** /plugins/kimchi/vms
diff --git a/src/wok/plugins/kimchi/model/model.py b/src/wok/plugins/kimchi/model/model.py
index 0c94f63..8335552 100644
--- a/src/wok/plugins/kimchi/model/model.py
+++ b/src/wok/plugins/kimchi/model/model.py
@@ -30,23 +30,37 @@ from libvirtconnection import LibvirtConnection
 class Model(BaseModel):
     def __init__(self, libvirt_uri=None, objstore_loc=None):
 
+        def get_instances(module_name):
+            instances = []
+            module = import_module(module_name)
+            members = inspect.getmembers(module, inspect.isclass)
+            for cls_name, instance in members:
+                if inspect.getmodule(instance) == module and \
+                   cls_name.endswith('Model'):
+                    instances.append(instance)
+
+            return instances
+
         self.objstore = ObjectStore(objstore_loc)
         self.conn = LibvirtConnection(libvirt_uri)
         kargs = {'objstore': self.objstore, 'conn': self.conn}
+        models = []
 
+        # Import task model from Wok
+        instances = get_instances('wok.model.tasks')
+        for instance in instances:
+            models.append(instance(**kargs))
+
+        # Import all Kimchi plugin models
         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('plugins.kimchi.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))
+            instances = get_instances('wok.plugins.kimchi.model.' + mod_name)
+            for instance in instances:
+                models.append(instance(**kargs))
 
         return super(Model, self).__init__(models)
diff --git a/src/wok/plugins/kimchi/tests/test_host.py b/src/wok/plugins/kimchi/tests/test_host.py
index f3da49b..2940f48 100644
--- a/src/wok/plugins/kimchi/tests/test_host.py
+++ b/src/wok/plugins/kimchi/tests/test_host.py
@@ -128,12 +128,12 @@ class HostTests(unittest.TestCase):
         task_params = [u'id', u'message', u'status', u'target_uri']
         self.assertEquals(sorted(task_params), sorted(task.keys()))
 
-        resp = self.request('/tasks/' + task[u'id'], None,
+        resp = self.request('/plugins/kimchi/tasks/' + task[u'id'], None,
                             'GET')
         task_info = json.loads(resp.read())
         self.assertEquals(task_info['status'], 'running')
         wait_task(_task_lookup, task_info['id'])
-        resp = self.request('/tasks/' + task[u'id'], None,
+        resp = self.request('/plugins/kimchi/tasks/' + task[u'id'], None,
                             'GET')
         task_info = json.loads(resp.read())
         self.assertEquals(task_info['status'], 'finished')
diff --git a/src/wok/plugins/kimchi/tests/test_mock_storagepool.py b/src/wok/plugins/kimchi/tests/test_mock_storagepool.py
index 5cf5b3e..ea9843b 100644
--- a/src/wok/plugins/kimchi/tests/test_mock_storagepool.py
+++ b/src/wok/plugins/kimchi/tests/test_mock_storagepool.py
@@ -61,7 +61,7 @@ class MockStoragepoolTests(unittest.TestCase):
 
     def _task_lookup(self, taskid):
         return json.loads(
-            self.request('/tasks/%s' % taskid).read()
+            self.request('/plugins/kimchi/tasks/%s' % taskid).read()
         )
 
     def test_storagepool(self):
diff --git a/src/wok/plugins/kimchi/tests/test_model_storagevolume.py b/src/wok/plugins/kimchi/tests/test_model_storagevolume.py
index 8812e46..087dd7b 100644
--- a/src/wok/plugins/kimchi/tests/test_model_storagevolume.py
+++ b/src/wok/plugins/kimchi/tests/test_model_storagevolume.py
@@ -64,7 +64,7 @@ def tearDownModule():
 def _do_volume_test(self, model, host, ssl_port, pool_name):
     def _task_lookup(taskid):
         return json.loads(
-            self.request('/tasks/%s' % taskid).read()
+            self.request('/plugins/kimchi/tasks/%s' % taskid).read()
         )
 
     uri = '/plugins/kimchi/storagepools/%s/storagevolumes' \
@@ -91,7 +91,7 @@ def _do_volume_test(self, model, host, ssl_port, pool_name):
             task_id = json.loads(resp.read())['id']
             wait_task(_task_lookup, task_id)
             status = json.loads(
-                self.request('/tasks/%s' % task_id).read()
+                self.request('/plugins/kimchi/tasks/%s' % task_id).read()
             )
             self.assertEquals('finished', status['status'])
             vol_info = json.loads(self.request(vol_uri).read())
@@ -137,7 +137,7 @@ def _do_volume_test(self, model, host, ssl_port, pool_name):
                                   cloned_vol_name)
             wait_task(_task_lookup, task['id'])
             task = json.loads(
-                self.request('/tasks/%s' % task['id']).read()
+                self.request('/plugins/kimchi/tasks/%s' % task['id']).read()
             )
             self.assertEquals('finished', task['status'])
             resp = self.request(uri + '/' + cloned_vol_name.encode('utf-8'))
@@ -177,7 +177,7 @@ def _do_volume_test(self, model, host, ssl_port, pool_name):
             self.assertEquals(202, resp.status)
             task_id = json.loads(resp.read())['id']
             wait_task(_task_lookup, task_id)
-            status = json.loads(self.request('/tasks/%s' %
+            status = json.loads(self.request('/plugins/kimchi/tasks/%s' %
                                              task_id).read())
             self.assertEquals('ready for upload', status['message'])
 
diff --git a/src/wok/plugins/kimchi/tests/test_rest.py b/src/wok/plugins/kimchi/tests/test_rest.py
index 8cf4bd3..e1a2f54 100644
--- a/src/wok/plugins/kimchi/tests/test_rest.py
+++ b/src/wok/plugins/kimchi/tests/test_rest.py
@@ -335,7 +335,7 @@ class RestTests(unittest.TestCase):
         task = json.loads(resp.read())
         wait_task(self._task_lookup, task['id'])
         task = json.loads(
-            self.request('/tasks/%s' % task['id'], '{}').read()
+            self.request('/plugins/kimchi/tasks/%s' % task['id'], '{}').read()
         )
         self.assertEquals('finished', task['status'])
         clone_vm_name = task['target_uri'].split('/')[-2]
@@ -366,7 +366,7 @@ class RestTests(unittest.TestCase):
         task = json.loads(resp.read())
         wait_task(self._task_lookup, task['id'])
         task = json.loads(
-            self.request('/tasks/%s' % task['id']).read()
+            self.request('/plugins/kimchi/tasks/%s' % task['id']).read()
         )
         self.assertEquals('finished', task['status'])
 
@@ -404,7 +404,7 @@ class RestTests(unittest.TestCase):
         task = json.loads(resp.read())
         snap_name = task['target_uri'].split('/')[-1]
         wait_task(self._task_lookup, task['id'])
-        resp = self.request('/tasks/%s' % task['id'], '{}',
+        resp = self.request('/plugins/kimchi/tasks/%s' % task['id'], '{}',
                             'GET')
         task = json.loads(resp.read())
         self.assertEquals('finished', task['status'])
@@ -1172,37 +1172,37 @@ class RestTests(unittest.TestCase):
 
     def _task_lookup(self, taskid):
         return json.loads(
-            self.request('/tasks/%s' % taskid).read()
+            self.request('/plugins/kimchi/tasks/%s' % taskid).read()
         )
 
     def test_tasks(self):
-        id1 = add_task('/tasks/1', self._async_op,
+        id1 = add_task('/plugins/kimchi/tasks/1', self._async_op,
                        model.objstore)
-        id2 = add_task('/tasks/2', self._except_op,
+        id2 = add_task('/plugins/kimchi/tasks/2', self._except_op,
                        model.objstore)
-        id3 = add_task('/tasks/3', self._intermid_op,
+        id3 = add_task('/plugins/kimchi/tasks/3', self._intermid_op,
                        model.objstore)
 
-        target_uri = urllib2.quote('^/tasks/*', safe="")
+        target_uri = urllib2.quote('^/plugins/kimchi/tasks/*', safe="")
         filter_data = 'status=running&target_uri=%s' % target_uri
         tasks = json.loads(
-            self.request('/tasks?%s' % filter_data).read()
+            self.request('/plugins/kimchi/tasks?%s' % filter_data).read()
         )
         self.assertEquals(3, len(tasks))
 
-        tasks = json.loads(self.request('/tasks').read())
+        tasks = json.loads(self.request('/plugins/kimchi/tasks').read())
         tasks_ids = [int(t['id']) for t in tasks]
         self.assertEquals(set([id1, id2, id3]) - set(tasks_ids), set([]))
         wait_task(self._task_lookup, id2)
         foo2 = json.loads(
-            self.request('/tasks/%s' % id2).read()
+            self.request('/plugins/kimchi/tasks/%s' % id2).read()
         )
         keys = ['id', 'status', 'message', 'target_uri']
         self.assertEquals(sorted(keys), sorted(foo2.keys()))
         self.assertEquals('failed', foo2['status'])
         wait_task(self._task_lookup, id3)
         foo3 = json.loads(
-            self.request('/tasks/%s' % id3).read()
+            self.request('/plugins/kimchi/tasks/%s' % id3).read()
         )
         self.assertEquals('in progress', foo3['message'])
         self.assertEquals('running', foo3['status'])
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
index a16c95e..bb3a53d 100644
--- a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
@@ -525,7 +525,7 @@ var kimchi = {
 
     getTask : function(taskId, suc, err) {
         wok.requestJSON({
-            url : 'tasks/' + encodeURIComponent(taskId),
+            url : 'plugins/kimchi/tasks/' + encodeURIComponent(taskId),
             type : 'GET',
             contentType : 'application/json',
             dataType : 'json',
@@ -536,7 +536,7 @@ var kimchi = {
 
     getTasksByFilter : function(filter, suc, err, sync) {
         wok.requestJSON({
-            url : 'tasks?' + filter,
+            url : 'plugins/kimchi/tasks?' + filter,
             type : 'GET',
             contentType : 'application/json',
             dataType : 'json',
-- 
1.9.1




More information about the Kimchi-devel mailing list