- This patch implements necessary changes in frontend to allow
users to edit and add extra disks to a chosen Template.
- This patch also refactor the UI code in order to avoid lots
of backend calls, improving performance.
- Template disks data saved in objectstore have new fields:
* 'size' is always recorded, even for ISCSI/SCSI types;
* 'storagepooltype' is always recorded;
* example:
"disks":[
{ "index":0,
"format":"raw",
"storagepooltype":"iscsi",
"volume":"unit:0:0:2",
"storagepool":"/plugins/kimchi/storagepools/test-iscsi",
"size":7
},
{ "index":1,
"format":"qcow2",
"storagepooltype":"dir",
"storagepool":"/plugins/kimchi/storagepools/default",
"size":3
}
]
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
---
.../kimchi/ui/js/src/kimchi.template_edit_main.js | 246 ++++++++++-----------
.../kimchi/ui/pages/template-edit.html.tmpl | 5 +-
2 files changed, 124 insertions(+), 127 deletions(-)
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
index 5b77892..dfe770b 100644
--- a/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
@@ -22,7 +22,6 @@ kimchi.template_edit_main = function() {
var origNetworks;
var templateDiskSize;
$('#template-name', templateEditMain).val(kimchi.selectedTemplate);
- //templateEditMain.tabs();
$('#edit-template-tabs
a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(this).attr('href');
@@ -68,134 +67,132 @@ kimchi.template_edit_main = function() {
return false;
}
enableSpice();
+
var initStorage = function(result) {
- var scsipools = {};
+ // Gather storage pool data
+ var storagePoolsInfo = new Object();
+ $.each(result, function(index, pool) {
+ if (pool.state === 'active' && pool.type !=
'kimchi-iso') {
+ if (pool.type === 'iscsi' || pool.type === 'scsi') {
+ volumes = new Object();
+ kimchi.listStorageVolumes(pool.name, function(vols) {
+ $.each(vols, function(i, vol) {
+ storagePoolsInfo[pool.name + "/" + vol.name] =
{
+ 'type' : pool.type,
+ 'volSize': vol.capacity / Math.pow(1024,
3)};
+ });
+ }, null, true);
+ } else {
+ storagePoolsInfo[pool.name] = { 'type' : pool.type };
+ }
+ }
+ });
+
var addStorageItem = function(storageData) {
var thisName = storageData.storageName;
+ // Compatibility with old versions
+ if (storageData.storageVolume) {
+ storageData.storageDisk = storagePoolsInfo[thisName].volSize;
+ }
+ if (!storageData.storageType) {
+ storageData.storageType = storagePoolsInfo[thisName].type;
+ }
+
var nodeStorage =
$.parseHTML(wok.substitute($('#template-storage-pool-tmpl').html(),
storageData));
$('.template-tab-body',
'#form-template-storage').append(nodeStorage);
+ var storageRow = '#storageRow' + storageData.storageIndex;
+
var storageOptions = '';
- var scsiOptions = '';
- $('#selectStorageName').find('option').remove();
- $.each(result, function(index, storageEntities) {
- if((storageEntities.state === 'active') &&
(storageEntities.type != 'kimchi-iso')) {
- if(storageEntities.type === 'iscsi' ||
storageEntities.type === 'scsi') {
- kimchi.listStorageVolumes(storageEntities.name,
function(currentVolume) {
- $.each(currentVolume, function(indexSCSI, scsiEntities)
{
- var tmpPath = storageEntities.name + '/' +
scsiEntities.name;
- var isSlected = tmpPath === thisName ? '
selected' : '';
- scsiOptions += '<option' + isSlected +
'>' + tmpPath + '</option>';
- });
- $('#selectStorageName').append(scsiOptions);
- }, function() {});
- } else {
- var isSlected = storageEntities.name === thisName ? '
selected' : '';
- storageOptions += '<option' + isSlected +
'>' + storageEntities.name + '</option>';
- }
- }
+ $.each(storagePoolsInfo, function(poolName, value) {
+ storageOptions += '<option value="' + poolName +
'">' + poolName + '</option>';
});
- $('#selectStorageName').append(storageOptions);
- $('select','#form-template-storage').selectpicker();
+
+ $(storageRow + ' #selectStorageName').append(storageOptions);
+ $(storageRow + '
#selectStorageName').val(storageData.storageName);
+ $(storageRow + ' #selectStorageName').selectpicker();
+
+ if (storageData.storageType === 'iscsi' ||
storageData.storageType === 'scsi') {
+ $(storageRow + '
.template-storage-disk').attr('readonly', true).prop('disabled',
true);
+ $(storageRow + ' #diskFormat').val('raw');
+ $(storageRow + ' #diskFormat').prop('disabled',
true).change();
+ } else if (storageData.storageType === 'logical') {
+ $(storageRow + ' #diskFormat').val('raw');
+ $(storageRow + ' #diskFormat').prop('disabled',
true).change();
+ }
// Set disk format
if (isImageBasedTemplate()) {
- $('#diskFormat').val('qcow2');
- $('#diskFormat').prop('disabled',
'disabled');
+ $(storageRow + ' #diskFormat').val('qcow2');
+ $(storageRow + ' #diskFormat').prop('disabled',
'disabled');
}
else {
- $('#diskFormat').val(storageData.storageDiskFormat);
- $('#diskFormat').on('change', function() {
- $('.template-storage-disk-format').val($(this).val());
+ $(storageRow + '
#diskFormat').val(storageData.storageDiskFormat);
+ $(storageRow + ' #diskFormat').on('change',
function() {
+ $(storageRow + '
.template-storage-disk-format').val($(this).val());
});
}
+ $(storageRow + ' #diskFormat').selectpicker();
- $('#selectStorageName').change(function() {
- var selectedItem = $(this).parent().parent();
- var tempStorageNameFull = $(this).val();
- var tempName = tempStorageNameFull.split('/');
- var tempStorageName = tempName[0];
- $('.template-storage-name').val(tempStorageNameFull);
- kimchi.getStoragePool(tempStorageName, function(info) {
- tempType = info.type;
-
selectedItem.find('.template-storage-type').val(tempType);
- if (tempType === 'iscsi' || tempType === 'scsi')
{
- kimchi.getStoragePoolVolume(tempStorageName,
tempName[tempName.length-1], function(info) {
- volSize = info.capacity / Math.pow(1024, 3);
- $('.template-storage-disk',
selectedItem).attr('readonly', true).val(volSize);
- if (!isImageBasedTemplate()) {
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled',
true).change();
- }
- });
- } else if (tempType === 'logical') {
- $('.template-storage-disk',
selectedItem).attr('readonly', false);
- if (!isImageBasedTemplate()) {
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled',
true).change();
- }
- } else {
- $('.template-storage-disk',
selectedItem).attr('readonly', false);
- if ($('#diskFormat').prop('disabled') == true
&&
- !isImageBasedTemplate()) {
- $('#diskFormat').val('qcow2');
- $('#diskFormat').prop('disabled',
false).change();
- }
- }
- });
+ $('.delete', '#form-template-storage').on(
"click",function(event) {
+ event.preventDefault();
+ $(this).parent().parent().remove();
});
- };
-
- if ((origDisks && origDisks.length) && (origPool &&
origPool.length)) {
- splitPool = origPool.split('/');
- var defaultPool = splitPool[splitPool.length-1];
- var defaultType;
- kimchi.getStoragePool(defaultPool, function(info) {
- defaultType = info.type;
- $.each(origDisks, function(index, diskEntities) {
- var storageNodeData = {
- viewMode : '',
- editMode : 'hide',
- storageName : defaultPool,
- storageType : defaultType,
- storageDisk : diskEntities.size,
- storageDiskFormat : diskEntities.format ? diskEntities.format
: 'qcow2'
+ $(storageRow + ' #selectStorageName').change(function() {
+ var poolType = storagePoolsInfo[$(this).val()].type;
+ $(storageRow + '
.template-storage-name').val($(this).val());
+ $(storageRow + ' .template-storage-type').val(poolType);
+ if (poolType === 'iscsi' || poolType === 'scsi') {
+ $(storageRow + '
.template-storage-disk').attr('readonly', true).prop('disabled',
true).val(storagePoolsInfo[$(this).val()].volSize);
+ if (!isImageBasedTemplate()) {
+ $(storageRow + '
#diskFormat').val('raw').prop('disabled', true).change();
}
-
- if (diskEntities.volume) {
- kimchi.getStoragePoolVolume(defaultPool, diskEntities.volume,
function(info) {
- var volSize = info.capacity / Math.pow(1024, 3);
- var nodeData = storageNodeData
- nodeData.storageName = defaultPool + '/' +
diskEntities.volume;
- nodeData.storageDisk = volSize;
- addStorageItem(nodeData);
-
$('.template-storage-disk').attr('readonly', true);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled',
true).change();
- });
- } else if (defaultType === 'logical') {
- addStorageItem(storageNodeData);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled',
true).change();
- } else {
- addStorageItem(storageNodeData);
+ } else if (poolType === 'logical') {
+ $(storageRow + '
.template-storage-disk').attr('readonly', false).prop('disabled',
false);
+ if (!isImageBasedTemplate()) {
+ $(storageRow + '
#diskFormat').val('raw').prop('disabled', true).change();
}
- });
+ } else {
+ $(storageRow + '
.template-storage-disk').attr('readonly', false).prop('disabled',
false);
+ if ($(storageRow + '
#diskFormat').prop('disabled') == true && !isImageBasedTemplate()) {
+ $(storageRow + '
#diskFormat').val('qcow2').prop('disabled', false).change();
+ }
+ }
+ $(storageRow + '
#diskFormat').selectpicker('refresh');
+ });
+ }; // End of addStorageItem funtion
+
+ if ((origDisks && origDisks.length) && (origPool &&
origPool.length)) {
+ origDisks.sort(function(a, b){return a.index-b.index});
+ $.each(origDisks, function(index, diskEntities) {
+ var defaultPool = diskEntities.storagepool ?
diskEntities.storagepool.split('/').pop() : origPool.split('/').pop()
+ var storageNodeData = {
+ storageIndex : diskEntities.index,
+ storageName : diskEntities.volume ? defaultPool + '/' +
diskEntities.volume : defaultPool,
+ storageType : diskEntities.storagepooltype,
+ storageDisk : diskEntities.size,
+ storageDiskFormat : diskEntities.format ? diskEntities.format :
'qcow2',
+ storageVolume : diskEntities.volume
+ }
+ addStorageItem(storageNodeData);
});
}
+ var storageID = origDisks.length -1;
$('#template-edit-storage-add-button').on("click",
function(event) {
event.preventDefault();
+ storageID = storageID + 1;
var storageNodeData = {
- viewMode : 'hide',
- editMode : '',
- storageName : 'null',
+ storageName : 'default',
storageType : 'dir',
- storageDisk : '10'
+ storageDisk : '10',
+ storageDiskFormat : 'qcow2',
+ storageIndex : storageID
}
addStorageItem(storageNodeData);
});
};
+
var initInterface = function(result) {
var networkItemNum = 0;
var addInterfaceItem = function(networkData) {
@@ -235,6 +232,7 @@ kimchi.template_edit_main = function() {
});
});
};
+
var initProcessor = function(){
var setCPUValue = function(){
if(!$('#cores').hasClass("invalid-field")&&$('#cores').val()!=""){
@@ -278,36 +276,32 @@ kimchi.template_edit_main = function() {
};
kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
-
$('#tmpl-edit-button-save').on('click', function() {
- var editableFields = [ 'name', 'memory', 'disks',
'graphics'];
+ var editableFields = [ 'name', 'memory', 'graphics'];
var data = {};
- //Fix me: Only support one storage pool now
- var storages = $('.template-tab-body .item',
'#form-template-storage');
- var tempName = $('.template-storage-name', storages).val();
- var tmpItem = $('#form-template-storage .item');
- tempName = tempName.split('/');
- var tempNameHead = tempName[0];
- var tempNameTail = tempNameHead;
- if($('.template-storage-type', tmpItem).val() === 'iscsi' ||
$('.template-storage-type', tmpItem).val() == 'scsi') {
- tempNameTail = tempName[tempName.length-1];
- }
- tempName = '/plugins/kimchi/storagepools/' + tempNameHead;
- data['storagepool'] = tempName;
- $.each(editableFields, function(i, field) {
- /* Support only 1 disk at this moment */
- if (field == 'disks') {
- if($('.template-storage-type', tmpItem).val() === 'iscsi'
|| $('.template-storage-type', tmpItem).val() == 'scsi') {
- origDisks[0]['size'] && delete
origDisks[0]['size'];
- origDisks[0]['volume'] = tempNameTail;
- } else {
- origDisks[0]['volume'] && delete
origDisks[0]['volume'];
- origDisks[0].size = Number($('.template-storage-disk',
tmpItem).val());
- }
- origDisks[0].format = $('.template-storage-disk-format',
tmpItem).val();
- data[field] = origDisks;
+ var disks = $('.template-tab-body .item',
'#form-template-storage');
+ var disksForUpdate = new Array();
+ $.each(disks, function(index, diskEntity) {
+ var newDisk = {
+ 'index' : index,
+ 'storagepool' : '/plugins/kimchi/storagepools/' +
$(diskEntity).find('.template-storage-name').val(),
+ 'size' :
Number($(diskEntity).find('.template-storage-disk').val()),
+ 'format' :
$(diskEntity).find('.template-storage-disk-format').val()
+ };
+
+ var storageType =
$(diskEntity).find('.template-storage-type').val();
+ newDisk['storagepooltype'] = storageType;
+
+ if(storageType === 'iscsi' || storageType === 'scsi') {
+ newDisk['volume'] =
newDisk['storagepool'].split('/').pop();
+ newDisk['storagepool'] = newDisk['storagepool'].slice(0,
newDisk['storagepool'].lastIndexOf('/'));
}
- else if (field == 'graphics') {
+ disksForUpdate.push(newDisk);
+ });
+ data.disks = disksForUpdate;
+
+ $.each(editableFields, function(i, field) {
+ if (field == 'graphics') {
var type = $('#form-template-general [name="' + field +
'"]').val();
data[field] = {'type': type};
}
diff --git a/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
index 59a2cfa..dc6b762 100644
--- a/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
+++ b/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
@@ -156,7 +156,7 @@
kimchi.template_edit_main();
</script>
<script id="template-storage-pool-tmpl" type="text/html">
- <div class='item'>
+ <div id="storageRow{storageIndex}" class='item'>
<span class="template-storage-cell storage-pool">
<input class="template-storage-name" value={storageName}
type="text" style="display:none" />
<select id="selectStorageName"></select>
@@ -182,6 +182,9 @@
<option value="vpc">vpc</option>
</select>
</span>
+ <span class="pull-right">
+ <button class="delete btn-primary btn"><i class="fa
fa-minus-circle"></i> $_("Delete")</button>
+ </span>
</div>
</script>
<script id="template-interface-tmpl" type="text/html">
--
2.1.0