[PATCH] [Kimchi] Add maxvCpu support UI for guest and template

- Give the option to set maxvCpu when editing guest and template Socorro Stoppler (1): MaxvCpu Initial Work; made some adjustments to style ui/css/kimchi.css | 66 +++++++++++++++++++++++++++++----- ui/css/src/modules/_edit-guests.scss | 22 +++++++++++- ui/css/src/modules/_templates.scss | 25 +++++++++++-- ui/js/src/kimchi.guest_edit_main.js | 30 +++++++++++++--- ui/js/src/kimchi.template_edit_main.js | 53 ++++++++++++++++++++------- ui/pages/guest-edit.html.tmpl | 9 ++++- ui/pages/i18n.json.tmpl | 2 ++ ui/pages/template-edit.html.tmpl | 29 ++++++++------- 8 files changed, 195 insertions(+), 41 deletions(-) -- 1.9.1

- MaxvCpu can be set when editing a guest or template Signed-off-by: Socorro Stoppler <socorro@linux.vnet.ibm.com> --- ui/css/kimchi.css | 66 +++++++++++++++++++++++++++++----- ui/css/src/modules/_edit-guests.scss | 22 +++++++++++- ui/css/src/modules/_templates.scss | 25 +++++++++++-- ui/js/src/kimchi.guest_edit_main.js | 30 +++++++++++++--- ui/js/src/kimchi.template_edit_main.js | 53 ++++++++++++++++++++------- ui/pages/guest-edit.html.tmpl | 9 ++++- ui/pages/i18n.json.tmpl | 2 ++ ui/pages/template-edit.html.tmpl | 29 ++++++++------- 8 files changed, 195 insertions(+), 41 deletions(-) diff --git a/ui/css/kimchi.css b/ui/css/kimchi.css index 88ae7de..b3ff8bd 100644 --- a/ui/css/kimchi.css +++ b/ui/css/kimchi.css @@ -78,7 +78,7 @@ #guest-add-window.modal-content label.box-iso-outer span.box-iso-border { display: block; border: 3px solid transparent; - transition: all .1s ease-in-out; + transition: all 0.1s ease-in-out; } #template-add-window.modal-content label.box-iso-outer .iso-radio-hidden:checked + span.box-iso-border, @@ -100,7 +100,7 @@ display: block; border: 1px solid transparent; background: #fff; - transition: all .1s ease-in-out; + transition: all 0.1s ease-in-out; } #template-add-window.modal-content ul.list-template, @@ -666,10 +666,28 @@ position: relative; } -#guest-edit-window #form-guest-edit-general #guest-edit-memory-textbox { +#guest-edit-window #form-guest-edit-general #guest-max-memory-panel, +#guest-edit-window #form-guest-edit-general #guest-max-processor-panel { + display: none; +} + +#guest-edit-window #form-guest-edit-general #guest-edit-memory-textbox, +#guest-edit-window #form-guest-edit-general #guest-edit-max-memory-textbox, +#guest-edit-window #form-guest-edit-general #guest-edit-cores-textbox, +#guest-edit-window #form-guest-edit-general #guest-edit-max-processor-textbox { width: 590px; } +#guest-edit-window #form-guest-edit-general #guest-edit-memory-textbox, +#guest-edit-window #form-guest-edit-general #guest-show-max-memory { + display: block; +} + +#guest-edit-window #form-guest-edit-general #guest-edit-cores-textbox, +#guest-edit-window #form-guest-edit-general #guest-show-max-processor { + display: inline-block; +} + #guest-edit-window #form-guest-edit-interface .column-actions { width: 23%; } @@ -1007,7 +1025,7 @@ border: 1px solid #eee !important; margin-bottom: 3px; display: block; - padding: .2em .6em .3em; + padding: 0.2em 0.6em 0.3em; font-weight: 700; line-height: 1; text-align: left; @@ -1178,17 +1196,44 @@ height: 40px; } +#template-edit-window #guest-max-processor-panel { + display: none; +} + +#template-edit-window #guest-show-max-processor { + display: inline-block; +} + +#template-edit-window #guest-processor label { + display: block; +} + +#template-edit-window #guest-max-processor-panel label { + display: block; +} + +#template-edit-window #guest-max-processor-panel .form-control, +#template-edit-window #guest-processor .form-control { + display: inline-block; + width: 184px; +} + #template-edit-window .manual { margin-top: 5px; margin-bottom: 10px; } #template-edit-window .topology { + display: none; margin: 0 24px; } -#template-edit-window .topology .form-inline { - margin-bottom: 10px; +#template-edit-window .topology label { + display: block; +} + +#template-edit-window .bootstrap-select .btrn .caret { + height: selectpicker height-2px; } #template-edit-window .template-storage-cell.storage-pool { @@ -1250,7 +1295,7 @@ height: 664px; width: 2164px; left: 0; - transition: left .2s ease-in-out; + transition: left 0.2s ease-in-out; } #template-add-window.modal-content p { @@ -1526,7 +1571,9 @@ padding-right: 35px !important; } -#templates-root-container .wok-vm-gallery .item-hidden.column-type, #templates-root-container .wok-vm-gallery .item-hidden.column-version, #templates-root-container .wok-vm-gallery .item-hidden.column-processors { +#templates-root-container .wok-vm-gallery .item-hidden.column-type, +#templates-root-container .wok-vm-gallery .item-hidden.column-version, +#templates-root-container .wok-vm-gallery .item-hidden.column-processors { padding-bottom: 11px; } @@ -2067,7 +2114,8 @@ white-space: nowrap; } -.storage-modal .filter-select.popable .popover ul li:hover, .storage-modal .filter-select.popable .popover ul li:focus, +.storage-modal .filter-select.popable .popover ul li:hover, +.storage-modal .filter-select.popable .popover ul li:focus, .storage-modal .storage-target-input .popover ul li:hover, .storage-modal .storage-target-input .popover ul li:focus, .storage-modal .storage-add-input .popover ul li:hover, diff --git a/ui/css/src/modules/_edit-guests.scss b/ui/css/src/modules/_edit-guests.scss index 4d642f3..84d116b 100644 --- a/ui/css/src/modules/_edit-guests.scss +++ b/ui/css/src/modules/_edit-guests.scss @@ -25,9 +25,29 @@ position: relative; } #form-guest-edit-general { - #guest-edit-memory-textbox { + + #guest-max-memory-panel, + #guest-max-processor-panel { + display: none; + } + + #guest-edit-memory-textbox, + #guest-edit-max-memory-textbox, + #guest-edit-cores-textbox, + #guest-edit-max-processor-textbox { width: 590px; } + + #guest-edit-memory-textbox, + #guest-show-max-memory { + display: block; + } + + #guest-edit-cores-textbox, + #guest-show-max-processor { + display: inline-block; + } + } #form-guest-edit-interface { .column-actions { diff --git a/ui/css/src/modules/_templates.scss b/ui/css/src/modules/_templates.scss index 0b2f935..19ed5a0 100644 --- a/ui/css/src/modules/_templates.scss +++ b/ui/css/src/modules/_templates.scss @@ -110,15 +110,36 @@ } } } + #guest-max-processor-panel { + display: none; + } + #guest-show-max-processor { + display: inline-block; + } + #guest-processor label { + display: block; + } + #guest-max-processor-panel label { + display: block; + } + #guest-max-processor-panel .form-control, + #guest-processor .form-control { + display: inline-block; + width: 184px; + } .manual { margin-top: 5px; margin-bottom: 10px; } .topology { + display: none; margin: 0 24px; } - .topology .form-inline { - margin-bottom: 10px; + .topology label { + display: block; + } + .bootstrap-select .btrn .caret { + height: selectpicker height - 2px; } .template-storage-cell.storage-pool { width: 220px !important; diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index 94b521e..6daec53 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -660,7 +660,8 @@ kimchi.guest_edit_main = function() { }; var initContent = function(guest) { - guest['vcpus'] = guest['cpu_info']['vcpus'] + guest['vcpus'] = guest.cpu_info['vcpus']; + guest['max-processor'] = guest.cpu_info['maxvcpus']; guest['icon'] = guest['icon'] || 'plugins/kimchi/images/icon-vm.png'; $('#form-guest-edit-general').fillWithObject(guest); kimchi.thisVMState = guest['state']; @@ -673,6 +674,14 @@ kimchi.guest_edit_main = function() { $("#form-guest-edit-general input").not("#guest-edit-memory-textbox").prop("disabled", true); } + $('#guest-show-max-processor').on('click', function(e) { + e.preventDefault; + $('#guest-max-processor-panel').slideToggle(); + var cputext = $('#guest-show-max-processor span.cputext').text(); + $('#guest-show-max-processor span.cputext').text(cputext == i18n['KCHVMED6008M'] ? i18n['KCHVMED6009M'] : i18n['KCHVMED6008M']); + $('#guest-show-max-processor i.fa').toggleClass('fa-plus-circle fa-minus-circle'); + }); + var onAttached = function(params) { refreshCDROMs(); }; @@ -709,10 +718,23 @@ kimchi.guest_edit_main = function() { data['memory'] = Number(data['memory']); } if (data['vcpus'] !== undefined) { - data['cpu_info'] = { - vcpus: Number(data['vcpus']) - }; + var cpu = Number(data['vcpus']); + var maxCpu = Number(data['max-processor']); + if (data['max-processor'] !== undefined && data['max-processor'] !== "") { + if (maxCpu >= cpu || maxCpu < cpu ) { // if maxCpu < cpu, this will throw an error from backend + data['cpu_info'] = { + vcpus: cpu, + maxvcpus: maxCpu + }; + } + } else { + data['cpu_info'] = { + vcpus: cpu, + maxvcpus: cpu + }; + } delete data['vcpus']; + delete data['max-processor']; } kimchi.updateVM(kimchi.selectedGuest, data, function() { diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js index ed4a4ea..14f317f 100644 --- a/ui/js/src/kimchi.template_edit_main.js +++ b/ui/js/src/kimchi.template_edit_main.js @@ -241,7 +241,12 @@ kimchi.template_edit_main = function() { var initProcessor = function(){ var setCPUValue = function(){ if(!$('#cores').hasClass("invalid-field")&&$('#cores').val()!=""){ - $("#vcpus").val(parseInt($("#cores").val())*parseInt($("#threads").val())); + var computedCpu = parseInt($("#cores").val())*parseInt($("#threads").val()); + $("#vcpus").val(computedCpu); + if ($("#cpus-check").prop("checked")) { + //If topology is checked, set maxcpu to be the same as # of cpu otherwise, backend gives error + $("#guest-edit-max-processor-textbox").val(computedCpu); + } }else{ $("#vcpus").val(''); } @@ -251,29 +256,44 @@ kimchi.template_edit_main = function() { if($(this).prop('id')=='cores') setCPUValue(); }); $("input:checkbox", "#form-template-processor").click(function(){ - $(".topology", "#form-template-processor").toggleClass("hide", !$(this).prop("checked")); + $('#threads').selectpicker(); + $(".topology", "#form-template-processor").slideToggle(); $("#vcpus").attr("disabled", $(this).prop("checked")); + $("#guest-edit-max-processor-textbox").attr("disabled", $(this).prop("checked")); setCPUValue(); }); - $('select', '#form-template-processor').change(function(){ + $('#threads').change(function(){ setCPUValue(); }); kimchi.getCPUInfo(function(data){ var options = ""; + var topo = template.cpu_info.topology; for(var i=0;Math.pow(2,i)<=data.threads_per_core;i++){ var lastOne = Math.pow(2,i+1)>data.threads_per_core?" selected":""; options += "<option"+lastOne+">"+Math.pow(2,i)+"</option>"; } - $('select', '#form-template-processor').append(options); - $('select', '#form-template-processor').selectpicker(); - if(template.cpu_info.vcpus) $("#vcpus").val(template.cpu_info.vcpus); - var topo = template.cpu_info.topology; - if(topo&&topo.cores) $("#cores").val(topo.cores); + $('#threads').append(options); + if(template.cpu_info.vcpus){ + $("#vcpus").val(template.cpu_info.vcpus); + } + if(template.cpu_info.maxvcpus){ + $("#guest-edit-max-processor-textbox").val(template.cpu_info.maxvcpus); + } + if(topo&&topo.cores){ + $("#cores").val(topo.cores); + } if(topo&&topo.threads){ - $('select', '#form-template-processor').val(topo.threads); + $('#threads').val(topo.threads); + $('#threads').selectpicker(); $("input:checkbox", "#form-template-processor").trigger('click'); } }); + $('#guest-show-max-processor').on('click', function(e) { + e.preventDefault; + $('#guest-max-processor-panel').slideToggle(); + var text = $('#guest-show-max-processor span.text').text(); + $('#guest-show-max-processor span.text').text(text == i18n['KCHVMED6008M'] ? i18n['KCHVMED6009M'] : i18n['KCHVMED6008M']); + }); }; kimchi.listNetworks(initInterface); kimchi.listStoragePools(initStorage); @@ -320,10 +340,17 @@ kimchi.template_edit_main = function() { } }); data['memory'] = Number(data['memory']); + var cpu = parseInt($('#vcpus').val()); + var maxCpu = parseInt($('#guest-edit-max-processor-textbox').val()); + var maxCpuFinal = cpu; //Initially set maxCpu to be the same as cpu + if (maxCpu >= cpu) { + maxCpuFinal = maxCpu; + } if($("input:checkbox", "#form-template-processor").prop("checked")){ + //Check if maxCpu field has a value data['cpu_info'] = { - vcpus: parseInt($('#vcpus').val()), - maxvcpus: parseInt($('#vcpus').val()), + vcpus: cpu, + maxvcpus: maxCpuFinal, topology: { sockets: 1, cores: parseInt($("#cores").val()), @@ -332,7 +359,9 @@ kimchi.template_edit_main = function() { }; }else{ data['cpu_info'] = { - vcpus: parseInt($('#vcpus').val()) + vcpus: cpu, + maxvcpus: maxCpuFinal, + topology: {} }; } var networks = $('.template-tab-body .item', '#form-template-interface'); diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index 32576e9..375d077 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -46,7 +46,14 @@ </div> <div class="form-group"> <label for="guest-edit-cores-textbox">$_("CPUs")</label> - <input id="guest-edit-cores-textbox" class="form-control" name="vcpus" type="text" /> + <div id="guest-processor"> + <input id="guest-edit-cores-textbox" class="form-control" name="vcpus" type="number" min="1" /> + <button id="guest-show-max-processor" class="btn btn-primary" type="button"><i class="fa fa-plus-circle"></i> <span class="cputext">$_("More")</span></button> + </div> + </div> + <div id="guest-max-processor-panel" class="form-group"> + <label for="guest-edit-max-processor-textbox">$_("Max CPU")</label> + <input id="guest-edit-max-processor-textbox" class="form-control" name="max-processor" type="number" min="1" /> </div> <div class="form-group"> <label for="guest-edit-memory-textbox">$_("Memory (MB)")</label> diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl index 82ba375..1e34183 100644 --- a/ui/pages/i18n.json.tmpl +++ b/ui/pages/i18n.json.tmpl @@ -77,6 +77,8 @@ "KCHVMED6005M": "$_("drive_type:")", "KCHVMED6006M": "$_("model:")", "KCHVMED6007M": "$_("Affected devices:")", + "KCHVMED6008M": "$_("More")", + "KCHVMED6009M": "$_("Less")", "KCHNET6001M": "$_("unavailable")", "KCHNET6002M": "$_("This action will interrupt network connectivity for any virtual machine that depend on this network.")", diff --git a/ui/pages/template-edit.html.tmpl b/ui/pages/template-edit.html.tmpl index 0b43a20..45ff504 100644 --- a/ui/pages/template-edit.html.tmpl +++ b/ui/pages/template-edit.html.tmpl @@ -121,27 +121,32 @@ </div> <div role="tabpanel" class="tab-pane" id="processor"> <form id="form-template-processor"> - <div class="form-inline"> - <div class="form-group"> - <label for="vcpus">$_("CPU Number"):</label> - <input type="text" class="form-control" value="1" id="vcpus" /> + <div class="form-group"> + <div id="guest-processor"> + <label for="vcpus">$_("CPU Number")</label> + <input id="vcpus" class="form-control" name="processor" type="number" min="1" /> + <button id="guest-show-max-processor" class="btn btn-primary" type="button"><i class="fa fa-plus-circle"></i> <span class="text">$_("More")</span></button> + </div> + <div id="guest-max-processor-panel" class="form-group"> + <label for="guest-edit-max-processor-textbox">$_("Max CPU")</label> + <input id="guest-edit-max-processor-textbox" class="form-control" name="max-processor" type="number" min="1" /> </div> </div> <div class="manual form-group"> <input type="checkbox" class="wok-checkbox" id="cpus-check" /> <label for="cpus-check">$_("Manually set CPU topology")</label> </div> - <div class="topology hide"> - <div class="form-inline"> + <div class="topology"> + <div class="form-group"> + <label for="cores">$_("Cores")</label> + <input type="text" class="form-control" value="1" id="cores" /> + </div> + <div> <div class="form-group"> - <label for="cores">$_("Cores"):</label> - <input type="text" class="form-control" value="1" id="cores" /> + <label for="threads">$_("Threads")</label> + <select id="threads" class="selectpicker col-md-12 col-lg-12"></select> </div> </div> - <div class="form-group"> - <label for="threads">$_("Threads"):</label> - <select id="threads" class="col-md-2"></select> - </div> </div> </form> </div> -- 1.9.1

Applied. Thanks. Regards, Aline Manera
participants (2)
-
Aline Manera
-
Socorro Stoppler