[Kimchi-devel] [PATCH v12 6/6] Host device passthrough (Front-end): Add PCI Devices to VM

Wen Wang wenwang at linux.vnet.ibm.com
Tue Oct 14 10:06:04 UTC 2014


I have sent a V13 UI patch that fix this.

On 10/13/2014 11:45 PM, Aline Manera wrote:
>
> Just one comment:
>
> When I select "Added" in the filter box, the all the dialog content 
> moves to right.
>
> On 10/08/2014 06:08 AM, Zhou Zheng Sheng wrote:
>> From: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
>>
>> Signed-off-by: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
>> Signed-off-by: Wen Wang <wenwang at 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 | 81 
>> ++++++++++++++++++++++++++++++++++
>>   ui/pages/guest-edit.html.tmpl       | 28 ++++++++++++
>>   4 files changed, 248 insertions(+), 2 deletions(-)
>>
>> diff --git a/ui/css/theme-default/guest-edit.css 
>> b/ui/css/theme-default/guest-edit.css
>> index 76fbaf2..ef2266f 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 {
>> @@ -261,3 +261,85 @@
>>       width: 46%;
>>       float: right;
>>   }
>> +
>> +.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 3398bd4..86bfd22 100644
>> --- a/ui/js/src/kimchi.api.js
>> +++ b/ui/js/src/kimchi.api.js
>> @@ -1114,6 +1114,20 @@ var kimchi = {
>>           });
>>       },
>>
>> +    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);
>> +            }
>> +        });
>> +    },
>> +
>>       getISCSITargets : function(server, port, suc, err) {
>>           server = encodeURIComponent(server);
>>           port = port ? '&_server_port='+encodeURIComponent(port) : '';
>> @@ -1144,6 +1158,47 @@ var kimchi = {
>>           });
>>       },
>>
>> +    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);
>> +            }
>> +        });
>> +    },
>> +
>>       /**
>>        * Add a volume to a given storage pool.
>>        */
>> diff --git a/ui/js/src/kimchi.guest_edit_main.js 
>> b/ui/js/src/kimchi.guest_edit_main.js
>> index c281289..030e112 100644
>> --- a/ui/js/src/kimchi.guest_edit_main.js
>> +++ b/ui/js/src/kimchi.guest_edit_main.js
>> @@ -359,6 +359,86 @@ kimchi.guest_edit_main = function() {
>>           });
>>       };
>>
>> +    var setupPCIDevice = function(){
>> +        kimchi.getHostPCIDevices(function(hostPCIs){
>> +            kimchi.getVMPCIDevices(kimchi.selectedGuest, 
>> function(vmPCIs){
>> +                kimchi.getCapabilities(function(result) {
>> +                    var pciEnabled = result.kernel_vfio;
>> +                    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;
>> +                            }
>> +                        }
>> +                        pciEnabled || $("button", itemNode).remove();
>> +                        $("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(){
>> + kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs1){
>> +                                        for(var k=0; 
>> k<hostPCIs.length; k++) {
>> +                                            $("button", "#" + 
>> hostPCIs[k].name).button("option", "icons", {primary: "ui-icon-plus"});
>> +                                        }
>> +                                        for(var k=0; 
>> k<vmPCIs1.length; k++) {
>> +                                            $("button", "#" + 
>> vmPCIs1[k].name).button("option", "icons", {primary: "ui-icon-minus"});
>> +                                        }
>> +                                    });
>> +                                    filterNodes($("select", 
>> "#form-guest-edit-pci").val(), $("input", 
>> "#form-guest-edit-pci").val());
>> +                                });
>> +                            }else{
>> + kimchi.addVMPCIDevice(kimchi.selectedGuest, { name: 
>> obj.parent().prop("id") }, function(){
>> + kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs1){
>> +                                        for(var k=0; 
>> k<vmPCIs1.length; k++) {
>> +                                            $("button", "#" + 
>> vmPCIs1[k].name).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);
>> @@ -395,6 +475,7 @@ kimchi.guest_edit_main = function() {
>>           initStorageListeners();
>>           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 917b2e8..69b11a7 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">$_("Host PCI 
>> Device")</a>
>> +                </li>
>>               </ul>
>>               <form id="form-guest-edit-general">
>>                   <fieldset class="guest-edit-fieldset">
>> @@ -138,6 +141,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>
>> @@ -221,6 +241,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>
>





More information about the Kimchi-devel mailing list