From: Royce Lv <lvroyce(a)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(a)linux.vnet.ibm.com>
---
src/kimchi/model/storagevolumes.py | 58 ++++++++++++++++----------------------
1 file changed, 24 insertions(+), 34 deletions(-)
diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py
index 48f715e..b6a17da 100644
--- a/src/kimchi/model/storagevolumes.py
+++ b/src/kimchi/model/storagevolumes.py
@@ -33,6 +33,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 f_open, flock
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
@@ -57,7 +58,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')
@@ -88,9 +89,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())
@@ -119,36 +118,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 = """
@@ -417,6 +386,27 @@ class StorageVolumeModel(object):
cb('OK', True)
+ def update(self, pool, name, params):
+ vol = self._get_storagevolume(pool, name)
+ path = vol.path()
+
+ size = int(params['chunk_size'])
+ index = int(params['index'])
+ pos = size * index
+ try:
+ with f_open(path, 'a+') as fp:
+ with flock(fp, pos, size):
+ fp.seek(pos)
+ fp.write(params['chunk'].fullvalue())
+ except Exception as e:
+ raise OperationFailed('KCHVOL0007E',
+ {'name': name,
+ 'pool': pool,
+ 'err': e.message})
+
+ # 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):
--
1.9.3