[Kimchi-devel] [PATCH 4/5] Storage Pool Add Volume UI: Connect the Feature in Storage Tab

Hongliang Wang hlwang at linux.vnet.ibm.com
Tue Sep 16 10:11:57 UTC 2014


On 09/16/2014 05:28 AM, Aline Manera wrote:
> From: Hongliang Wang <hlwang at linux.vnet.ibm.com>
>
> Connect download/upload volume window with storage pool add button.
>
> Signed-off-by: Hongliang Wang <hlwang at linux.vnet.ibm.com>
> Signed-off-by: Aline Manera <alinefm at linux.vnet.ibm.com>
Reviewed-by: Hongliang Wang <hlwang at linux.vnet.ibm.com>
> ---
>   ui/css/theme-default/storage.css |  31 ++++++-
>   ui/js/src/kimchi.storage_main.js | 196 ++++++++++++++++++++++++++++++++++-----
>   ui/pages/tabs/storage.html.tmpl  |  12 ++-
>   3 files changed, 213 insertions(+), 26 deletions(-)
>
> diff --git a/ui/css/theme-default/storage.css b/ui/css/theme-default/storage.css
> index f635c2f..e0ab290 100644
> --- a/ui/css/theme-default/storage.css
> +++ b/ui/css/theme-default/storage.css
> @@ -336,7 +336,6 @@
>       float: left;
>       padding: 4px;
>       margin-bottom: 5px;
> -    height: 40px;
>       width: 130px;
>   }
>
> @@ -622,3 +621,33 @@
>   #iSCSITarget input {
>       width: 493px;
>   }
> +
> +/* Progress bar */
> +.volume-progress {
> +    clear: both;
> +    width: 140px;
> +}
> +
> +.volume-progress .progress-bar-outer {
> +    background: #ccc;
> +    height: 4px;
> +    overflow: hidden;
> +    width: 100%;
> +}
> +
> +.volume-progress .progress-bar-inner {
> +    background: #090;
> +    height: 100%;
> +    width: 0%;
> +}
> +
> +.volume-progress .progress-label {
> +    color: #999;
> +    font-size: 10px;
> +    line-height: 16px;
> +}
> +
> +.volume-progress .progress-transferred {
> +    float: right;
> +}
> +/* End of Progress bar */
> diff --git a/ui/js/src/kimchi.storage_main.js b/ui/js/src/kimchi.storage_main.js
> index ae3f963..28b2b58 100644
> --- a/ui/js/src/kimchi.storage_main.js
> +++ b/ui/js/src/kimchi.storage_main.js
> @@ -42,7 +42,6 @@ kimchi.doListStoragePools = function() {
>       }, function(err) {
>           kimchi.message.error(err.responseJSON.reason);
>       });
> -
>   }
>
>   kimchi.storageBindClick = function() {
> @@ -79,6 +78,19 @@ kimchi.storageBindClick = function() {
>           }
>       });
>
> +    $('.pool-add-volume').each(function(index) {
> +        var canAddVolume =
> +            $(this).data('stat') === 'active' &&
> +            $(this).data('type') !== 'iscsi' &&
> +            $(this).data('type') !== 'scsi';
> +        if(canAddVolume) {
> +            $(this).show();
> +        }
> +        else {
> +            $(this).hide();
> +        }
> +    });
> +
>       if(kimchi.tabMode['storage'] === 'admin') {
>           $('.pool-delete').on('click', function(event) {
>               var $pool = $(this);
> @@ -135,6 +147,12 @@ kimchi.storageBindClick = function() {
>               }
>           });
>
> +        $('.pool-add-volume').on('click', function(event) {
> +            var poolName = $(this).data('name');
> +            kimchi.selectedSP = poolName;
> +            kimchi.window.open('storagepool-add-volume.html');
> +        });
> +
>           $('.storage-action').on('click', function() {
>               var storage_action = $(this);
>               var deleteButton = storage_action.find('.pool-delete');
> @@ -149,10 +167,6 @@ kimchi.storageBindClick = function() {
>               $("#logicalPoolExtend").dialog("option", "poolName", $(this).data('name'));
>               $("#logicalPoolExtend").dialog("open");
>           });
> -
> -        $('#volume-doAdd').on('click', function() {
> -            kimchi.window.open('storagevolume-add.html');
> -        });
>       }
>
>       $('.storage-li').on('click', function(event) {
> @@ -173,29 +187,90 @@ kimchi.storageBindClick = function() {
>       });
>   }
>
> +kimchi._generateVolumeHTML = function(volume) {
> +    if(volume['type'] === 'kimchi-iso') {
> +        return '';
> +    }
> +    var volumeHtml = $('#volumeTmpl').html();
> +    volume.capacity = kimchi.changetoProperUnit(volume.capacity,1);
> +    volume.allocation = kimchi.changetoProperUnit(volume.allocation,1);
> +    return kimchi.substitute(volumeHtml, volume);
> +};
> +
>   kimchi.doListVolumes = function(poolObj) {
> -    var volumeDiv = $('#volume' + poolObj.data('name'));
> +    var poolName = poolObj.data('name')
> +
> +    var getOngoingVolumes = function() {
> +        var result = {}
> +        var filter = 'status=running&target_uri=' + encodeURIComponent('^/storagepools/' + poolName + '/*')
> +        kimchi.getTasksByFilter(filter, function(tasks) {
> +            for(var i = 0; i < tasks.length; i++) {
> +                var volumeName = tasks[i].target_uri.split('/').pop();
> +                result[volumeName] = tasks[i];
> +
> +                if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
> +                    continue;
> +                }
> +
> +                kimchi.trackTask(tasks[i].id, function(result) {
> +                    kimchi.topic('kimchi/volumeTransferFinished').publish(result);
> +                }, function(result) {
> +                    kimchi.topic('kimchi/volumeTransferError').publish(result);
> +                }, function(result) {
> +                    kimchi.topic('kimchi/volumeTransferProgress').publish(result);
> +                });
> +            }
> +        }, null, true);
> +        return result;
> +    };
> +
> +    var volumeDiv = $('#volume' + poolName);
> +    $(volumeDiv).empty();
>       var slide = poolObj.next('.volumes');
>       var handleArrow = poolObj.children().last().children();
> -    kimchi.listStorageVolumes(poolObj.data('name'), function(result) {
> -        var volumeHtml = $('#volumeTmpl').html();
> -        if (result) {
> -            if (result.length) {
> -                var listHtml = '';
> -                $.each(result, function(index, value) {
> -                    value.poolname = poolObj.data('name');
> -                    value.capacity = kimchi.changetoProperUnit(value.capacity,1);
> -                    value.allocation = kimchi.changetoProperUnit(value.allocation,1);
> -                    listHtml += kimchi.substitute(volumeHtml, value);
> -                });
> -                volumeDiv.html(listHtml);
> -            } else {
> -                volumeDiv.html("<div class='pool-empty'>" + i18n['KCHPOOL6002M'] + "</div>");
> +
> +    kimchi.listStorageVolumes(poolName, function(result) {
> +        var listHtml = '';
> +        var ongoingVolumes = [];
> +        var ongoingVolumesMap = getOngoingVolumes();
> +        $.each(ongoingVolumesMap, function(volumeName, task) {
> +            ongoingVolumes.push(volumeName)
> +            var volume = {
> +                poolName: poolName,
> +                ref_cnt: 0,
> +                capacity: 0,
> +                name: volumeName,
> +                format: '',
> +                bootable: null,
> +                os_distro: '',
> +                allocation: 0,
> +                os_version: '',
> +                path: '',
> +                type: 'file'
> +            };
> +            listHtml += kimchi._generateVolumeHTML(volume);
> +        });
> +
> +        $.each(result, function(index, value) {
> +            if (ongoingVolumes.indexOf(value.name) == -1) {
> +                value.poolname = poolName;
> +                listHtml += kimchi._generateVolumeHTML(value);
>               }
> -            poolObj.removeClass('in');
> -            kimchi.changeArrow(handleArrow);
> -            slide.slideDown('slow');
> +        });
> +
> +        if (listHtml.length > 0) {
> +            volumeDiv.html(listHtml);
> +        } else {
> +            volumeDiv.html("<div class='pool-empty'>" + i18n['KCHPOOL6002M'] + "</div>");
>           }
> +
> +        $.each(ongoingVolumesMap, function(volumeName, task) {
> +            kimchi.topic('kimchi/volumeTransferProgress').publish(task);
> +        });
> +
> +        poolObj.removeClass('in');
> +        kimchi.changeArrow(handleArrow);
> +        slide.slideDown('slow');
>       }, function(err) {
>           kimchi.message.error(err.responseJSON.reason);
>       });
> @@ -255,7 +330,80 @@ kimchi.storage_main = function() {
>       }
>       kimchi.doListStoragePools();
>       kimchi.initLogicalPoolExtend();
> -}
> +
> +    kimchi.topic('kimchi/storageVolumeAdded').subscribe(function() {
> +        pool = kimchi.selectedSP;
> +        var poolNode = $('.storage-li[data-name="' + pool + '"]');
> +        kimchi.doListVolumes(poolNode);
> +    });
> +
> +    kimchi.topic('kimchi/volumeTransferProgress').subscribe(function(result) {
> +        var extractProgressData = function(data) {
> +            var sizeArray = /(\d+)\/(\d+)/g.exec(data) || [0, 0, 0];
> +            var downloaded = sizeArray[1];
> +            var percent = 0;
> +            if(downloaded) {
> +                var total = sizeArray[2];
> +                if(!isNaN(total)) {
> +                    percent = downloaded / total * 100;
> +                }
> +            }
> +            var formatted = kimchi.formatMeasurement(downloaded);
> +            var size = (1.0 * formatted['v']).toFixed(1) + formatted['s'];
> +            return {
> +                size: size,
> +                percent: percent
> +            };
> +        };
> +
> +        var uriElements = result.target_uri.split('/');
> +        var poolName = uriElements[2];
> +        var volumeName = uriElements.pop();
> +        var progress = extractProgressData(result['message']);
> +        var size = progress['size'];
> +        var percent = progress['percent'];
> +
> +        volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
> +        $('.progress-bar-inner', volumeBox).css({
> +            width: percent + '%'
> +        });
> +        $('.progress-transferred', volumeBox).text(size);
> +        $('.volume-progress', volumeBox).removeClass('hidden');
> +        $('.progress-status', volumeBox).text(i18n['KCHPOOL6014M']);
> +    });
> +
> +    kimchi.topic('kimchi/volumeTransferFinished').subscribe(function(result) {
> +        var uriElements = result.target_uri.split('/');
> +        var poolName = uriElements[2];
> +        var volumeName = uriElements.pop();
> +        var volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
> +        $('.volume-progress', volumeBox).addClass('hidden');
> +        kimchi.getStoragePoolVolume(poolName, volumeName, function(volume) {
> +            var html = kimchi._generateVolumeHTML(volume);
> +            $(volumeBox).replaceWith(html);
> +        }, function(err) {
> +            kimchi.message.error(err.responseJSON.reason);
> +        });
> +    });
> +
> +    kimchi.topic('kimchi/volumeTransferError').subscribe(function(result) {
> +        // Error message from Async Task status
> +        if (result['message']) {
> +            var errText = result['message'];
> +        }
> +        // Error message from standard kimchi exception
> +        else {
> +            var errText = result['responseJSON']['reason'];
> +        }
> +        result && kimchi.message.error(errText);
> +
> +        var uriElements = result.target_uri.split('/');
> +        var poolName = uriElements[2];
> +        var volumeName = uriElements.pop();
> +        volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
> +        $('.progress-status', volumeBox).text(i18n['KCHPOOL6015M']);
> +    });
> +};
>
>   kimchi.changeArrow = function(obj) {
>       if ($(obj).hasClass('arrow-down')) {
> diff --git a/ui/pages/tabs/storage.html.tmpl b/ui/pages/tabs/storage.html.tmpl
> index 87205bd..523f480 100644
> --- a/ui/pages/tabs/storage.html.tmpl
> +++ b/ui/pages/tabs/storage.html.tmpl
> @@ -82,6 +82,7 @@
>                       <div class="popover actionsheet right-side" style="width: 250px">
>                           <button class="button-big pool-deactivate" data-stat="{state}" data-name="{name}" data-persistent="{persistent}"><span class="text">$_("Deactivate")</span></button>
>                           <button class="button-big pool-activate" data-stat="{state}" data-name="{name}"><span class="text">$_("Activate")</span></button>
> +                        <button class="button-big pool-add-volume" data-stat="{state}" data-name="{name}" data-type="{type}"><span class="text">$_("Add Volume")</span></button>
>                           <button class="button-big pool-extend {enableExt}" data-stat="{state}" data-name="{name}"><span class="text">$_("Extend")</span></button>
>                           <button class="button-big red pool-delete" data-stat="{state}" data-name="{name}"><span class="text">$_("Undefine")</span></button>
>                       </div>
> @@ -98,11 +99,20 @@
>       </li>
>   </script>
>   <script id="volumeTmpl" type="html/text">
> -        <div class="volume-box white-box">
> +        <div class="volume-box white-box" data-volume-name="{name}">
>               <div class="storage-icon volume-default icon-{format} ">
>               </div>
>               <div class="volume-title">
>                   <div class="volume-name" title="{name}">{name}</div>
> +                <div class="volume-progress hidden">
> +                    <div class="progress-bar-outer">
> +                        <div class="progress-bar-inner"></div>
> +                    </div>
> +                    <div class="progress-label">
> +                        <span class="progress-status"></span>
> +                        <span class="progress-transferred"></span>
> +                    </div>
> +                </div>
>               </div>
>               <div class="volume-setting">
>               </div>




More information about the Kimchi-devel mailing list