[Kimchi-devel] [PATCH] [Kimchi] Introducing s390x UI Interfaces module for Edit Guest under virtualization

rajgupta at linux.vnet.ibm.com rajgupta at linux.vnet.ibm.com
Wed Sep 7 15:23:33 UTC 2016


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

Introducing s390x UI Interfaces module for Edit Guest under virtualization

Signed-off-by: Rajat Gupta <rajgupta at linux.vnet.ibm.com>
---
 ui/css/kimchi.css                    |  26 +++-
 ui/css/src/modules/_edit-guests.scss |  23 ++-
 ui/js/src/kimchi.guest_edit_main.js  | 282 ++++++++++++++++++++++++++++++++---
 ui/pages/guest-edit.html.tmpl        |  40 +++++
 4 files changed, 341 insertions(+), 30 deletions(-)

diff --git a/ui/css/kimchi.css b/ui/css/kimchi.css
index 6cf2cc9..9299c38 100644
--- a/ui/css/kimchi.css
+++ b/ui/css/kimchi.css
@@ -1028,7 +1028,7 @@ body.wok-gallery {
 }
 
 #guest-edit-window #form-guest-edit-interface .column-actions {
-  width: 23%;
+  width: 20%;
 }
 
 #guest-edit-window #form-guest-edit-storage .column-actions {
@@ -1088,19 +1088,25 @@ body.wok-gallery {
 #guest-edit-window form .header .cell.column-type,
 #guest-edit-window form .task .cell.column-type,
 #guest-edit-window form .body .cell.column-type {
-  width: 11.35%;
+  width: 18%;
+}
+
+#guest-edit-window form .header .cell.column-mode,
+#guest-edit-window form .task .cell.column-mode,
+#guest-edit-window form .body .cell.column-mode {
+  width: 16%;
 }
 
 #guest-edit-window form .header .cell.column-mac,
 #guest-edit-window form .task .cell.column-mac,
 #guest-edit-window form .body .cell.column-mac {
-  width: 14.5%;
+  width: 14%;
 }
 
 #guest-edit-window form .header .cell.column-ip,
 #guest-edit-window form .task .cell.column-ip,
 #guest-edit-window form .body .cell.column-ip {
-  width: 31%;
+  width: 12%;
 }
 
 #guest-edit-window form .header .cell.column-sel,
@@ -1239,6 +1245,18 @@ body.wok-gallery {
   width: 180px;
 }
 
+#guest-edit-window form .header .cell.column-mode .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn),
+#guest-edit-window form .task .cell.column-mode .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn),
+#guest-edit-window form .body .cell.column-mode .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn) {
+  width: 160px;
+}
+
+#guest-edit-window form .header .cell.column-type .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn),
+#guest-edit-window form .task .cell.column-type .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn),
+#guest-edit-window form .body .cell.column-type .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn) {
+  width: 180px;
+}
+
 .guest-edit-snapshot .hide,
 .guest-edit-interface .hide {
   display: none !important;
diff --git a/ui/css/src/modules/_edit-guests.scss b/ui/css/src/modules/_edit-guests.scss
index b7e6941..632d634 100644
--- a/ui/css/src/modules/_edit-guests.scss
+++ b/ui/css/src/modules/_edit-guests.scss
@@ -48,7 +48,7 @@
     }
     #form-guest-edit-interface {
         .column-actions {
-            width: 23%;
+            width: 20%;
         }
     }
     #form-guest-edit-storage {
@@ -94,13 +94,16 @@
                 }
             }
             .cell.column-type {
-                width: 11.35%;
+                width: 18%;
+            }
+            .cell.column-mode {
+                width: 16%;
             }
             .cell.column-mac {
-                width: 14.5%;
+                width: 14%;
             }
             .cell.column-ip {
-                width: 31%;
+                width: 12%;
             }
             .cell.column-sel {
                 width: 1.77%;
@@ -204,6 +207,18 @@
   width: 180px;
 }
 
+#guest-edit-window form .header .cell.column-mode .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn),
+#guest-edit-window form .task .cell.column-mode .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn),
+#guest-edit-window form .body .cell.column-mode .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn) {
+  width: 160px;
+}
+
+#guest-edit-window form .header .cell.column-type .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn),
+#guest-edit-window form .task .cell.column-type .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn),
+#guest-edit-window form .body .cell.column-type .bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn) {
+  width: 180px;
+}
+
 .guest-edit-snapshot .hide,
 .guest-edit-interface .hide {
     display: none !important;
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index dcaafb8..cc899ff 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -20,6 +20,11 @@ kimchi.guest_edit_main = function() {
     var formTargetId;
     var guestEditForm = $('#form-guest-edit-general');
     var saveButton = $('#guest-edit-button-save');
+    var s390xArch = 's390x';
+    var macvtapNetworks = "";
+    var ovsNetworks = "";
+    var networkOptions = "";
+
     clearTimeout(kimchi.vmTimeout);
 
     $('#modalWindow').on('hidden.bs.modal', function() {
@@ -176,14 +181,28 @@ kimchi.guest_edit_main = function() {
             });
         });
         var toggleEdit = function(item, on, itemId) {
+          if(kimchi.hostarch === s390xArch){
+              $("#label-mac-" + itemId, item).toggleClass("hide", on);
+              $("#edit-mac-" + itemId, item).toggleClass("hide", !on);
+              $("#label-network-" + itemId, item).toggleClass("hide", false);
+              $("#label-type-" + itemId, item).toggleClass("hide", false);
+              $("#label-mode-" + itemId, item).toggleClass("hide", false);
+              $("select", item).toggleClass("hide", true);
+              $(".bootstrap-select", item).toggleClass("hide", true);
+              $(".action-area", item).toggleClass("hide");
+
+          }else {
+
             $("#label-mac-" + itemId, item).toggleClass("hide", on);
             $("#edit-mac-" + itemId, item).toggleClass("hide", !on);
             $("#label-network-" + itemId, item).toggleClass("hide", false);
             $("select", item).toggleClass("hide", true);
             $(".bootstrap-select", item).toggleClass("hide", true);
             $(".action-area", item).toggleClass("hide");
+          }
         };
         var addItem = function(data) {
+            var oriID = data.id;
             if (data.id === -1) {
                 data.id = $('#form-guest-edit-interface > .body').children().size();
             }
@@ -192,13 +211,28 @@ kimchi.guest_edit_main = function() {
             } else {
                 data.ips = data.ips;
             }
-            var itemNode = $.parseHTML(wok.substitute($('#interface-tmpl').html(), data));
-            $(".body", "#form-guest-edit-interface").append(itemNode);
-            $("select", itemNode).append(networkOptions);
-            $("select", itemNode).selectpicker();
-            if (data.network !== "") {
-                $("select", itemNode).val(data.network);
+            if (kimchi.hostarch === s390xArch) {
+                data.mode = (data.mode) ? data.mode : 'None';
+                var itemNode = $.parseHTML(wok.substitute($('#interface-s390x-tmpl').html(), data));
+                $(".body", "#form-guest-edit-interface").append(itemNode);
+
+                $("select", "span.column-type", itemNode).empty().append(typeOptions);
+                $("select", "span.column-mode", itemNode).empty().append(modeOptions);
+                $("select", "span.column-network", itemNode).empty().append(macvtapNetworks);
+
+                $("select", "span.column-type", itemNode).val(data.type);
+                $("select", "span.column-network", itemNode).val(data.source);
+                $("select", "span.column-mode", itemNode).val(data.mode);
+
+            } else {
+                var itemNode = $.parseHTML(wok.substitute($('#interface-tmpl').html(), data));
+                $(".body", "#form-guest-edit-interface").append(itemNode);
+                $("select", "span.column-network", itemNode).append(networkOptions);
             }
+
+            $("select", itemNode).selectpicker();
+
+
             $('.edit', itemNode).attr('disabled', kimchi.thisVMState === "running");
             $(".edit", itemNode).on('click', function(evt) {
                 evt.preventDefault();
@@ -214,22 +248,122 @@ kimchi.guest_edit_main = function() {
             $(".save", itemNode).on('click', function(evt) {
                 evt.preventDefault();
                 var item = $(this).parent().parent();
-                var interface = {
-                    network: $("select", item).val(),
-                        type: "network",
-                        mac: $(":text", item).val(),
-                        ips: $(".ipText", item).val()
-                };
+
+                if (kimchi.hostarch === s390xArch) {
+                    if (item.prop("id") === "") { //adding new interface
+                        switch ($("span.column-type select", item).val()) {
+                            case 'macvtap':
+                                var interface = {
+                                    source: $("span.column-network select", item).val(),
+                                        type: $("span.column-type select", item).val(),
+                                        mac: $(":text", item).val(),
+                                        ips: $(".ipText", item).val(),
+                                        mode: $("span.column-mode select", item).val()
+                                };
+                                break;
+
+                            case 'ovs':
+                                var interface = {
+                                    source: $("span.column-network select", item).val(),
+                                        type: $("span.column-type select", item).val(),
+                                        mac: $(":text", item).val(),
+                                        ips: $(".ipText", item).val()
+                                };
+                                break;
+
+                            case 'network':
+                                var interface = {
+                                    network: $("span.column-network select", item).val(),
+                                        type: "network",
+                                        mac: $(":text", item).val(),
+                                        ips: $(".ipText", item).val()
+                                };
+                                break;
+                        }
+                    } else { //updating existing interface
+
+                        switch ($("#label-type-" + data.id, item).text()) {
+                            case 'macvtap':
+
+                                var interface = {
+                                    source: $("#label-network-" + data.id, item).text(),
+                                        type: $("#label-type-" + data.id, item).text(),
+                                        mac: $(":text", item).val(),
+                                        ips: $(".ipText", item).val(),
+                                        mode: $("#label-mode-" + data.id, item).text()
+                                };
+                                break;
+
+                            case 'ovs':
+                                var interface = {
+                                    source: $("#label-network-" + data.id, item).text(),
+                                        type: $("#label-type-" + data.id, item).text(),
+                                        mac: $(":text", item).val(),
+                                        ips: $(".ipText", item).val()
+                                };
+                                break;
+
+                            case 'network':
+                                var interface = {
+                                    network: $("#label-network-" + data.id, item).text(),
+                                        type: "network",
+                                        mac: $(":text", item).val(),
+                                        ips: $(".ipText", item).val()
+                                };
+                                break;
+                        }
+
+                    }
+                } else { //in s86 arch
+                    var interface = {
+                        network: $("select", item).val(),
+                            type: "network",
+                            mac: $(":text", item).val(),
+                            ips: $(".ipText", item).val()
+                    };
+                }
+
                 var postUpdate = function(mac) {
                     $("#label-network-" + data.id, item).text(interface.network);
                     $("#label-mac-" + data.id, item).text(mac);
                     $("#edit-mac-" + data.id, item).val(mac);
                     toggleEdit(item, false, data.id);
                 };
+
+                var posts390xUpdate = function(result) {
+                    switch(result.type){
+                      case 'macvtap' :
+                                      $("#label-type-" + data.id, item).text(result.type);
+                                      $("#label-network-" + data.id, item).text(result.source);
+                                      $("#label-mode-" + data.id, item).text(result.mode);
+                           break;
+
+                      case 'ovs' :
+                                      $("#label-type-" + data.id, item).text(result.type);
+                                      $("#label-network-" + data.id, item).text(result.source);
+                                      $("#label-mode-" + data.id, item).text('None');
+                          break;
+
+                      case 'network' :
+                                      $("#label-type-" + data.id, item).text(result.type);
+                                      $("#label-network-" + data.id, item).text(result.network);
+                                      $("#label-mode-" + data.id, item).text('None');
+                            break;
+                    }
+
+                    $("#label-mac-" + data.id, item).text(result.mac);
+                    $("#edit-mac-" + data.id, item).val(result.mac);
+                    toggleEdit(item, false, data.id);
+                };
+
                 if (item.prop("id") === "") {
                     kimchi.createGuestInterface(kimchi.selectedGuest, interface, function(data) {
                         item.prop("id", data.mac);
-                        postUpdate(data.mac);
+                        if(kimchi.hostarch == s390xArch){
+                          posts390xUpdate(data);
+                        }else{
+                          postUpdate(data.mac);
+                        }
                     });
                 } else {
                     if (item.prop('id') === interface.mac) {
@@ -249,22 +383,126 @@ kimchi.guest_edit_main = function() {
                 var item = $(this).parent().parent();
                 $("label", item).text() === "" ? item.remove() : toggleEdit(item, false, data.id);
             });
+
+            if (kimchi.hostarch === s390xArch) {
+                $("#interface-s390x-type-" + data.id).on('change', function() {
+                    var itemNode = $(this).closest('div.item');
+                    switch ($(this).val()) {
+                        case 'macvtap':
+                            $('#label-mode-' + data.id).addClass('hide');
+                            $('span.column-mode .bootstrap-select', itemNode).toggleClass("hide", false);
+
+                            $("span.column-network select", itemNode).empty().append(macvtapNetworks);
+                            $("span.column-network select", itemNode).selectpicker('refresh');
+
+                            break;
+                        case 'ovs':
+                            $('#label-mode-' + data.id).html('None');
+                            $('#label-mode-' + data.id).removeClass('hide');
+                            $('span.column-mode .bootstrap-select', itemNode).toggleClass("hide", true);
+
+                            $("span.column-network select", itemNode).empty().append(ovsNetworks);
+                            $("span.column-network select", itemNode).selectpicker('refresh');
+                            break;
+                        case 'network':
+                            $('#label-mode-' + data.id).html('None');
+                            $('#label-mode-' + data.id).removeClass('hide');
+                            $('span.column-mode .bootstrap-select', itemNode).toggleClass("hide", true);
+
+                            $("span.column-network select", itemNode).empty().append(networkOptions);
+                            $("span.column-network select", itemNode).selectpicker('refresh');
+                            break;
+                    }
+                });
+                if (oriID === -1) {
+                    $("#interface-s390x-type-" + data.id).trigger('change');
+                }
+            }
+
         };
-        var networkOptions = "";
+
+
         kimchi.listNetworks(function(data) {
             for (var i = 0; i < data.length; i++) {
                 var isSlected = i === 0 ? " selected" : "";
                 networkOptions += "<option" + isSlected + ">" + data[i].name + "</option>";
             }
-            kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data) {
-                for (var i = 0; i < data.length; i++) {
-                    data[i].viewMode = "";
-                    data[i].editMode = "hide";
-                    data[i].id = i;
-                    addItem(data[i]);
-                }
-            });
+
+            if (kimchi.hostarch === s390xArch) {
+
+                kimchi.listmacvtapNetworks(function(data) {
+                    for (var i = 0; i < data.length; i++) {
+                        var isSlected = i === 0 ? ' selected="selected"' : "";
+                        macvtapNetworks += "<option" + isSlected + ">" + data[i].name + "</option>";
+                    }
+
+                    kimchi.listovsNetworks(function(data) {
+                        for (var i = 0; i < data.length; i++) {
+                            var isSlected = i === 0 ? " selected" : "";
+                            ovsNetworks += "<option" + isSlected + ">" + data[i] + "</option>";
+                        }
+
+                        kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data) {
+                            for (var i = 0; i < data.length; i++) {
+                                data[i].viewMode = "";
+                                data[i].editMode = "hide";
+                                data[i].id = i;
+                                addItem(data[i]);
+                            }
+                        });
+                    });
+                });
+            } else {
+                kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data) {
+                    for (var i = 0; i < data.length; i++) {
+                        data[i].viewMode = "";
+                        data[i].editMode = "hide";
+                        data[i].id = i;
+                        if (data[i].type == 'network')
+                            addItem(data[i]);
+                    }
+                });
+            }
         });
+
+        if (kimchi.hostarch === s390xArch) {
+            $('#form-guest-edit-interface > div.header').hide();
+            $('#form-guest-edit-interface > div.s390x').show();
+
+            var typeOptionsdata = [{
+                label: "macvtap",
+                value: "macvtap"
+            }, {
+                label: "ovs",
+                value: "ovs"
+            }, {
+                label: "network",
+                value: "network"
+            }];
+            var typeOptions = '';
+
+            for (var i = 0; i < typeOptionsdata.length; i++) {
+                var isSlected = i === 0 ? ' selected="selected"' : "";
+                typeOptions += '<option' + isSlected + ' value="' + typeOptionsdata[i].value + '">' + typeOptionsdata[i].label + '</option>';
+            }
+
+            var modeOptionsdata = [{
+                label: "Bridge",
+                value: "bridge"
+            }, {
+                label: "Vepa",
+                value: "vepa"
+            }];
+            var modeOptions = '';
+
+            for (var i = 0; i < modeOptionsdata.length; i++) {
+                var isSlected = i === 0 ? " selected" : "";
+                modeOptions += '<option' + isSlected + ' value="' + modeOptionsdata[i].value + '">' + modeOptionsdata[i].label + '</option>';
+            }
+        } else {
+            $('#form-guest-edit-interface > div.header').show();
+            $('#form-guest-edit-interface > div.s390x').hide();
+        }
     };
 
     var setupPermission = function() {
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index a9a468e..3a575dc 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -92,6 +92,14 @@
                     <span class="cell column-ip">$_("IP Address")</span>
                     <span class="cell column-actions"><span class="sr-only">$_("Actions")</span></span>
                 </div>
+                <div class="header s390x" style="display:none">
+                    <span class="cell column-type">$_("Type")</span>
+                    <span class="cell column-network">$_("Network/Interface")</span>
+                    <span class="cell column-mode">$_("Mode")</span>
+                    <span class="cell column-mac">$_("MAC Address")</span>
+                    <span class="cell column-ip">$_("IP Address")</span>
+                    <span class="cell column-actions"><span class="sr-only">$_("Actions")</span></span>
+                </div>
                 <div class="body"></div>
             </form>
             <form role="tabpanel" class="guest-edit-permission tab-pane" id="form-guest-edit-permission">
@@ -246,6 +254,38 @@
         </span>
     <div>
 </script>
+<script id="interface-s390x-tmpl" type="text/html">
+    <div class="item" id="{mac}">
+        <span class="cell column-type">
+          <span id="label-type-{id}" class="{viewMode}">{type}</span>
+          <select id="interface-s390x-type-{id}" class="{editMode}"></select>
+        </span>
+        <span class="cell column-network">
+            <span id="label-network-{id}" class="{viewMode}">{network}{source}</span>
+            <select id="interface-s390x-network-{id}" class="{editMode}"></select>
+        </span>
+        <span class="cell column-mode">
+            <span id="label-mode-{id}" class="{viewMode}">{mode}</span>
+            <select id="interface-s390x-mode-{id}" class="{editMode}"></select>
+        </span>
+        <span class="cell column-mac">
+            <span id="label-mac-{id}" class="{viewMode}">{mac}</span>
+            <input class="form-control {editMode}" type="text"
+               id="edit-mac-{id}" class="form-control" name="{mac}" value="{mac}" />
+        </span>
+        <span class="cell column-ip">
+            <span class=ipText>{ips}</span>
+        </span>
+        <span class="cell {editMode} column-actions action-area">
+                <button class="btn btn-primary save">$_("Save")</button>
+                <button class="btn btn-primary cancel">$_("Remove")</button>
+        </span>
+        <span class="cell {viewMode} column-actions action-area">
+            <button class="btn btn-link edit"><i class="fa fa-pencil"></i> $_("Edit")</button>
+            <button class="btn btn-link delete"><i class="fa fa-minus-circle"></i> $_("Remove")</button>
+        </span>
+    <div>
+</script>
 <script id="ldap-user-tmpl" type="text/html">
     <div class="item" id="{user}">
         <span class="cell">
-- 
2.1.0




More information about the Kimchi-devel mailing list