[Kimchi-devel] [PATCH] [Kimchi] Introducing s390x UI Storage module for Edit Template under virtualization

rajgupta at linux.vnet.ibm.com rajgupta at linux.vnet.ibm.com
Fri Sep 9 07:23:25 UTC 2016


From: Rajat Gupta <rajgupta at linux.vnet.linux.com>

Introducing s390x UI Storage module for Edit Template under virtualization

Signed-off-by: Rajat Gupta <rajgupta at 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()
+                        };
+                    }
 
-            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>
-- 
2.1.0




More information about the Kimchi-devel mailing list