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

Aline Manera alinefm at linux.vnet.ibm.com
Mon Apr 14 18:49:17 UTC 2014


On 04/14/2014 06:53 AM, huoyuxin at linux.vnet.ibm.com wrote:
> 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);
> +            }
> +        });

The update API is not implemented on backend yet.
You can remove it.


>       }
>   };
> 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: "",

The model will be chosen by Kimchi automatically.
It is a low level information and we should not require it from user.

> +                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>

As I said before we should not require model info

> +                    <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>

Same here.

> +            </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();




More information about the Kimchi-devel mailing list