From a2d53a1dce6d8575101493e9db77f559f24c26ac Mon Sep 17 00:00:00 2001 From: Frederick Borges Date: Wed, 17 Mar 2021 12:51:52 +0100 Subject: [PATCH] F #5280: Iothread id configurable on disks (#986) Signed-off-by: Frederick Borges --- .../form-panels/create-common.js | 14 +- .../create/wizard-tabs/os/html.hbs | 4 +- .../wizard-tabs/storage/disk-tab/options.hbs | 14 ++ .../create/wizard-tabs/utils/iothreads.js | 196 ++++++++++++++++++ .../app/tabs/vms-tab/dialogs/attach-disk.js | 5 + 5 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/utils/iothreads.js diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create-common.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create-common.js index 4401ba4803..8283853034 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create-common.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create-common.js @@ -18,15 +18,14 @@ define(function(require) { /* DEPENDENCIES */ - var Notifier = require("utils/notifier"); var BaseFormPanel = require("utils/form-panels/form-panel"); var Sunstone = require("sunstone"); var Locale = require("utils/locale"); - var Tips = require("utils/tips"); var TemplateUtils = require("utils/template-utils"); var WizardFields = require("utils/wizard-fields"); var OpenNebulaAction = require("opennebula/action"); var OpenNebulaTemplate = require("opennebula/template"); + var IothreadsConf = require("./create/wizard-tabs/utils/iothreads"); /* TEMPLATES */ @@ -72,6 +71,9 @@ define(function(require) { update_title = Locale.tr("Update Virtual Router VM Template"); } + this.create_title = create_title; + this.update_title = update_title; + this.actions = { "create": { "title": create_title, @@ -274,6 +276,14 @@ define(function(require) { } } } + + if (!IothreadsConf.setupVMTemplate( + templateJSON, + this.action, + this.create_title, + this.update_title) + ) return false; + if (this.action == "create") { Sunstone.runAction(this.resource+".create", {"vmtemplate": templateJSON}); return false; diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/os/html.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/os/html.hbs index 8d66e6f84b..4e05eae81a 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/os/html.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/os/html.hbs @@ -268,9 +268,9 @@
-
diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab/options.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab/options.hbs index 8a005c8ba9..3183deab46 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab/options.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab/options.hbs @@ -255,4 +255,18 @@ + +
+ {{tr "IOTHREADS"}} +
+
+
+ + +
+
+
\ No newline at end of file diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/utils/iothreads.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/utils/iothreads.js new file mode 100644 index 0000000000..0bf77a7579 --- /dev/null +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/utils/iothreads.js @@ -0,0 +1,196 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +define(function(require) { + + var Notifier = require("utils/notifier"); + + /* + CONSTRUCTOR + */ + + return { + 'setupVMTemplate': _setupVMTemplate, + 'setupAttachDisk': _setupAttachDisk, + }; + + /* + FUNCTIONS + */ + + /** + * Convert first letter to upper case + * @param {string} string + */ + function capitalize (string) { + return string[0].toUpperCase() + string.slice(1) + } + + /** + * Function to set an error with the iothread attribute of the given disk in the VMTemplate context. + * @param {string} diskId Id of the disk which has the wrong value of iothreads. + * @param {string} diskType Type of the disk which the wrong value ofiothreads. + */ + function _setErrorDiskVMTemplate (diskId, diskType) { + $('div[diskid="' + diskId + '"] div.' + diskType + ' input[name="IOTHREAD"]').addClass('is-invalid-input'); + $('div[diskid="' + diskId + '"] div.' + diskType + ' label[for="IOTHREAD"]').addClass('is-invalid-label'); + } + + /** + * Function to unset an error with the iothread attribute of the given disk in the VMTemplate context. + * @param {string} diskId Id of the disk which has the wrong value of iothreads. + * @param {string} diskType Type of the disk which the wrong value ofiothreads. + */ + function _unsetErrorDiskVMTemplate (diskId, diskType) { + $('div[diskid="' + diskId + '"] div.' + diskType + ' input[name="IOTHREAD"]').removeClass('is-invalid-input'); + $('div[diskid="' + diskId + '"] div.' + diskType + ' label[for="IOTHREAD"]').removeClass('is-invalid-label'); + } + + /** + * Function to set an error with the iothreads attribute on the features section in the VMTemplate context. + */ + function _setErrorFeaturesIothreads () { + $('#tabs-bootos input[wizard_field="IOTHREADS"]').addClass('is-invalid-input'); + $('#tabs-bootos label.features_iothreads').addClass('is-invalid-label'); + } + + /** + * Function to unset an error with the iothreads attribute on the features section in the VMTemplate context. + */ + function _unsetErrorFeaturesIothreads () { + $('#tabs-bootos input[wizard_field="IOTHREADS"]').removeClass('is-invalid-input'); + $('#tabs-bootos label.features_iothreads').removeClass('is-invalid-label'); + } + + /** + * Function to read the actual value from OS & CPU -> Features -> Iothreads + * If it's not configured iothreads = 0; + * @param {JSON} templateJSON Current VM template + * @returns Max iothread configurable value. + */ + function _getMaxIothreads (templateJSON) { + var iothreads = 0; + if (templateJSON && + templateJSON.FEATURES && + templateJSON.FEATURES.IOTHREADS){ + iothreads = parseInt(templateJSON.FEATURES.IOTHREADS, 10); + } + + return iothreads; + } + + /** + * Function to take all disks from the template. + * @param {JSON} templateJSON + * @returns JSON with all the VM disks. + */ + function _getDisks (templateJSON) { + var disks = templateJSON.DISK || []; + if (templateJSON && templateJSON.DISK && !templateJSON.DISK instanceof Array){ + disks = [templateJSON.DISK] + } + + return disks; + } + + /** + * Validate if all disks have correctly set an iothread value + * between 0 and iothreads-1. + * @param {int} iothreads Maximun number of iothreads. + * @param {Array} disks Array with disks templates for this VM template. + * @returns Array with disks templates with errors in IOTHREAD. + */ + function _checkDisksVMTemplate (iothreads, disks) { + var disksWithError = []; + disks.forEach(function (element, index) { + var diskId = index + 1; + var diskType; + if (element && element.IOTHREAD && (element.IOTHREAD >= iothreads || element.IOTHREAD < 0)){ + disksWithError.push(index); + _setErrorDiskVMTemplate(diskId.toString(10), diskType); + } + else{ + _unsetErrorDiskVMTemplate(diskId.toString(10), diskType); + } + }); + + return disksWithError; + } + + /** + * Function to notify the error with the iothreads value. + * @param {int} iothreads Maximum iothreads value. + * @param {Array} disks Disks with errors on the iothreads value. + */ + function _notifyError (iothreads, disks) { + if (iothreads === 0){ + _setErrorFeaturesIothreads(); + Notifier.notifyError("Maximum IOTHREADS value must be configured, please proceed to OS & CPU -> Features"); + } + else{ + _unsetErrorFeaturesIothreads(); + var error = "Disk IOTHREAD id must be between 0 and " + (iothreads-1).toString(10) + " (maximum number of IOTHREADS configured - 1). Please check: "; + disks.forEach(function (id){ + error += "Disk" + id.toString(10); + if (id != disks[disks.length-1]) error += ", "; + }); + error += "."; + Notifier.notifyError(error); + } + } + + /** + * Function to verify the values of the iothreads on the VMTemplate. + * @param {JSON} templateJSON Current VM template + * @returns True if everything goes well, false if there is an error. + */ + function _setupVMTemplate (templateJSON, action, create_title, update_title) { + var iothreads = _getMaxIothreads(templateJSON); + var disks = _getDisks(templateJSON); + var errorDisks = _checkDisksVMTemplate(iothreads, disks); + + if (errorDisks.length > 0){ + _notifyError(iothreads, errorDisks); + var button = $('#templates-tabsubmit_button > button'); + button.removeAttr('disabled'); + button.text(capitalize(action)); + var header = $('span.sunstone-form-title'); + if (action == "create") + header.text(create_title); + else + header.text(update_title); + return false; + } + + return true; + } + + /** + * Function to block the Iothread id input on the Attach Disk Context. + * @param {JSON} templateJSON Current VM template + */ + function _setupAttachDisk (templateJSON) { + var iothreads = _getMaxIothreads(templateJSON); + if (iothreads === 0){ + $('#attachDiskVMDialogForm input[name="IOTHREAD"]').attr('disabled','disabled'); + $('#attachDiskVMDialogForm input[name="IOTHREAD"]').removeAttr('max'); + }else{ + $('#attachDiskVMDialogForm input[name="IOTHREAD"]').removeAttr('disabled'); + $('#attachDiskVMDialogForm input[name="IOTHREAD"]').attr('max', iothreads); + } + } + +}); \ No newline at end of file diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-disk.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-disk.js index d5b8a50c7d..57de436d1b 100644 --- a/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-disk.js +++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-disk.js @@ -25,6 +25,7 @@ define(function(require) { var Notifier = require('utils/notifier'); var Tips = require('utils/tips'); var DiskTab = require('tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab'); + var IothreadsConf = require('tabs/templates-tab/form-panels/create/wizard-tabs/utils/iothreads'); var WizardFields = require('utils/wizard-fields'); /* @@ -101,6 +102,10 @@ define(function(require) { $('.hybrid_plus_section').show(); } + if (this && this.element && this.element.TEMPLATE){ + IothreadsConf.setupAttachDisk(this.element.TEMPLATE); + } + return false; }