
From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> Add, List, Delete, Update Guest Network Interface. Signed-off-by: Yu Xin Huo <huoyuxin@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