On 09/09/2016 04:23 AM, rajgupta(a)linux.vnet.ibm.com wrote:
From: Rajat Gupta <rajgupta(a)linux.vnet.linux.com>
Introducing s390x UI Storage module for Edit Template under virtualization
Signed-off-by: Rajat Gupta <rajgupta(a)linux.vnet.linux.com>
---
ui/css/kimchi.css | 12 +-
ui/css/src/modules/_templates.scss | 10 +-
ui/js/src/kimchi.template_edit_main.js | 277 ++++++++++++++++++++++++++++-----
ui/pages/template-edit.html.tmpl | 11 ++
4 files changed, 268 insertions(+), 42 deletions(-)
diff --git a/ui/css/kimchi.css b/ui/css/kimchi.css
index 6cf2cc9..e0e05c7 100644
--- a/ui/css/kimchi.css
+++ b/ui/css/kimchi.css
@@ -1597,7 +1597,15 @@ body.wok-gallery {
}
#template-edit-window .template-storage-cell.storage-pool {
- width: 220px !important;
+ width: 180px !important;
+}
+
+#template-edit-window .template-storage-cell.storage-path {
+ width: 180px !important;
+}
+
+#template-edit-window .template-storage-cell.source {
+ width: 180px !important;
}
#template-edit-window .template-storage-cell.type {
@@ -1609,7 +1617,7 @@ body.wok-gallery {
}
#template-edit-window .template-storage-cell.format {
- width: 320px;
+ width: 250px;
}
#template-edit-window .template-interface-cell.network {
diff --git a/ui/css/src/modules/_templates.scss b/ui/css/src/modules/_templates.scss
index a75d803..2ae7412 100644
--- a/ui/css/src/modules/_templates.scss
+++ b/ui/css/src/modules/_templates.scss
@@ -158,7 +158,13 @@ $kimchi-icon-path: '../images';
height: selectpicker height - 2px;
}
.template-storage-cell.storage-pool {
- width: 220px !important;
+ width: 180px !important;
+ }
+ .template-storage-cell.storage-path {
+ width: 180px !important;
+ }
+ .template-storage-cell.source {
+ width: 180px !important;
}
.template-storage-cell.type {
width: 100px;
@@ -167,7 +173,7 @@ $kimchi-icon-path: '../images';
width: 100px;
}
.template-storage-cell.format {
- width: 320px;
+ width: 250px;
}
.template-interface-cell.network {
width: 220px;
diff --git a/ui/js/src/kimchi.template_edit_main.js
b/ui/js/src/kimchi.template_edit_main.js
index a2032cc..6b79fed 100644
--- a/ui/js/src/kimchi.template_edit_main.js
+++ b/ui/js/src/kimchi.template_edit_main.js
@@ -226,6 +226,185 @@ kimchi.template_edit_main = function() {
});
};
+ var initStorage_s390 = function(result) {
+ // Gather storage 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) {
+ if (storageData.storageSource == 'pool') {
+ 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 = '';
+ $.each(storagePoolsInfo, function(poolName, value) {
+ storageOptions += '<option value="' + poolName +
'">' + poolName + '</option>';
+ });
+
+
+ $(storageRow + ' .selectStorageName').append(storageOptions);
+ if (storageData.storageSource == 'pool') {
+ if (!$(storageRow + ' .selectStorageName
option[value="' + storageData.storageName + '"]').length) {
+ var invalidOption = '<option
disabled="disabled" selected="selected" value="' +
storageData.storageName + '">' + storageData.storageName +
'</option>';
+ $(storageRow + '
.selectStorageName').prepend(invalidOption);
+ $(storageRow + '
.selectStorageName').parent().addClass('has-error')
+ }
+ $(storageRow + '
.selectStorageName').val(storageData.storageName);
+ $(storageRow + ' span.storage-pool').show();
+ $(storageRow + ' span.storage-path').hide();
+ } else {
+ $(storageRow + ' span.storage-pool').hide();
+ $(storageRow + ' span.storage-path').show();
+ }
+
+ $(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 source
+ $('#form-template-storage span.source').show();
+ $(storageRow + ' #source').val(storageData.storageSource);
+ $(storageRow + ' #source').on('change', function() {
+ var source = $(this).val();
+ $(storageRow + ' .template-storage-source').val(source);
+ if (source == 'path') {
+ $(storageRow + ' span.storage-pool').hide();
+ $(storageRow + ' span.storage-path').show();
+ } else {
+ $(storageRow + ' span.storage-pool').show();
+ $(storageRow + ' span.storage-path').hide();
+ }
+ });
+
+ $(storageRow + ' #source').selectpicker();
+
+
+
+ // Set disk format
+ if (isImageBasedTemplate()) {
+ $(storageRow + ' #diskFormat').val('qcow2');
+ $(storageRow + ' #diskFormat').prop('disabled',
'disabled');
+ } else {
+ $(storageRow + '
#diskFormat').val(storageData.storageDiskFormat);
+ $(storageRow + ' #diskFormat').on('change',
function() {
+ $(storageRow + '
.template-storage-disk-format').val($(this).val());
+ });
+ }
+ $(storageRow + ' #diskFormat').selectpicker();
+
+ $('.delete',
'#form-template-storage').on("click", function(event) {
+ event.preventDefault();
+ $(this).parent().parent().remove();
+ });
+
+ $(storageRow + ' select.selectStorageName').change(function() {
+ $(this).parent().parent().removeClass('has-error');
+ 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();
+ }
+ } 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) {
+ origDisks.sort(function(a, b) {
+ return a.index - b.index
+ });
+ $.each(origDisks, function(index, diskEntities) {
+ if (typeof diskEntities.pool !== 'undefined') {
+ var defaultPool =
diskEntities.pool.name.split('/').pop()
+ var storageNodeData = {
+ storageSource: 'pool',
+ storageName: diskEntities.volume ? defaultPool + '/'
+ diskEntities.volume : defaultPool,
+ storageType: diskEntities.pool.type,
+ storageIndex: diskEntities.index,
+ storageDisk: diskEntities.size,
+ storageDiskFormat: diskEntities.format ? diskEntities.format
: 'qcow2',
+ storageVolume: diskEntities.volume
+ }
+ } else {
+ var storageNodeData = {
+ storageSource: 'path',
+ storagePath: diskEntities.path,
+ storageType: 'dir',
+ storageIndex: diskEntities.index,
+ 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 = {
+ storageSource: 'pool',
+ storageName: 'default',
+ storageType: 'dir',
+ storageDisk: '10',
+ storageDiskFormat: 'qcow2',
+ storageIndex: storageID
+ }
+ addStorageItem(storageNodeData);
+ });
+ };
+
var initInterface = function(result) {
var networkItemNum = 0;
var addInterfaceItem = function(networkData) {
@@ -340,49 +519,71 @@ kimchi.template_edit_main = function() {
});
}
- kimchi.listNetworks(initInterface);
- kimchi.listStoragePools(initStorage);
+ if (kimchi.hostarch === s390xArch) {
+ kimchi.listmacvtapNetworks(function(macvtapnet) {
+ origmacvtapNetworks = macvtapnet;
+ kimchi.listovsNetworks(function(ovsnet) {
+ origovsNetworks = ovsnet;
+ kimchi.listNetworks(initInterface_s390x);
+ });
+ });
+
+ kimchi.listStoragePools(initStorage_s390);
+ } else {
+ kimchi.listNetworks(initInterface);
+ kimchi.listStoragePools(initStorage);
+ }
+
initProcessor();
checkInvalids();
- };
- kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
-
+ };
+ kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
$('#tmpl-edit-button-save').on('click', function() {
- $button = $(this);
- $button.html('<span class="wok-loading-icon" /> ' +
i18n['KCHAPI6010M']);
- $button.prop('disabled', true);
- $('.modal .wok-mask').removeClass('hidden');
- $('.modal input[type="text"]').prop('disabled',
true);
- $('.modal input[type="checkbox"]').prop('disabled',
true);
- $('.modal select').prop('disabled', true);
- $('.modal .selectpicker').addClass('disabled');
- var editableFields = ['name', 'memory', 'graphics',
'max-memory'];
- var data = {};
- var disks = $('.template-tab-body .item',
'#form-template-storage');
- var disksForUpdate = new Array();
- $.each(disks, function(index, diskEntity) {
- var newDisk = {
- 'index': index,
- 'pool': { 'name':
'/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()
- };
-
- // image based template: add base to dictionary
- if ((baseImageTemplate) && (index == 0)) {
- newDisk["base"] =
$('#template-edit-vmimage-textbox').val();
- }
+ $button = $(this);
+ $button.html('<span class="wok-loading-icon" />
' + i18n['KCHAPI6010M']);
+ $button.prop('disabled', true);
+ $('.modal .wok-mask').removeClass('hidden');
+ $('.modal
input[type="text"]').prop('disabled', true);
+ $('.modal
input[type="checkbox"]').prop('disabled', true);
+ $('.modal select').prop('disabled', true);
+ $('.modal .selectpicker').addClass('disabled');
+ var editableFields = ['name', 'memory',
'graphics', 'max-memory'];
+ var data = {};
+ var disks = $('.template-tab-body .item',
'#form-template-storage');
+ var disksForUpdate = new Array();
+ $.each(disks, function(index, diskEntity) {
+ if (kimchi.hostarch == s390xArch &&
($(diskEntity).find('.template-storage-source').val()) == 'path') {
+ var newDisk = {
+ 'index': index,
+ 'path':
$(diskEntity).find('.template-storage-path').val(),
+ 'size':
Number($(diskEntity).find('.template-storage-disk').val()),
+ 'format':
$(diskEntity).find('.template-storage-disk-format').val()
+ };
+ } else {
+ var newDisk = {
+ 'index': index,
+ 'pool': {
+ 'name': '/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()
+ };
+
Why did you change the indentation level here?
}
- var storageType =
$(diskEntity).find('.template-storage-type').val();
- if (storageType === 'iscsi' || storageType === 'scsi') {
- newDisk['volume'] =
newDisk['pool']['name'].split('/').pop();
- newDisk['pool']['name'] =
newDisk['pool']['name'].slice(0,
newDisk['pool']['name'].lastIndexOf('/'));
- delete newDisk.size;
- }
- disksForUpdate.push(newDisk);
- });
- data.disks = disksForUpdate;
+ // image based template: add base to dictionary
+ if ((baseImageTemplate) && (index == 0)) {
+ newDisk["base"] =
$('#template-edit-vmimage-textbox').val();
+ }
+ var storageType =
$(diskEntity).find('.template-storage-type').val();
+ if (storageType === 'iscsi' || storageType ===
'scsi') {
+ newDisk['volume'] =
newDisk['pool']['name'].split('/').pop();
+ newDisk['pool']['name'] =
newDisk['pool']['name'].slice(0,
newDisk['pool']['name'].lastIndexOf('/'));
+ delete newDisk.size;
+ }
+ disksForUpdate.push(newDisk);
+ });
+ data.disks = disksForUpdate;
$.each(editableFields, function(i, field) {
if (field == 'graphics') {
var type = $('#form-template-general [name="' + field +
'"]').val();
diff --git a/ui/pages/template-edit.html.tmpl b/ui/pages/template-edit.html.tmpl
index 6cac885..33533a1 100644
--- a/ui/pages/template-edit.html.tmpl
+++ b/ui/pages/template-edit.html.tmpl
@@ -110,6 +110,7 @@
<div role="tabpanel" class="tab-pane"
id="storage">
<form id="form-template-storage">
<div class="template-tab-header">
+ <span class="template-storage-cell source"
style="display:none">$_("Source")</span>
<span class="template-storage-cell
storage-pool">$_("Storage Pool")</span>
<span class="template-storage-cell
type">$_("Type")</span>
<span class="template-storage-cell
disk">$_("Disk(GB)")</span>
@@ -182,10 +183,20 @@
</script>
<script id="template-storage-pool-tmpl" type="text/html">
<div id="storageRow{storageIndex}" class='item'>
+ <span class="template-storage-cell source"
style="display:none">
+ <input class="template-storage-source" value={storageSource}
type="text" style="display:none" />
+ <select id="source">
+ <option value="pool">pool</option>
+ <option value="path">path</option>
+ </select>
+ </span>
<span class="template-storage-cell storage-pool">
<input class="template-storage-name"
value="{storageName}" type="text" style="display:none"
/>
<select id="selectStorageName-{storageIndex}"
class="selectStorageName"></select>
</span>
+ <span class="template-storage-cell storage-path"
style="display:none">
+ <input class="template-storage-path storage-path form-control"
value="{storagePath}" type="text" />
+ </span>
<span class="template-storage-cell type">
<input class="template-storage-type form-control"
value={storageType} readonly=true type="text" />
</span>