1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

F #982: Change boot order on instantiate (#811)

Signed-off-by: Frederick Borges <fborges@opennebula.io>
This commit is contained in:
Frederick Borges 2021-02-15 16:49:29 +01:00 committed by GitHub
parent dc999c347b
commit 74924f4138
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 414 additions and 3 deletions

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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(
"<tr value=\""+value+"\">"+
"<td><input type=\"checkbox\"/></td>"+
"<td>"+value+"</td>"+
"<td><label>"+label+"</label></td>"+
"<td>"+
"<button class=\"boot-order-instantiate-provision-up button radius tiny secondary\"><i class=\"fas fa-lg fa-arrow-up\" aria-hidden=\"true\"></i></button>"+
"<button class=\"boot-order-instantiate-provision-down button radius tiny secondary\"><i class=\"fas fa-lg fa-arrow-down\" aria-hidden=\"true\"></i></button>"+
"</td>"+
"</tr>");
}
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 = "<i class=\"fas fa-fw fa-lg fa-server\"></i> ";
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 = "<i class=\"fas fa-fw fa-lg fa-globe\"></i> ";
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(
"<tr>\
<td>" + Locale.tr("Disks and NICs will appear here") + "</td>\
</tr>");
}
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")){

View File

@ -150,4 +150,25 @@
</fieldset>
</div>
</div>
{{#isFeatureEnabled "show_boot_order"}}
<div class="row provision_boot" hidden="true">
<div class="small-12 columns bootContext{{element.ID}}">
<fieldset>
<legend>
<i class="fas fa-power-off"></i> {{tr "OS Booting"}}
</legend>
<div class="provision_boot_selector" data-tab-content>
<label>
{{tr "Boot order"}}
{{{tip (tr "Select the devices to boot from, and their order")}}}
</label>
<table class="boot-order-instantiate-provision dataTable" value="">
<tbody>
</tbody>
</table>
</div>
</fieldset>
</div>
</div>
{{/isFeatureEnabled}}
</form>

View File

@ -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(
"<tr value=\""+value+"\">"+
"<td><input type=\"checkbox\"/></td>"+
"<td>"+value+"</td>"+
"<td><label>"+label+"</label></td>"+
"<td>"+
"<button class=\"boot-order-instantiate-up button radius tiny secondary\"><i class=\"fas fa-lg fa-arrow-up\" aria-hidden=\"true\"></i></button>"+
"<button class=\"boot-order-instantiate-down button radius tiny secondary\"><i class=\"fas fa-lg fa-arrow-down\" aria-hidden=\"true\"></i></button>"+
"</td>"+
"</tr>");
}
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 = "<i class=\"fas fa-fw fa-lg fa-server\"></i> ";
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 = "<i class=\"fas fa-fw fa-lg fa-globe\"></i> ";
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(
"<tr>\
<td>" + Locale.tr("Disks and NICs will appear here") + "</td>\
</tr>");
}
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);
}
}
});

View File

@ -158,5 +158,21 @@
</div>
{{/advancedImportationSection}}
{{/isFeatureEnabled}}
{{#isFeatureEnabled "show_boot_order"}}
{{#advancedImportationSection "<i class=\"fas fa-power-off\"></i>" (tr "OS Booting")}}
<div class="row">
<div class="medium-8 columns">
<label>
{{tr "Boot order"}}
{{{tip (tr "Select the devices to boot from, and their order")}}}
</label>
<table class="boot-order-instantiate dataTable" value="">
<tbody>
</tbody>
</table>
</div>
</div>
{{/advancedImportationSection}}
{{/isFeatureEnabled}}
</div>
<br>