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

Aline Manera alinefm at linux.vnet.ibm.com
Tue Oct 20 13:59:11 UTC 2015



On 19/10/2015 14:45, Lucio Correia wrote:
> 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..39097c4 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('plugins.kimchi.model.' + mod_name)

I suspect it should be 'wok.plugins.kimchi.model'

> +            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',




More information about the Kimchi-devel mailing list