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

Sheldon shaohef at linux.vnet.ibm.com
Wed Apr 16 09:41:40 UTC 2014


On 04/16/2014 05:25 PM, Yu Xin Huo wrote:
> 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 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.
>>>>
>>> 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 
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 at ovirt.org
>>>> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>
>


-- 
Thanks and best regards!

Sheldon Feng(冯少合)<shaohef at linux.vnet.ibm.com>
IBM Linux Technology Center




More information about the Kimchi-devel mailing list