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

Aline Manera alinefm at linux.vnet.ibm.com
Mon Feb 9 14:51:18 UTC 2015


On 28/01/2015 11:20, lvroyce at linux.vnet.ibm.com wrote:
> 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):

Prior to the PUT requests we must have a POST to create the volume.

> +        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):




More information about the Kimchi-devel mailing list