[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