[Kimchi-devel] [PATCH 4/5] Storage Pool Add Volume UI: Connect the Feature in Storage Tab
Aline Manera
alinefm at linux.vnet.ibm.com
Mon Sep 15 21:28:52 UTC 2014
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>
---
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>
--
1.9.3
More information about the Kimchi-devel
mailing list