<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>Reviewed by: Archana Singh <a class="moz-txt-link-rfc2396E"
href="mailto:archus@linux.vnet.ibm.com"><archus@linux.vnet.ibm.com></a></p>
<br>
<div class="moz-cite-prefix">On 09/14/2016 03:02 PM,
<a class="moz-txt-link-abbreviated" href="mailto:rajgupta@linux.vnet.ibm.com">rajgupta@linux.vnet.ibm.com</a> wrote:<br>
</div>
<blockquote
cite="mid:1473845521-30198-1-git-send-email-rajgupta@linux.vnet.ibm.com"
type="cite">
<pre wrap="">From: Rajat Gupta <a class="moz-txt-link-rfc2396E" href="mailto:rajgupta@linux.vnet.ibm.com"><rajgupta@linux.vnet.ibm.com></a>
Introducing s390x UI Storage module for Edit Template under virtualization
Signed-off-by: Rajat Gupta <a class="moz-txt-link-rfc2396E" href="mailto:rajgupta@linux.vnet.ibm.com"><rajgupta@linux.vnet.ibm.com></a>
---
ui/css/kimchi.css | 12 +-
ui/css/src/modules/_templates.scss | 10 +-
ui/js/src/kimchi.template_edit_main.js | 214 +++++++++++++++++++++++++++++++--
ui/pages/template-edit.html.tmpl | 11 ++
4 files changed, 235 insertions(+), 12 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..92ce977 100644
--- a/ui/js/src/kimchi.template_edit_main.js
+++ b/ui/js/src/kimchi.template_edit_main.js
@@ -226,6 +226,181 @@ 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,8 +515,20 @@ 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();
};
@@ -361,12 +548,23 @@ kimchi.template_edit_main = function() {
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()
- };
+ 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()
+ };
+ }
// image based template: add base to dictionary
if ((baseImageTemplate) && (index == 0)) {
diff --git a/ui/pages/template-edit.html.tmpl b/ui/pages/template-edit.html.tmpl
index 6cac885..432f986 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>
</pre>
</blockquote>
<br>
</body>
</html>