Reviewed by: Archana Singh <archus@linux.vnet.ibm.com>


On 09/14/2016 03:02 PM, rajgupta@linux.vnet.ibm.com wrote:
From: Rajat Gupta <rajgupta@linux.vnet.ibm.com>

Introducing s390x UI Storage module for Edit Template under virtualization

Signed-off-by: Rajat Gupta <rajgupta@linux.vnet.ibm.com>
---
 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>