[Kimchi-devel] [kimchi-devel][PATCHv3 4/6] Update model for storage volume update

lvroyce at linux.vnet.ibm.com lvroyce at linux.vnet.ibm.com
Wed Jan 28 13:20:29 UTC 2015


From: Royce Lv <lvroyce at linux.vnet.ibm.com>

Storage update abandoned async task because mem copy is not long lasting
task and does not need to use task to track its status.
So update just do the data upload, and following storage volume lookup
will take care of current upload progress.

Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
---
 src/kimchi/i18n.py                 |  1 +
 src/kimchi/model/storagevolumes.py | 61 +++++++++++++++++---------------------
 2 files changed, 28 insertions(+), 34 deletions(-)

diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index af912bd..af0dc4f 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -211,6 +211,7 @@ messages = {
     "KCHVOL0022E": _("Unable to access file %(url)s. Please, check it."),
     "KCHVOL0023E": _("Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)s"),
     "KCHVOL0024E": _("Upload volume chunk index, size and total size must be integer"),
+    "KCHVOL0025E": _("Upload volume fails. Details: %(err)s"),
     "KCHVOL0026E": _("Inconsistent upload count"),
 
     "KCHIFACE0001E": _("Interface %(name)s does not exist"),
diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py
index cb79966..ff99972 100644
--- a/src/kimchi/model/storagevolumes.py
+++ b/src/kimchi/model/storagevolumes.py
@@ -34,6 +34,7 @@ from kimchi.isoinfo import IsoImage
 from kimchi.model.diskutils import get_disk_ref_cnt
 from kimchi.model.storagepools import StoragePoolModel
 from kimchi.model.tasks import TaskModel
+from kimchi.model.utils import get_vol_update_lock, release_vol_update_lock
 from kimchi.utils import add_task, get_next_clone_name, get_unique_file_name
 from kimchi.utils import kimchi_log
 from kimchi.xmlutils.utils import xpath_get_text
@@ -58,7 +59,7 @@ class StorageVolumesModel(object):
         self.task = TaskModel(**kargs)
 
     def create(self, pool_name, params):
-        vol_source = ['file', 'url', 'capacity']
+        vol_source = ['url', 'capacity']
 
         name = params.get('name')
 
@@ -89,9 +90,7 @@ class StorageVolumesModel(object):
             # if 'name' is omitted - except for the methods listed in
             # 'REQUIRE_NAME_PARAMS' - the default volume name will be the
             # file/URL basename.
-            if create_param == 'file':
-                name = os.path.basename(params['file'].filename)
-            elif create_param == 'url':
+            if create_param == 'url':
                 name = os.path.basename(params['url'])
             else:
                 name = 'upload-%s' % int(time.time())
@@ -120,36 +119,6 @@ class StorageVolumesModel(object):
         taskid = add_task(targeturi, create_func, self.objstore, params)
         return self.task.lookup(taskid)
 
-    def _create_volume_with_file(self, cb, params):
-        pool_name = params.pop('pool')
-        dir_path = StoragePoolModel(
-            conn=self.conn, objstore=self.objstore).lookup(pool_name)['path']
-        file_path = os.path.join(dir_path, params['name'])
-        if os.path.exists(file_path):
-            raise InvalidParameter('KCHVOL0001E', {'name': params['name']})
-
-        upload_file = params['file']
-        f_len = upload_file.fp.length
-        try:
-            size = 0
-            with open(file_path, 'wb') as f:
-                while True:
-                    data = upload_file.file.read(READ_CHUNK_SIZE)
-                    if not data:
-                        break
-                    size += len(data)
-                    f.write(data)
-                    cb('%s/%s' % (size, f_len))
-        except Exception as e:
-            raise OperationFailed('KCHVOL0007E',
-                                  {'name': params['name'],
-                                   'pool': pool_name,
-                                   'err': e.message})
-
-        # Refresh to make sure volume can be found in following lookup
-        StoragePoolModel.get_storagepool(pool_name, self.conn).refresh(0)
-        cb('OK', True)
-
     def _create_volume_with_capacity(self, cb, params):
         pool_name = params.pop('pool')
         vol_xml = """
@@ -464,6 +433,30 @@ class StorageVolumeModel(object):
 
         cb('OK', True)
 
+    def update(self, pool, name, params):
+        vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+        vol_path = vol.path()
+
+        chunk_size = int(params['chunk_size'])
+        index = int(params['index'])
+        pos = chunk_size * index
+        lock = get_vol_update_lock(vol_path)
+        try:
+            with lock:
+                st = self.conn.get().newStream(0)
+                vol.upload(st, pos, chunk_size)
+                st.send(params['chunk'].fullvalue())
+                st.finish()
+        except Exception as e:
+            st and st.abort()
+            raise OperationFailed('KCHVOL0025E',
+                                  {'err': e.message})
+        finally:
+            release_vol_update_lock(vol_path)
+
+        # Refresh to make sure volume can be found in following lookup
+        StoragePoolModel.get_storagepool(pool, self.conn).refresh(0)
+
 
 class IsoVolumesModel(object):
     def __init__(self, **kargs):
-- 
2.1.0




More information about the Kimchi-devel mailing list