[Kimchi-devel] [PATCH V3] [Kimchi] Introducing s390x UI Interfaces module for Edit Template under virtualization
Rajat Gupta
rajgupta at linux.vnet.ibm.com
Fri Sep 16 08:31:14 UTC 2016
Hello,
Following patch is still having merge conflict while trying to apply to
the next branch,
Hence I will be sending V4 patch.
Thanks and Regards,
Rajat Gupta
On 9/15/2016 8:34 AM, archus at linux.vnet.ibm.com wrote:
> From: Rajat Gupta <rajgupta at linux.vnet.ibm.com>
>
> Introducing s390x UI Interfaces module for Edit Template under virtualization
>
> Signed-off-by: Rajat Gupta <rajgupta at linux.vnet.ibm.com>
> ---
> ui/js/src/kimchi.api.js | 44 ++++++
> ui/js/src/kimchi.main.js | 5 +
> ui/js/src/kimchi.template_edit_main.js | 257 +++++++++++++++++++++++++++++++--
> ui/pages/template-edit.html.tmpl | 29 ++++
> 4 files changed, 319 insertions(+), 16 deletions(-)
>
> diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
> index 2f127aa..950ca00 100644
> --- a/ui/js/src/kimchi.api.js
> +++ b/ui/js/src/kimchi.api.js
> @@ -596,6 +596,34 @@ var kimchi = {
> });
> },
>
> + listmacvtapNetworks: function(suc, err) {
> + wok.requestJSON({
> + url: 'plugins/kimchi/interfaces?type=^nic|bonding|vlan$',
> + type: 'GET',
> + contentType: 'application/json',
> + dataType: 'json',
> + resend: true,
> + success: suc,
> + error: err ? err : function(data) {
> + wok.message.error(data.responseJSON.reason);
> + }
> + });
> + },
> +
> + listovsNetworks: function(suc, err) {
> + wok.requestJSON({
> + url: 'plugins/kimchi/ovsbridges',
> + type: 'GET',
> + contentType: 'application/json',
> + dataType: 'json',
> + resend: true,
> + success: suc,
> + error: err ? err : function(data) {
> + wok.message.error(data.responseJSON.reason);
> + }
> + });
> + },
> +
> toggleNetwork : function(name, on, suc, err) {
> var action = on ? "activate" : "deactivate";
> wok.requestJSON({
> @@ -1271,3 +1299,19 @@ var kimchi = {
> });
> }
> };
> +
> + /**
> + * Get the host information.
> + */
> +
> + kimchi.getHostDetails = function(suc, err) {
> + wok.requestJSON({
> + url: 'plugins/gingerbase/host',
> + type: 'GET',
> + resend: true,
> + contentType: 'application/json',
> + dataType: 'json',
> + success: suc,
> + error: err
> + });
> + }
> diff --git a/ui/js/src/kimchi.main.js b/ui/js/src/kimchi.main.js
> index b6de2cf..f3078ec 100644
> --- a/ui/js/src/kimchi.main.js
> +++ b/ui/js/src/kimchi.main.js
> @@ -33,6 +33,11 @@ kimchi.getCapabilities(function(result) {
> kimchi.capabilities = {};
> });
>
> +kimchi.hostarch = undefined;
> +kimchi.getHostDetails(function(result) {
> + kimchi.hostarch = result["architecture"];
> +});
> +
> $(function(){
> $('body').removeClass('wok-list wok-gallery');
> });
> diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js
> index a2032cc..9ccf9cc 100644
> --- a/ui/js/src/kimchi.template_edit_main.js
> +++ b/ui/js/src/kimchi.template_edit_main.js
> @@ -19,8 +19,13 @@ kimchi.template_edit_main = function() {
> var templateEditMain = $('#edit-template-tabs');
> var origDisks;
> var origNetworks;
> + var origInterfaces;
> + var origmacvtapNetworks;
> + var origovsNetworks;
> var templateDiskSize;
> var baseImageTemplate;
> + var s390xArch = 's390x';
> +
> $('#template-name', templateEditMain).val(kimchi.selectedTemplate);
> $('#edit-template-tabs a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
> $('.tab-content').css('overflow', 'hidden');
> @@ -47,6 +52,7 @@ kimchi.template_edit_main = function() {
> var initTemplate = function(template) {
> origDisks = template.disks;
> origNetworks = template.networks;
> + origInterfaces = template.interfaces;
> for (var i = 0; i < template.disks.length; i++) {
> if (template.disks[i].base) {
> template["vm-image"] = template.disks[i].base;
> @@ -268,10 +274,170 @@ kimchi.template_edit_main = function() {
> });
> };
>
> - var initProcessor = function() {
> - var setCPUValue = function() {
> - if (!$('#cores').hasClass("invalid-field") && $('#cores').val() != "") {
> - var computedCpu = parseInt($("#cores").val()) * parseInt($("#threads").val());
> + var initInterface_s390x = function(result) {
> + $('#form-template-interface-s390x').show();
> + $('#form-template-interface').hide();
> + var networkItemNum = 0;
> + var addInterfaceItem = function(networkData) {
> + var networkName = networkData.networkV;
> + var nodeInterface = $.parseHTML(wok.substitute($('#template-interface-s390x-tmpl').html(), networkData));
> + $('.template-tab-body', '#form-template-interface-s390x').append(nodeInterface);
> + $('.delete', '#form-template-interface-s390x').on("click", function(event) {
> + event.preventDefault();
> + $(this).parent().parent().remove();
> + });
> +
> + //initialize type option
> + var typeOptionsdata = {};
> + var typeOptions = '';
> + typeOptionsdata.macvtap = 'macvtap';
> + typeOptionsdata.ovs = 'ovs';
> + typeOptionsdata.network = 'network';
> +
> + $.each(typeOptionsdata, function(key, value) {
> + if (value === networkData.type) {
> + typeOptions += '<option value="' + key + '" selected="selected">' + networkData.type + '</option>';
> + } else {
> + typeOptions += '<option value="' + key + '">' + value + '</option>';
> + }
> + });
> +
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.type').append(typeOptions);
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.type').on('change', function() {
> + var itemNode = $(this).closest('div.item');
> +
> + switch ($(this).val()) {
> + case 'macvtap':
> + $('span.mode .label-mode', itemNode).addClass('hide');
> + $('span.mode .bootstrap-select', itemNode).toggleClass("hide", false);
> +
> + var networkOptions = '';
> + for (var i = 0; i < origmacvtapNetworks.length; i++) {
> + networkOptions += '<option>' + origmacvtapNetworks[i].name + '</option>';
> + }
> +
> + $('span.network select', itemNode).empty().append(networkOptions);
> + $('span.network select', itemNode).selectpicker('refresh');
> +
> + break;
> + case 'ovs':
> + $('span.mode .label-mode', itemNode).removeClass('hide');
> + $('span.mode .bootstrap-select', itemNode).toggleClass("hide", true);
> + var networkOptions = '';
> + for (var i = 0; i < origovsNetworks.length; i++) {
> + networkOptions += '<option>' + origovsNetworks[i] + '</option>';
> + }
> +
> + $('span.network select', itemNode).empty().append(networkOptions);
> + $('span.network select', itemNode).selectpicker('refresh');
> +
> + break;
> + case 'network':
> + $('span.mode .label-mode', itemNode).removeClass('hide');
> + $('span.mode .bootstrap-select', itemNode).toggleClass("hide", true);
> +
> + var networkOptions = '';
> + for (var i = 0; i < result.length; i++) {
> + if (result[i].state === "active") {
> + networkOptions += '<option>' + result[i].name + '</option>';
> + }
> + }
> + $('span.network select', itemNode).empty().append(networkOptions);
> + $('span.network select', itemNode).selectpicker('refresh');
> + break;
> + }
> + });
> +
> + switch (networkData.type) {
> + case 'macvtap':
> + //initialize network option
> + var networkOptions = '';
> + for (var i = 0; i < origmacvtapNetworks.length; i++) {
> + if (networkName === origmacvtapNetworks[i].name) {
> + networkOptions += '<option selected="selected">' + origmacvtapNetworks[i].name + '</option>';
> + }
> + networkOptions += '<option>' + origmacvtapNetworks[i].name + '</option>';
> + }
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.network').append(networkOptions);
> +
> + //initialize Mode option for Macvtap
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.mode').val(networkData.mode);
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.mode').selectpicker('refresh');
> +
> + $('span.mode .label-mode', nodeInterface).addClass('hide');
> + $('span.mode .bootstrap-select', nodeInterface).removeClass("hide");
> +
> + break;
> + case 'ovs':
> + var networkOptions = '';
> + for (var i = 0; i < origovsNetworks.length; i++) {
> + if (networkName === origovsNetworks[i]) {
> + networkOptions += '<option selected="selected">' + origovsNetworks[i] + '</option>';
> + }
> + networkOptions += '<option>' + origovsNetworks[i] + '</option>';
> + }
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.network').append(networkOptions);
> +
> + //initialize Mode option for ovs
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.mode').selectpicker('refresh');
> + $('span.mode .label-mode', nodeInterface).removeClass('hide');
> + $('span.mode .bootstrap-select', nodeInterface).addClass("hide");
> + break;
> + case 'network':
> + var networkOptions = '';
> + for (var i = 0; i < result.length; i++) {
> + if (networkName === result[i].name) {
> + networkOptions += '<option selected="selected">' + result[i].name + '</option>';
> + }
> + if (result[i].state === "active" && networkName !== result[i].name) {
> + networkOptions += '<option>' + result[i].name + '</option>';
> + }
> + }
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.network').append(networkOptions);
> +
> + //initialize Mode option for Network
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum + ' span.mode').selectpicker('refresh');
> + $('span.mode .label-mode', nodeInterface).removeClass('hide');
> + $('span.mode .bootstrap-select', nodeInterface).addClass("hide");
> + break;
> + }
> + $('select', '#form-template-interface-s390x #networkID' + networkItemNum).selectpicker();
> + networkItemNum += 1;
> + };
> + if (origInterfaces && origInterfaces.length > 0) {
> + for (var i = 0; i < origInterfaces.length; i++) {
> + addInterfaceItem({
> + networkID: 'networkID' + networkItemNum,
> + networkV: origInterfaces[i].name,
> + type: origInterfaces[i].type,
> + mode: origInterfaces[i].mode
> + });
> + }
> + }
> + if (result && result.length > 0) {
> + for (var i = 0; i < origNetworks.length; i++) {
> + addInterfaceItem({
> + networkID: 'networkID' + networkItemNum,
> + networkV: origNetworks[i],
> + type: 'network'
> + });
> + }
> + }
> + $('#template-edit-interface-add-button-s390x').on("click", function(event) {
> + event.preventDefault();
> + addInterfaceItem({
> + networkID: 'networkID' + networkItemNum,
> + networkV: 'default',
> + type: 'network',
> + mode: 'None'
> + });
> + });
> + };
> +
> + var initProcessor = function(){
> + var setCPUValue = function(){
> + if(!$('#cores').hasClass("invalid-field")&&$('#cores').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
> @@ -340,11 +506,23 @@ kimchi.template_edit_main = function() {
> });
> }
>
> - kimchi.listNetworks(initInterface);
> + if(kimchi.hostarch === s390xArch){
> + kimchi.listmacvtapNetworks(function(macvtapnet){
> + origmacvtapNetworks = macvtapnet;
> + kimchi.listovsNetworks(function(ovsnet){
> + origovsNetworks = ovsnet;
> + kimchi.listNetworks(initInterface_s390x);
> + });
> + });
> + }else {
> + kimchi.listNetworks(initInterface);
> + }
> +
> kimchi.listStoragePools(initStorage);
> initProcessor();
> checkInvalids();
> };
> +
> kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
>
> $('#tmpl-edit-button-save').on('click', function() {
> @@ -432,18 +610,65 @@ kimchi.template_edit_main = function() {
> topology: {}
> };
> }
> - var networks = $('.template-tab-body .item', '#form-template-interface');
> - var networkForUpdate = new Array();
> - $.each(networks, function(index, networkEntities) {
> - var thisValue = $('select', networkEntities).val();
> - networkForUpdate.push(thisValue);
> +
> + if(kimchi.hostarch === s390xArch){
> + var interfaces = $('.template-tab-body .item', '#form-template-interface-s390x');
> + var networkForUpdate = new Array();
> + var interfacceForUpdate = new Array();
> +
> + $.each(interfaces, function(index, interfaceEntities) {
> + var fields = $('span.type select', interfaceEntities);
> + switch(fields.val()){
> + case 'network':
> + var thisValue = $('span.network select', interfaceEntities).val();
> + networkForUpdate.push(thisValue);
> + break;
> + case 'macvtap':
> + var thisdata = {};
> + thisdata.type = $('span.type select', interfaceEntities).val();
> + thisdata.name = $('span.network select', interfaceEntities).val();
> + thisdata.mode = $('span.mode select', interfaceEntities).val();
> + interfacceForUpdate.push(thisdata);
> + break;
> + case 'ovs':
> + var thisdata = {};
> + thisdata.type = $('span.type select', interfaceEntities).val();
> + thisdata.name = $('span.network select', interfaceEntities).val();
> + interfacceForUpdate.push(thisdata);
> + break;
> + }
> +
> + if (networkForUpdate instanceof Array) {
> + data.networks = networkForUpdate;
> + } else if (networkForUpdate != null) {
> + data.networks = [networkForUpdate];
> + } else {
> + data.networks = [];
> + }
> +
> + if (networkForUpdate instanceof Array) {
> + data.interfaces = interfacceForUpdate;
> + } else if (interfacceForUpdate != null) {
> + data.interfaces = [interfacceForUpdate];
> + } else {
> + data.interfaces = [];
> + }
> });
> - if (networkForUpdate instanceof Array) {
> - data.networks = networkForUpdate;
> - } else if (networkForUpdate != null) {
> - data.networks = [networkForUpdate];
> - } else {
> - data.networks = [];
> + }else {
> + var networks = $('.template-tab-body .item', '#form-template-interface');
> + var networkForUpdate = new Array();
> + $.each(networks, function(index, networkEntities) {
> + var thisValue = $('select', networkEntities).val();
> + networkForUpdate.push(thisValue);
> + });
> +
> + if (networkForUpdate instanceof Array) {
> + data.networks = networkForUpdate;
> + } else if (networkForUpdate != null) {
> + data.networks = [networkForUpdate];
> + } else {
> + data.networks = [];
> + }
> }
>
> if ($('.has-error', '#form-template-storage').length) {
> diff --git a/ui/pages/template-edit.html.tmpl b/ui/pages/template-edit.html.tmpl
> index 6cac885..8591561 100644
> --- a/ui/pages/template-edit.html.tmpl
> +++ b/ui/pages/template-edit.html.tmpl
> @@ -129,6 +129,15 @@
> </div>
> <div class="template-tab-body"></div>
> </form>
> + <form id="form-template-interface-s390x" style="display:none">
> + <div class="template-tab-header">
> + <span class="template-interface-cell type">$_("Type")</span>
> + <span class="template-interface-cell network">$_("Network/Interface")</span>
> + <span class="template-interface-cell mode">$_("Mode")</span>
> + <button type="button" id="template-edit-interface-add-button-s390x" class="pull-right btn btn-primary"><i class="fa fa-plus-circle"></i> $_("Add Interface")</button>
> + </div>
> + <div class="template-tab-body"></div>
> + </form>
> </div>
> <div role="tabpanel" class="tab-pane" id="processor">
> <form id="form-template-processor">
> @@ -221,5 +230,25 @@
> </span>
> </div>
> </script>
> +<script id="template-interface-s390x-tmpl" type="text/html">
> + <div class="item" id={networkID}>
> + <span class="template-interface-cell type">
> + <select></select>
> + </span>
> + <span class="template-interface-cell network">
> + <select></select>
> + </span>
> + <span class="template-interface-cell mode">
> + <span class="label-mode hide">None</span>
> + <select>
> + <option value="bridge">bridge</option>
> + <option value="vepa">vepa</option>
> + </select>
> + </span>
> + <span class="pull-right">
> + <button class="delete btn-primary btn"><i class="fa fa-minus-circle"></i> $_("Delete")</button>
> + </span>
> + </div>
> +</script>
> </body>
> </html>
More information about the Kimchi-devel
mailing list