From 74924f4138ea7566f8655e42e7ca20d6f69019fb Mon Sep 17 00:00:00 2001 From: Frederick Borges Date: Mon, 15 Feb 2021 16:49:29 +0100 Subject: [PATCH] F #982: Change boot order on instantiate (#811) Signed-off-by: Frederick Borges --- .../etc/sunstone-views/kvm/admin.yaml | 3 + .../etc/sunstone-views/kvm/cloud.yaml | 3 + .../etc/sunstone-views/kvm/groupadmin.yaml | 2 +- src/sunstone/etc/sunstone-views/kvm/user.yaml | 3 + .../etc/sunstone-views/mixed/admin.yaml | 3 + .../etc/sunstone-views/mixed/cloud.yaml | 3 + .../etc/sunstone-views/mixed/groupadmin.yaml | 5 +- .../etc/sunstone-views/mixed/user.yaml | 3 + .../etc/sunstone-views/vcenter/admin.yaml | 3 + .../etc/sunstone-views/vcenter/cloud.yaml | 3 + .../sunstone-views/vcenter/groupadmin.yaml | 5 +- .../etc/sunstone-views/vcenter/user.yaml | 3 + src/sunstone/public/app/tabs/provision-tab.js | 174 ++++++++++++++++++ .../app/tabs/provision-tab/vms/create.hbs | 21 +++ .../templates-tab/form-panels/instantiate.js | 167 +++++++++++++++++ .../form-panels/instantiate/templateRow.hbs | 16 ++ 16 files changed, 414 insertions(+), 3 deletions(-) diff --git a/src/sunstone/etc/sunstone-views/kvm/admin.yaml b/src/sunstone/etc/sunstone-views/kvm/admin.yaml index f847642fec..628ba2ebb5 100644 --- a/src/sunstone/etc/sunstone-views/kvm/admin.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/admin.yaml @@ -102,6 +102,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: dashboard-tab: # The following widgets can be used inside any of the '_per_row' settings diff --git a/src/sunstone/etc/sunstone-views/kvm/cloud.yaml b/src/sunstone/etc/sunstone-views/kvm/cloud.yaml index caca25b61c..446189419b 100644 --- a/src/sunstone/etc/sunstone-views/kvm/cloud.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/cloud.yaml @@ -44,6 +44,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: provision-tab: panel_tabs: diff --git a/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml b/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml index ee4372ee16..abcdafedfe 100644 --- a/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml @@ -252,7 +252,7 @@ tabs: Template.refresh: true Template.create_dialog: false Template.import_dialog: false - Template.update_dialog: false + Template.update_dialog: true Template.instantiate_vms: true Template.rename: true Template.chown: true diff --git a/src/sunstone/etc/sunstone-views/kvm/user.yaml b/src/sunstone/etc/sunstone-views/kvm/user.yaml index dea9d15a86..cf6f2ac9be 100644 --- a/src/sunstone/etc/sunstone-views/kvm/user.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/user.yaml @@ -96,6 +96,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: dashboard-tab: # The following widgets can be used inside any of the '_per_row' settings diff --git a/src/sunstone/etc/sunstone-views/mixed/admin.yaml b/src/sunstone/etc/sunstone-views/mixed/admin.yaml index aed18fd5a9..c0f7eff166 100644 --- a/src/sunstone/etc/sunstone-views/mixed/admin.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/admin.yaml @@ -102,6 +102,9 @@ features: # True to show schedule actions to instantiate a VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: dashboard-tab: # The following widgets can be used inside any of the '_per_row' settings diff --git a/src/sunstone/etc/sunstone-views/mixed/cloud.yaml b/src/sunstone/etc/sunstone-views/mixed/cloud.yaml index ff54e29059..f5fe6ec6ef 100644 --- a/src/sunstone/etc/sunstone-views/mixed/cloud.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/cloud.yaml @@ -44,6 +44,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: provision-tab: panel_tabs: diff --git a/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml b/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml index d998cab7e1..4a76e9f81a 100644 --- a/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml @@ -102,6 +102,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: dashboard-tab: # The following widgets can be used inside any of the '_per_row' settings @@ -252,7 +255,7 @@ tabs: Template.refresh: true Template.create_dialog: false Template.import_dialog: false - Template.update_dialog: false + Template.update_dialog: true Template.instantiate_vms: true Template.rename: true Template.chown: true diff --git a/src/sunstone/etc/sunstone-views/mixed/user.yaml b/src/sunstone/etc/sunstone-views/mixed/user.yaml index 6d7fda8972..bc56f602fd 100644 --- a/src/sunstone/etc/sunstone-views/mixed/user.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/user.yaml @@ -96,6 +96,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: dashboard-tab: # The following widgets can be used inside any of the '_per_row' settings diff --git a/src/sunstone/etc/sunstone-views/vcenter/admin.yaml b/src/sunstone/etc/sunstone-views/vcenter/admin.yaml index 8fa6ba56ff..331c0cfb06 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/admin.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/admin.yaml @@ -102,6 +102,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: dashboard-tab: # The following widgets can be used inside any of the '_per_row' settings diff --git a/src/sunstone/etc/sunstone-views/vcenter/cloud.yaml b/src/sunstone/etc/sunstone-views/vcenter/cloud.yaml index 16e9513610..e820265062 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/cloud.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/cloud.yaml @@ -44,6 +44,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: provision-tab: panel_tabs: diff --git a/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml b/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml index 02a68d1e33..52df7942e0 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml @@ -102,6 +102,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: dashboard-tab: # The following widgets can be used inside any of the '_per_row' settings @@ -252,7 +255,7 @@ tabs: Template.refresh: true Template.create_dialog: false Template.import_dialog: false - Template.update_dialog: false + Template.update_dialog: true Template.instantiate_vms: true Template.rename: true Template.chown: true diff --git a/src/sunstone/etc/sunstone-views/vcenter/user.yaml b/src/sunstone/etc/sunstone-views/vcenter/user.yaml index 51c1bb772a..195d3ed357 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/user.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/user.yaml @@ -96,6 +96,9 @@ features: # True to show schedule actions section to instantiate VM show_sched_actions_instantiate: true + + # True to show boot order section to instantiate VM + show_boot_order: true tabs: dashboard-tab: # The following widgets can be used inside any of the '_per_row' settings diff --git a/src/sunstone/public/app/tabs/provision-tab.js b/src/sunstone/public/app/tabs/provision-tab.js index 7db8bacee3..50dc19cd49 100644 --- a/src/sunstone/public/app/tabs/provision-tab.js +++ b/src/sunstone/public/app/tabs/provision-tab.js @@ -51,6 +51,11 @@ define(function(require) { var TemplateDashboardGroupVms = require("hbs!./provision-tab/dashboard/group-vms"); var TAB_ID = require("./provision-tab/tabId"); var FLOW_TEMPLATE_LABELS_COLUMN = 2; + + var distinct = function(value, index, self){ + return self.indexOf(value)===index; + }; + var povision_actions = { "Provision.Flow.instantiate" : { type: "single", @@ -632,6 +637,7 @@ define(function(require) { $("#provision_create_vm .provision_add_vmgroup").show(); $("#provision_create_vm .provision_vmgroup").hide(); $("#provision_create_vm .provision_ds").hide(); + $("#provision_create_vm .provision_boot").hide(); $("#provision_create_vm .provision_custom_attributes_selector").html(""); $("#provision_create_vm li:not(.is-active) a[href='#provision_dd_template']").trigger("click"); $("#provision_create_vm .total_cost_div").hide(); @@ -851,6 +857,153 @@ define(function(require) { } return true; } + + //---------------------------------------------------------------------------- + // Boot order + //---------------------------------------------------------------------------- + + function _retrieveBootValue(context) { + return $("table.boot-order-instantiate-provision", context).attr("value"); + } + + function _fillBootValue(context, value) { + return $("table.boot-order-instantiate-provision", context).attr("value", value); + } + + function _refreshBootValue(context) { + var table = $("table.boot-order-instantiate-provision", context); + + var devices = []; + + $.each($("tr", table), function(){ + if ($("input", this).is(":checked")){ + devices.push( $(this).attr("value") ); + } + }); + + table.attr("value", devices.join(",")); + } + + function _addBootRow(context, value, label) { + $("table.boot-order-instantiate-provision tbody", context).append( + ""+ + ""+ + ""+value+""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""); + } + + function _loadBootOrder(context, templateJSON) { + var table = $("table.boot-order-instantiate-provision", context); + var prev_value = $(table).attr("value"); + + $("table.boot-order-instantiate-provision tbody", context).html(""); + + if (templateJSON.DISK !== undefined){ + var disks = templateJSON.DISK; + + if (!$.isArray(disks)){ + disks = [disks]; + } + disks = disks.filter(distinct); + + $.each(disks, function(i,disk){ + var label = " "; + var disk_name = "disk"; + + if (disk.IMAGE !== undefined){ + label += disk.IMAGE; + } else if (disk.IMAGE_ID !== undefined){ + label += Locale.tr("Image ID") + " " + disk.IMAGE_ID; + } else { + label += Locale.tr("Volatile"); + } + + if (disk.DISK_ID === undefined){ + disk_name += i; + } else { + disk_name += disk.DISK_ID; + } + + _addBootRow(context, disk_name, label); + }); + } + + if (templateJSON.NIC !== undefined){ + var nics = templateJSON.NIC; + + if (!$.isArray(nics)){ + nics = [nics]; + } + nics = nics.filter(distinct); + nics.map(function(nic,i){ + var label = " "; + if (nic && nic.NETWORK && nic.NETWORK !== undefined){ + label += nic.NETWORK; + } else if (nic.NETWORK_ID !== undefined){ + label += Locale.tr("Network ID") + " " + nic.NETWORK_ID; + } else { + label += Locale.tr("Manual settings"); + } + _addBootRow(context, "nic"+i, label); + }); + } + + if (templateJSON.DISK === undefined && templateJSON.NIC === undefined){ + $("table.boot-order-instantiate-provision tbody", context).append( + "\ + " + Locale.tr("Disks and NICs will appear here") + "\ + "); + } + + if (prev_value.length > 0){ + var pos = 0; + + $.each(prev_value.split(","), function(i,device){ + var tr = $("tr[value=\"" + device + "\"]", table); + + if(tr.length > 0){ + $($("tr", table)[pos]).before(tr); + $("input", tr).click(); + + pos += 1; + } + }); + + _refreshBootValue(context); + } + } + + tab.on("click", "button.boot-order-instantiate-provision-up", function(){ + var tr = $(this).closest("tr"); + tr.prev().before(tr); + + _refreshBootValue(tab); + + return false; + }); + + tab.on("click", "button.boot-order-instantiate-provision-down", function(){ + var tr = $(this).closest("tr"); + tr.next().after(tr); + + _refreshBootValue(tab); + + return false; + }); + + $("table.boot-order-instantiate-provision tbody", tab).on("change", "input", function(){ + _refreshBootValue(tab); + }); + + //---------------------------------------------------------------------------- + // End Boot order + //---------------------------------------------------------------------------- + provision_vm_instantiate_templates_datatable = $("#provision_vm_instantiate_templates_table").dataTable({ "iDisplayLength": 6, "bAutoWidth": false, @@ -965,6 +1118,7 @@ define(function(require) { $("#provision_create_vm .provision_vmgroup").show(); $("#provision_create_vm .provision_ds").show(); + $("#provision_create_vm .provision_boot").show(); OpenNebula.Template.show({ data : { @@ -974,6 +1128,7 @@ define(function(require) { timeout: true, success: function (request, template_json) { that.template_base_json= template_json; + tab.template_base_json = template_json; } }); @@ -1077,6 +1232,15 @@ define(function(require) { $(".provision_custom_attributes_selector", create_vm_context).html(""); } + // boot order + + var osJSON = template_json.VMTEMPLATE.TEMPLATE.OS; + if (osJSON && osJSON["BOOT"]) { + _fillBootValue(create_vm_context, osJSON["BOOT"]); + } + + _loadBootOrder(create_vm_context, template_json.VMTEMPLATE.TEMPLATE) + }, error: function(request, error_json, container) { Notifier.onError(request, error_json, container); @@ -1168,6 +1332,16 @@ define(function(require) { extra_info.template.TOPOLOGY = topology; } + var boot = _retrieveBootValue(context); + var os = tab.template_base_json.VMTEMPLATE.TEMPLATE.OS ? tab.template_base_json.VMTEMPLATE.TEMPLATE.OS : {}; + + if (boot && boot.length > 0) { + os.BOOT = boot + extra_info.template.OS = os; + } else { + extra_info.template.OS = os; + } + var action; if ($("input.instantiate_pers", context).prop("checked")){ diff --git a/src/sunstone/public/app/tabs/provision-tab/vms/create.hbs b/src/sunstone/public/app/tabs/provision-tab/vms/create.hbs index b025c758d7..af449426d0 100644 --- a/src/sunstone/public/app/tabs/provision-tab/vms/create.hbs +++ b/src/sunstone/public/app/tabs/provision-tab/vms/create.hbs @@ -150,4 +150,25 @@ + {{#isFeatureEnabled "show_boot_order"}} + + {{/isFeatureEnabled}} \ No newline at end of file diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js index e0be6ff262..55e95028df 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js @@ -55,6 +55,10 @@ define(function(require) { var CREATE = true; var contextRow; + var distinct = function(value, index, self){ + return self.indexOf(value)===index; + }; + /* CONSTRUCTOR */ @@ -200,6 +204,32 @@ define(function(require) { ScheduleActions.fill($(this),context); } }); + + //---------------------------------------------------------------------------- + // Boot order + //---------------------------------------------------------------------------- + + context.on("click", "button.boot-order-instantiate-up", function(){ + var tr = $(this).closest("tr"); + tr.prev().before(tr); + + _refreshBootValue(context); + + return false; + }); + + context.on("click", "button.boot-order-instantiate-down", function(){ + var tr = $(this).closest("tr"); + tr.next().after(tr); + + _refreshBootValue(context); + + return false; + }); + + $("table.boot-order-instantiate tbody", context).on("change", "input", function(){ + _refreshBootValue(context); + }); } function _calculateCost(){ @@ -428,6 +458,16 @@ define(function(require) { tmp_json.TOPOLOGY = topology; } + var boot = _retrieveBootValue(context); + var os = original_tmpl.TEMPLATE.OS ? original_tmpl.TEMPLATE.OS : {}; + + if (boot && boot.length > 0) { + os.BOOT = boot + tmp_json.OS = os; + } else { + tmp_json.OS = os; + } + extra_info["template"] = tmp_json; for (var i = 0; i < n_times_int; i++) { extra_info["vm_name"] = vm_name.replace(/%i/gi, i); // replace wildcard @@ -679,6 +719,13 @@ define(function(require) { if (idsLength == idsDone){ Sunstone.enableFormPanelSubmit(that.tabId); } + + var osJSON = template_json.VMTEMPLATE.TEMPLATE.OS; + if (osJSON && osJSON["BOOT"]) { + _fillBootValue(context, osJSON["BOOT"]); + } + + _loadBootOrder(context, template_json.VMTEMPLATE.TEMPLATE) }, error: function(request, error_json, container) { Notifier.onError(request, error_json, container); @@ -726,4 +773,124 @@ define(function(require) { $("#SCHED_REQUIREMENTS" + id, context).val(req_string.join(" | ")); $("#SCHED_DS_REQUIREMENTS" + id, context).val(req_ds_string.join(" | ")); } + + //---------------------------------------------------------------------------- + // Boot order + //---------------------------------------------------------------------------- + + function _retrieveBootValue(context) { + return $("table.boot-order-instantiate", context).attr("value"); + } + + function _fillBootValue(context, value) { + return $("table.boot-order-instantiate", context).attr("value", value); + } + + function _refreshBootValue(context) { + var table = $("table.boot-order-instantiate", context); + + var devices = []; + + $.each($("tr", table), function(){ + if ($("input", this).is(":checked")){ + devices.push( $(this).attr("value") ); + } + }); + + table.attr("value", devices.join(",")); + } + + function _addBootRow(context, value, label) { + $("table.boot-order-instantiate tbody", context).append( + ""+ + ""+ + ""+value+""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""); + } + + function _loadBootOrder(context, templateJSON) { + var table = $("table.boot-order-instantiate", context); + var prev_value = $(table).attr("value"); + + $("table.boot-order-instantiate tbody", context).html(""); + + if (templateJSON.DISK !== undefined){ + var disks = templateJSON.DISK; + + if (!$.isArray(disks)){ + disks = [disks]; + } + disks = disks.filter(distinct); + + $.each(disks, function(i,disk){ + var label = " "; + var disk_name = "disk"; + + if (disk.IMAGE !== undefined){ + label += disk.IMAGE; + } else if (disk.IMAGE_ID !== undefined){ + label += Locale.tr("Image ID") + " " + disk.IMAGE_ID; + } else { + label += Locale.tr("Volatile"); + } + + if (disk.DISK_ID === undefined){ + disk_name += i; + } else { + disk_name += disk.DISK_ID; + } + + _addBootRow(context, disk_name, label); + }); + } + + if (templateJSON.NIC !== undefined){ + var nics = templateJSON.NIC; + + if (!$.isArray(nics)){ + nics = [nics]; + } + nics = nics.filter(distinct); + nics.map(function(nic,i){ + var label = " "; + if (nic && nic.NETWORK && nic.NETWORK !== undefined){ + label += nic.NETWORK; + } else if (nic.NETWORK_ID !== undefined){ + label += Locale.tr("Network ID") + " " + nic.NETWORK_ID; + } else { + label += Locale.tr("Manual settings"); + } + _addBootRow(context, "nic"+i, label); + }); + } + + if (templateJSON.DISK === undefined && templateJSON.NIC === undefined){ + $("table.boot-order-instantiate tbody", context).append( + "\ + " + Locale.tr("Disks and NICs will appear here") + "\ + "); + } + + if (prev_value.length > 0){ + var pos = 0; + + $.each(prev_value.split(","), function(i,device){ + var tr = $("tr[value=\"" + device + "\"]", table); + + if(tr.length > 0){ + $($("tr", table)[pos]).before(tr); + $("input", tr).click(); + + pos += 1; + } + }); + + _refreshBootValue(context); + } + } }); diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs index adb20e330a..b7503f8bf7 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs @@ -158,5 +158,21 @@ {{/advancedImportationSection}} {{/isFeatureEnabled}} + {{#isFeatureEnabled "show_boot_order"}} + {{#advancedImportationSection "" (tr "OS Booting")}} +
+
+ + + + +
+
+
+ {{/advancedImportationSection}} + {{/isFeatureEnabled}}
\ No newline at end of file