[V1 0/2] Edit Guest Network Interface

From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> Edit guest network interface UI and translations Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)

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

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

On 04/15/2014 02:49 AM, Aline Manera wrote:
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
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); + } + });
The update API is not implemented on backend yet. You can remove it.
will implement it as soon as possible.
} }; 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.
Yese. For "create", model is chosen by Kimchi automatically. But for "update", it can be chosen by user, user know which is the best model for VM.
+ 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();
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
-- Thanks and best regards! Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com> IBM Linux Technology Center

On 4/16/2014 3:48 PM, Sheldon wrote:
On 04/15/2014 02:49 AM, Aline Manera wrote:
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
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); + } + });
The update API is not implemented on backend yet. You can remove it.
will implement it as soon as possible.
} }; 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.
Yese. For "create", model is chosen by Kimchi automatically. But for "update", it can be chosen by user, user know which is the best model for VM. If we are confident to select the best model, then it does not need to be exposed in 'edit' either. How will the backend automatically select a 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>
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();
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

On 04/16/2014 03:48 PM, Sheldon wrote:
On 04/15/2014 02:49 AM, Aline Manera wrote:
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
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); + } + });
The update API is not implemented on backend yet. You can remove it.
will implement it as soon as possible.
} }; 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.
Yese. For "create", model is chosen by Kimchi automatically.
But for "update", it can be chosen by user, user know which is the best model for VM.
Actually we let libvirt to choose a model in backend. The backend do not know which the model type is the best after we has install OS on VM. For the VM will not store any template information, after it is create. we only know the best model type when we create a VM. That's because, the template tell us the guest OS and the best model for this OS. So discuss with aline, we let libvirt to choose a model for interface. This model may not be the best optima, but it is the best compatible.
+ 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();
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
-- Thanks and best regards! Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com> IBM Linux Technology Center

On 4/16/2014 5:17 PM, Sheldon wrote:
On 04/16/2014 03:48 PM, Sheldon wrote:
On 04/15/2014 02:49 AM, Aline Manera wrote:
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
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); + } + });
The update API is not implemented on backend yet. You can remove it.
will implement it as soon as possible.
} }; 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.
Yese. For "create", model is chosen by Kimchi automatically.
But for "update", it can be chosen by user, user know which is the best model for VM.
Actually we let libvirt to choose a model in backend.
The backend do not know which the model type is the best after we has install OS on VM. For the VM will not store any template information, after it is create.
we only know the best model type when we create a VM. That's because, the template tell us the guest OS and the best model for this OS.
So discuss with aline, we let libvirt to choose a model for interface. This model may not be the best optima, but it is the best compatible. What is the most compatible model, let me make it default, but also leave user the option to select. Since different model has different advantage, no need to limit user to a certain one.
+ 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();
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

On 4/16/2014 5:17 PM, Sheldon wrote:
On 04/16/2014 03:48 PM, Sheldon wrote:
On 04/15/2014 02:49 AM, Aline Manera wrote:
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
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); + } + });
The update API is not implemented on backend yet. You can remove it.
will implement it as soon as possible.
} }; 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.
Yese. For "create", model is chosen by Kimchi automatically.
But for "update", it can be chosen by user, user know which is the best model for VM.
Actually we let libvirt to choose a model in backend.
The backend do not know which the model type is the best after we has install OS on VM. For the VM will not store any template information, after it is create.
we only know the best model type when we create a VM. That's because, the template tell us the guest OS and the best model for this OS.
So discuss with aline, we let libvirt to choose a model for interface. This model may not be the best optima, but it is the best compatible. What is the most compatible model, let me make it default, but also leave user the option to select. Since different model has different advantage, no need to limit user to a certain one. I have try, libvirt will chooses rtl8139. It emulates a physical NIC. virtio is a para-virtualization NIC, high performance than an emulated
On 04/16/2014 05:25 PM, Yu Xin Huo wrote: physical NIC.
+ 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();
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
-- Thanks and best regards! Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com> IBM Linux Technology Center

From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> Signed-off-by: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> --- po/en_US.po | 3 +++ po/kimchi.pot | 3 +++ po/pt_BR.po | 3 +++ po/zh_CN.po | 3 +++ 4 files changed, 12 insertions(+), 0 deletions(-) diff --git a/po/en_US.po b/po/en_US.po index f2abcf0..493eb7e 100644 --- a/po/en_US.po +++ b/po/en_US.po @@ -61,6 +61,9 @@ msgstr "OS Version" msgid "CPUS" msgstr "CPUS" +msgid "Model" +msgstr "Model" + msgid "Memory" msgstr "Memory" diff --git a/po/kimchi.pot b/po/kimchi.pot index 7b33eb3..a4bced3 100755 --- a/po/kimchi.pot +++ b/po/kimchi.pot @@ -61,6 +61,9 @@ msgstr "" msgid "CPUS" msgstr "" +msgid "Model" +msgstr "" + msgid "Memory" msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po index 4967e1d..991fea6 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -79,6 +79,9 @@ msgstr "Versão do sistema operacional" msgid "CPUS" msgstr "CPUS" +msgid "Model" +msgstr "" + msgid "Memory" msgstr "Memória" diff --git a/po/zh_CN.po b/po/zh_CN.po index 6393b83..b264802 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -77,6 +77,9 @@ msgstr "操作系统版本" msgid "CPUS" msgstr "中央处理器" +msgid "Model" +msgstr "模型" + msgid "Memory" msgstr "内存" -- 1.7.1

We should keep the UI consistent. The storage and interface views are very different. I personally prefer the interface view but we should update the storage to follow the same layout. On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com>
Edit guest network interface UI and translations
Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO
po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
ÿØÿà

Hong Liang will send a patch to update the style of Storage tab. On 4/15/2014 2:53 AM, Aline Manera wrote:
We should keep the UI consistent. The storage and interface views are very different.
I personally prefer the interface view but we should update the storage to follow the same layout.
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo<huoyuxin@linux.vnet.ibm.com>
Edit guest network interface UI and translations
Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO
po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

I've 3 options to suggest: 1. grid style 2. iface style 3. original style with jQ UI icons On 04/15/2014 02:53 AM, Aline Manera wrote:
We should keep the UI consistent. The storage and interface views are very different.
I personally prefer the interface view but we should update the storage to follow the same layout.
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo<huoyuxin@linux.vnet.ibm.com>
Edit guest network interface UI and translations
Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO
po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

I've 3 options to suggest: (Royce is working on the storage tab to add another column "type") 1. grid style 2. iface style 3. original style with jQuery UI icons On 04/15/2014 02:53 AM, Aline Manera wrote:
We should keep the UI consistent. The storage and interface views are very different.
I personally prefer the interface view but we should update the storage to follow the same layout.
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo<huoyuxin@linux.vnet.ibm.com>
Edit guest network interface UI and translations
Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO
po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

On 04/17/2014 05:50 AM, Hongliang Wang wrote:
I've 3 options to suggest: (Royce is working on the storage tab to add another column "type")
1. grid style
2. iface style
I prefer the option 2.
3. original style with jQuery UI icons
On 04/15/2014 02:53 AM, Aline Manera wrote:
We should keep the UI consistent. The storage and interface views are very different.
I personally prefer the interface view but we should update the storage to follow the same layout.
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo<huoyuxin@linux.vnet.ibm.com>
Edit guest network interface UI and translations
Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO
po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

ACK. On 04/22/2014 10:42 PM, Aline Manera wrote:
On 04/17/2014 05:50 AM, Hongliang Wang wrote:
I've 3 options to suggest: (Royce is working on the storage tab to add another column "type")
1. grid style
2. iface style
I prefer the option 2.
3. original style with jQuery UI icons
On 04/15/2014 02:53 AM, Aline Manera wrote:
We should keep the UI consistent. The storage and interface views are very different.
I personally prefer the interface view but we should update the storage to follow the same layout.
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo<huoyuxin@linux.vnet.ibm.com>
Edit guest network interface UI and translations
Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO
po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

On 04/22/2014 10:42 PM, Aline Manera wrote:
On 04/17/2014 05:50 AM, Hongliang Wang wrote:
I've 3 options to suggest: (Royce is working on the storage tab to add another column "type")
1. grid style
2. iface style
I prefer the option 2. OK, @Aline. I'll send a patch based-on Option 2. Though Royce is working on a feature that affects this part of code, I'd like to start working after her patch has been applied to avoid conflicts, OK?
3. original style with jQuery UI icons
On 04/15/2014 02:53 AM, Aline Manera wrote:
We should keep the UI consistent. The storage and interface views are very different.
I personally prefer the interface view but we should update the storage to follow the same layout.
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo<huoyuxin@linux.vnet.ibm.com>
Edit guest network interface UI and translations
Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO
po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

On 04/23/2014 05:50 AM, Hongliang Wang wrote:
On 04/22/2014 10:42 PM, Aline Manera wrote:
On 04/17/2014 05:50 AM, Hongliang Wang wrote:
I've 3 options to suggest: (Royce is working on the storage tab to add another column "type")
1. grid style
2. iface style
I prefer the option 2. OK, @Aline. I'll send a patch based-on Option 2. Though Royce is working on a feature that affects this part of code, I'd like to start working after her patch has been applied to avoid conflicts, OK?
Ok. Sounds good for me.
3. original style with jQuery UI icons
On 04/15/2014 02:53 AM, Aline Manera wrote:
We should keep the UI consistent. The storage and interface views are very different.
I personally prefer the interface view but we should update the storage to follow the same layout.
On 04/14/2014 06:53 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo<huoyuxin@linux.vnet.ibm.com>
Edit guest network interface UI and translations
Yu Xin Huo (2): Edit Guest Network Inteface UI Edit Guest Network Interface PO
po/en_US.po | 3 + po/kimchi.pot | 3 + po/pt_BR.po | 3 + po/zh_CN.po | 3 + 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 ++++++++++++++++++ 8 files changed, 266 insertions(+), 0 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
participants (5)
-
Aline Manera
-
Hongliang Wang
-
huoyuxin@linux.vnet.ibm.com
-
Sheldon
-
Yu Xin Huo