The UI looks good but it still refers to interface update which is not
implemented on backend.
I suggest disabling it until we have the backend completed.
On 04/17/2014 04:08 AM, huoyuxin(a)linux.vnet.ibm.com wrote:
From: Yu Xin Huo <huoyuxin(a)linux.vnet.ibm.com>
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 | 90 +++++++++++++++++++++++++++++++++++
ui/pages/guest-edit.html.tmpl | 28 +++++++++++
4 files changed, 216 insertions(+), 0 deletions(-)
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
index 0b7ba21..39bf1fb 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: 250px;
+}
+
+.guest-edit-interface .body select {
+ width: 180px;
+ 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 e96a67a..71b552f 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -959,5 +959,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..4337150 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -78,6 +78,94 @@ 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: "",
+ type: "network",
+ 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 itemNode =
$.parseHTML(kimchi.template($('#interface-tmpl').html(),data));
+ $(".body",
"#form-guest-edit-interface").append(itemNode);
+ $("select", itemNode).append(networkOptions);
+ if(data.network!==""){
+ $("select", itemNode).val(data.network);
+ }
+ $(".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 item = $(this).parent().parent();
+ var interface = {
+ network: $("select", item).val(),
+ type: "network"
+ };
+ var postUpdate = function(){
+ $("label", item).text(interface.network);
+ toggleEdit(item, false);
+ };
+ if(item.prop("id")==""){
+ kimchi.createGuestInterface(kimchi.selectedGuest, interface,
function(data){
+ item.prop("id", data.mac);
+ postUpdate();
+ });
+ }else{
+ kimchi.updateGuestInterface(kimchi.selectedGuest,
item.prop("id"), interface, function(){
+ postUpdate();
+ });
+ }
+ });
+ $(".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 +189,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..d54b3ab 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,14 @@
</div>
</fieldset>
</form>
+ <form id="form-guest-edit-interface"
class="guest-edit-interface">
+ <div class="header">
+ <span
class="cell">$_("Network")</span>
+ <span
class="cell">$_("Type")</span>
+ <button class="add action-area"></button>
+ </div>
+ <div class="body"></div>
+ </form>
</div>
</div>
<footer>
@@ -133,6 +144,23 @@
</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">
+ <span>{type}</span>
+ </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();