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

Yu Xin Huo huoyuxin at linux.vnet.ibm.com
Wed Apr 16 07:59:36 UTC 2014


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 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.
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 at ovirt.org
>> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>>
>>
>>
>
>




More information about the Kimchi-devel mailing list