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 | 86 ++++++++++++++++++++++++++++++++++-
ui/js/src/kimchi.api.js | 55 ++++++++++++++++++++++
ui/js/src/kimchi.guest_edit_main.js | 66 +++++++++++++++++++++++++++
ui/pages/guest-edit.html.tmpl | 28 +++++++++++
4 files changed, 233 insertions(+), 2 deletions(-)
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
index 1092cc9..c9b43bd 100644
--- a/ui/css/theme-default/guest-edit.css
+++ b/ui/css/theme-default/guest-edit.css
@@ -17,8 +17,8 @@
*/
#guest-edit-window {
font-size: 13px;
- height: 400px;
- width: 610px;
+ height: 420px;
+ width: 820px;
}
#guest-edit-tabs {
@@ -266,3 +266,85 @@
float: right;
margin-right: 10px;
}
+
+.guest-edit-pci {
+ height: 79%;
+ overflow: auto;
+ font-size: 12px;
+}
+
+.guest-edit-pci .filter {
+ height: 35px;
+ margin-right: 5px;
+ overflow: hidden;
+}
+
+.guest-edit-pci .group {
+ float: right;
+}
+
+.guest-edit-pci .filter .control {
+ border: 1px solid #AAAAAA;
+ font-size: 12px;
+ background-color: white;
+}
+
+.guest-edit-pci .filter select {
+ border-right: 0px!important;
+ border-radius: 7px 0px 0px 7px;
+ padding: 2px 2px 2px 7px;
+ width: 100px;
+}
+
+.guest-edit-pci .filter select option {
+ padding-left: 7px;
+}
+
+.guest-edit-pci .filter input {
+ border-radius: 0px 7px 7px 0px;
+ padding: 3px 3px 3px 10px;
+ width: 200px;
+ font-style: italic;
+}
+
+.guest-edit-pci .header {
+ margin-bottom: 8px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+
+.guest-edit-pci .item {
+ margin-bottom: 4px;
+ overflow: hidden;
+}
+
+.guest-edit-pci .cell {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 10px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.guest-edit-pci .item button {
+ width: 20px;
+ height: 20px;
+ float: right;
+}
+
+.guest-edit-pci .name {
+ width: 18%;
+ max-width: 18%;
+}
+
+.guest-edit-pci .product {
+ width: 45%;
+ max-width: 45%;
+}
+
+.guest-edit-pci .vendor {
+ width: 25%;
+ max-width: 25%;
+}
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 4562992..ad91ad3 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -1098,5 +1098,60 @@ var kimchi = {
kimchi.message.error(data.responseJSON.reason);
}
});
+ },
+
+ getHostPCIDevices : function(suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url + 'host/devices?_passthrough=true&_cap=pci',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getVMPCIDevices : function(id, suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url +
'vms/'+encodeURIComponent(id)+'/hostdevs',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ addVMPCIDevice : function(vm, device, suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url + 'vms/'+ encodeURIComponent(vm)
+'/hostdevs',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(device),
+ success : suc,
+ error : err ? err : function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ removeVMPCIDevice : function(vm, device, suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url + 'vms/'+ encodeURIComponent(vm)
+'/hostdevs/' + encodeURIComponent(device),
+ type : 'DELETE',
+ contentType : 'application/json',
+ 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 38a2bc0..d002add 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -349,6 +349,71 @@ kimchi.guest_edit_main = function() {
});
};
+ var setupPCIDevice = function(){
+ kimchi.getHostPCIDevices(function(hostPCIs){
+ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){
+ for(var i=0; i<hostPCIs.length; i++){
+ var itemNode =
$.parseHTML(kimchi.substitute($('#pci-tmpl').html(),{
+ name: hostPCIs[i].name,
+ product: hostPCIs[i].product.description,
+ vendor: hostPCIs[i].vendor.description
+ }));
+ $(".body",
"#form-guest-edit-pci").append(itemNode);
+ var iconClass = "ui-icon-plus";
+ for(var j=0; j<vmPCIs.length; j++){
+ if(hostPCIs[i].name==vmPCIs[j].name){
+ iconClass = "ui-icon-minus";
+ break;
+ }
+ }
+ $("button", itemNode).button({
+ icons: { primary: iconClass },
+ text: false
+ }).click(function(){
+ var obj = $(this);
+ if(obj.button("option", "icons").primary ==
"ui-icon-minus"){
+ kimchi.removeVMPCIDevice(kimchi.selectedGuest,
obj.parent().prop("id"), function(){
+ obj.button("option", "icons", {
primary: "ui-icon-plus" });
+ filterNodes($("select",
"#form-guest-edit-pci").val(), $("input",
"#form-guest-edit-pci").val());
+ });
+ }else{
+ kimchi.addVMPCIDevice(kimchi.selectedGuest, { name:
obj.parent().prop("id") }, function(){
+ obj.button("option", "icons", {
primary: "ui-icon-minus" });
+ filterNodes($("select",
"#form-guest-edit-pci").val(), $("input",
"#form-guest-edit-pci").val());
+ });
+ }
+ });
+ }
+ });
+ });
+ var filterNodes = function(group, text){
+ text = text.toLowerCase();
+ $(".body",
"#form-guest-edit-pci").children().each(function(){
+ var textFilter = $(".name",
this).text().toLowerCase().indexOf(text)!=-1;
+ textFilter = textFilter || $(".product",
this).text().toLowerCase().indexOf(text)!=-1;
+ textFilter = textFilter || $(".vendor",
this).text().toLowerCase().indexOf(text)!=-1;
+ var display = "none";
+ var itemGroup = $("button", this).button("option",
"icons").primary;
+ if(textFilter){
+ if(group == "all"){
+ display = "";
+ }else if(group=="toAdd" &&
itemGroup=="ui-icon-plus"){
+ display = ""
+ }else if(group == "added" &&
itemGroup=="ui-icon-minus"){
+ display = ""
+ }
+ }
+ $(this).css("display", display);
+ });
+ };
+ $("select", "#form-guest-edit-pci").change(function(){
+ filterNodes($(this).val(), $("input",
"#form-guest-edit-pci").val());
+ });
+ $("input", "#form-guest-edit-pci").on("keyup",
function() {
+ filterNodes($("select", "#form-guest-edit-pci").val(),
$(this).val());
+ });
+ };
+
var initContent = function(guest) {
guest['icon'] = guest['icon'] || 'images/icon-vm.png';
$('#form-guest-edit-general').fillWithObject(guest);
@@ -379,6 +444,7 @@ kimchi.guest_edit_main = function() {
setupInterface();
setupPermission();
+ setupPCIDevice();
kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index 1c1d7d4..7ae3bfd 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -41,6 +41,9 @@
<li>
<a
href="#form-guest-edit-permission">$_("Permission")</a>
</li>
+ <li>
+ <a href="#form-guest-edit-pci">$_("PCI
Device")</a>
+ </li>
</ul>
<form id="form-guest-edit-general">
<fieldset class="guest-edit-fieldset">
@@ -142,6 +145,23 @@
</div>
</div>
</form>
+ <form id="form-guest-edit-pci"
class="guest-edit-pci">
+ <div class="filter">
+ <span class="group">
+ <select class="control">
+ <option
value="all">$_("All")</option>
+ <option value="toAdd">$_("To
Add")</option>
+ <option
value="added">$_("Added")</option>
+ </select><input type="text"
class="control" placeholder="$_("filter")">
+ </span>
+ </div>
+ <div class="header">
+ <span class="cell
name">$_("Name")</span>
+ <span class="cell
product">$_("Product")</span>
+ <span class="cell
vendor">$_("Vendor")</span>
+ </div>
+ <div class="body"></div>
+ </form>
</div>
</div>
<footer>
@@ -228,6 +248,14 @@
<label>{val}</label>
</div>
</script>
+<script id="pci-tmpl" type="text/html">
+<div class="item" id="{name}">
+ <span class="cell name" title="{name}">{name}</span>
+ <span class="cell product"
title="{product}">{product}</span>
+ <span class="cell vendor"
title="{vendor}">{vendor}</span>
+ <button></button>
+</div>
+</script>
<script type="text/javascript">
kimchi.guest_edit_main();
</script>
--
1.7.1