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(a)linux.vnet.ibm.com wrote:
>> From: Yu Xin Huo <huoyuxin(a)linux.vnet.ibm.com>
>>
>> Add, List, Delete, Update Guest Network Interface.
>>
>> Signed-off-by: Yu Xin Huo <huoyuxin(a)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(a)ovirt.org
>
http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>
>
>
--
Thanks and best regards!
Sheldon Feng(冯少合)<shaohef(a)linux.vnet.ibm.com>
IBM Linux Technology Center