[Kimchi-devel] [V1 1/2] Edit Guest Network Inteface UI

huoyuxin at linux.vnet.ibm.com huoyuxin at linux.vnet.ibm.com
Mon Apr 14 09:53:28 UTC 2014


From: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>

Add, List, Delete, Update Guest Network Interface.

Signed-off-by: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
---
 ui/css/theme-default/guest-edit.css |   43 +++++++++++++++
 ui/js/src/kimchi.api.js             |   55 +++++++++++++++++++
 ui/js/src/kimchi.guest_edit_main.js |  103 +++++++++++++++++++++++++++++++++++
 ui/pages/guest-edit.html.tmpl       |   53 ++++++++++++++++++
 4 files changed, 254 insertions(+), 0 deletions(-)

diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
index 0b7ba21..4b208c1 100644
--- a/ui/css/theme-default/guest-edit.css
+++ b/ui/css/theme-default/guest-edit.css
@@ -156,3 +156,46 @@
 .guest-edit-cdrom-button.detach[disabled] {
     background-position: -54px -108px;
 }
+
+.guest-edit-interface .header {
+    margin-bottom: 8px;
+    padding-bottom: 2px;
+    font-weight: bold;
+    border-bottom: 1px solid #999999;
+    overflow: hidden;
+}
+
+.guest-edit-interface .body .item {
+    margin: 5px 0;
+}
+
+.guest-edit-interface .cell {
+    display: inline-block;
+    width: 150px;
+}
+
+.guest-edit-interface .body select {
+    width: 130px;
+    padding: 0px;
+}
+
+.guest-edit-interface .action-area {
+    float: right;
+}
+
+.guest-edit-interface button {
+    width: 20px;
+    height: 20px;
+}
+
+.guest-edit-interface .header button {
+    margin-bottom: 1px;
+}
+
+.guest-edit-interface .body button:not(:last-child) {
+    margin-right: 2px;
+}
+
+.guest-edit-interface .hide {
+    display: none;
+}
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 8c1030c..168e53d 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -955,5 +955,60 @@ var kimchi = {
                 kimchi.message.error(data.responseJSON.reason);
             }
         });
+    },
+
+    getGuestInterfaces: function(name, suc, err) {
+        var url = kimchi.url+'/vms/'+encodeURIComponent(name)+'/ifaces';
+        kimchi.requestJSON({
+            url : url,
+            type : 'GET',
+            contentType : 'application/json',
+            dataType : 'json',
+            success : suc,
+            error : err || function(data) {
+                kimchi.message.error(data.responseJSON.reason);
+            }
+        });
+    },
+
+    createGuestInterface : function(name, interface, suc, err) {
+        kimchi.requestJSON({
+            url : kimchi.url+'/vms/'+encodeURIComponent(name)+'/ifaces',
+            type : 'POST',
+            contentType : 'application/json',
+            dataType : 'json',
+            data : JSON.stringify(interface),
+            success : suc,
+            error : err || function(data) {
+                kimchi.message.error(data.responseJSON.reason);
+            }
+        });
+    },
+
+    deleteGuestInterface : function(vm, mac, suc, err) {
+        kimchi.requestJSON({
+            url : kimchi.url+'/vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
+            type : 'DELETE',
+            contentType : 'application/json',
+            dataType : 'json',
+            success : suc,
+            error : err ? err : function(data) {
+                kimchi.message.error(data.responseJSON.reason);
+            }
+        });
+    },
+
+    updateGuestInterface : function(vm, mac, interface, suc, err) {
+        $.ajax({
+            url : kimchi.url+'/vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
+            type : 'PUT',
+            contentType : 'application/json',
+            data : JSON.stringify(interface),
+            dataType : 'json',
+            success: suc,
+            error: err ? err : function(data) {
+                kimchi.message.error(data.responseJSON.reason);
+            }
+        });
     }
 };
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index 9375c51..b051774 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -78,6 +78,107 @@ kimchi.guest_edit_main = function() {
         });
     };
 
+    var setupInterface = function() {
+        $(".add", "#form-guest-edit-interface").button({
+            icons: { primary: "ui-icon-plusthick" },
+            text: false
+        }).click(function(){
+            addItem({
+                mac: "",
+                network: "",
+                model: "",
+                type: "",
+                viewMode: "hide",
+                editMode: ""
+            });
+        });
+        var toggleEdit = function(item, on){
+            $("label", item).toggleClass("hide", on);
+            $("select", item).toggleClass("hide", !on);
+            $(".action-area", item).toggleClass("hide");
+        };
+        var addItem = function(data) {
+            var attrs = ["network", "model", "type"];
+            var attrIndex = 0;
+            var itemNode = $.parseHTML(kimchi.template($('#interface-tmpl').html(),data));
+            $(".body", "#form-guest-edit-interface").append(itemNode);
+            $("select", itemNode).first().append(networkOptions);
+            if(data[attrs[attrIndex]]!=""){
+                $("select", itemNode).each(function(){
+                    $(this).val(data[attrs[attrIndex]]);
+                    attrIndex++;
+                });
+                attrIndex = 0;
+            }
+            $(".edit", itemNode).button({
+                icons: { primary: "ui-icon-pencil" },
+                text: false
+            }).click(function(){
+                toggleEdit($(this).parent().parent(), true);
+            });
+            $(".delete", itemNode).button({
+                icons: { primary: "ui-icon-trash" },
+                text: false
+            }).click(function(){
+                var item = $(this).parent().parent();
+                kimchi.deleteGuestInterface(kimchi.selectedGuest, item.prop("id"), function(){
+                    item.remove();
+                });
+            });
+            $(".save", itemNode).button({
+                icons: { primary: "ui-icon-disk" },
+                text: false
+            }).click(function(){
+                var interface = {};
+                var item = $(this).parent().parent();
+                $("select", item).each(function(){
+                    interface[attrs[attrIndex]] = $(this).val();
+                    attrIndex++;
+                });
+                attrIndex = 0;
+                var postUpdae = function(){
+                    $("label", item).each(function(){
+                        $(this).text(interface[attrs[attrIndex]]);
+                        attrIndex++;
+                    });
+                    attrIndex = 0;
+                    toggleEdit(item, false);
+                };
+                if(item.prop("id")==""){
+                    kimchi.createGuestInterface(kimchi.selectedGuest, interface, function(data){
+                        item.prop("id", data.mac);
+                        postUpdae();
+                    });
+                }else{
+                    kimchi.updateGuestInterface(kimchi.selectedGuest, item.prop("id"), interface, function(){
+                        postUpdae();
+                    });
+                }
+            });
+            $(".cancel", itemNode).button({
+                icons: { primary: "ui-icon-arrowreturnthick-1-w" },
+                text: false
+            }).click(function(){
+                var item = $(this).parent().parent();
+                $("label", item).text()==="" ? item.remove() : toggleEdit(item, false);
+            });
+        };
+        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";
+                    addItem(data[i]);
+                }
+            });
+        });
+    };
+
     var initContent = function(guest) {
         guest['icon'] = guest['icon'] || 'images/icon-vm.png';
         for ( var prop in guest) {
@@ -101,6 +202,8 @@ kimchi.guest_edit_main = function() {
             refreshCDROMs();
         };
 
+        setupInterface();
+
         kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
         kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
         kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached);
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index 804fc39..a2949be 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -35,6 +35,9 @@
                 <li>
                     <a href="#form-guest-edit-storage">$_("Storage")</a>
                 </li>
+                <li>
+                    <a href="#form-guest-edit-interface">$_("Interface")</a>
+                </li>
             </ul>
             <form id="form-guest-edit-general">
                 <fieldset class="guest-edit-fieldset">
@@ -103,6 +106,15 @@
                     </div>
                 </fieldset>
             </form>
+            <form id="form-guest-edit-interface" class="guest-edit-interface">
+                <div class="header">
+                    <span class="cell">$_("Network")</span>
+                    <span class="cell">$_("Model")</span>
+                    <span class="cell">$_("Type")</span>
+                    <button class="add action-area"></button>
+                </div>
+                <div class="body"></div>
+            </form>
         </div>
     </div>
     <footer>
@@ -133,6 +145,47 @@
         </div>
     </div>
 </script>
+<script id="interface-tmpl" type="text/html">
+    <div class="item" id="{mac}">
+        <span class="cell">
+            <label class="{viewMode}">{network}</label>
+            <select class="{editMode}"></select>
+        </span>
+        <span class="cell">
+            <label class="{viewMode}">{model}</label>
+            <select class="{editMode}">
+                <option>ne2k_pci</option>
+                <option>i82551</option>
+                <option>i82557b</option>
+                <option>i82559er</option>
+                <option selected>rtl8139</option>
+                <option>e1000</option>
+                <option>pcnet</option>
+                <option>virtio</option>
+            </select>
+        </span>
+        <span class="cell">
+            <label class="{viewMode}">{type}</label>
+            <select class="{editMode}">
+                <option selected>network</option>
+                <option disabled>bridge</option>
+                <option disabled>user</option>
+                <option disabled>ethernet</option>
+                <option disabled>direct</option>
+                <option disabled>hostdev</option>
+                <option disabled>mcast</option>
+                <option disabled>server</option>
+                <option disabled>client</option>
+            </select>
+        </span>
+        <span class="action-area {editMode}">
+            <button class="save"></button><button class="cancel"></button>
+        </span>
+        <span class="action-area {viewMode}">
+            <button class="edit"></button><button class="delete"></button>
+        </span>
+    <div>
+</script>
 
 <script type="text/javascript">
     kimchi.guest_edit_main();
-- 
1.7.1




More information about the Kimchi-devel mailing list