1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-23 22:50:09 +03:00

F #1636: Add CPU_MODEL in VM Template (#2751)

This commit is contained in:
Jorge Miguel Lobo Escalona 2023-09-22 12:15:52 +02:00 committed by GitHub
parent 3008f8ab69
commit d59f30c382
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 201 additions and 29 deletions

View File

@ -0,0 +1,81 @@
/* ------------------------------------------------------------------------- *
* Copyright 2002-2023, 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. *
* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- *
* Copyright 2002-2023, 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. *
* ------------------------------------------------------------------------- */
import { array, string } from 'yup'
import {
DEFAULT_CPU_MODELS,
HYPERVISORS,
INPUT_TYPES,
T,
} from 'client/constants'
import { useGetHostsQuery } from 'client/features/OneApi/host'
import { getKvmCpuFeatures, getKvmCpuModels } from 'client/models/Host'
import { Field, arrayToOptions } from 'client/utils'
const { vcenter, firecracker, lxc } = HYPERVISORS
/** @type {Field} CPU model field */
export const MODEL = {
name: 'CPU_MODEL.MODEL',
label: T.CpuModel,
notOnHypervisors: [vcenter, firecracker, lxc],
type: INPUT_TYPES.SELECT,
values: () => {
const { data: hosts = [] } = useGetHostsQuery()
const kvmCpuModels = getKvmCpuModels(hosts)
kvmCpuModels.unshift(...DEFAULT_CPU_MODELS)
return arrayToOptions(kvmCpuModels)
},
validation: string()
.trim()
.notRequired()
.default(() => undefined),
}
/** @type {Field} Features field */
export const FEATURES = {
name: 'CPU_MODEL.FEATURES',
label: T.CpuFeature,
notOnHypervisors: [vcenter, firecracker, lxc],
type: INPUT_TYPES.SELECT,
multiple: true,
values: () => {
const { data: hosts = [] } = useGetHostsQuery()
const kvmFeatures = getKvmCpuFeatures(hosts)
return arrayToOptions(kvmFeatures)
},
validation: array(string().trim()).default(() => []),
}
/** @type {Field[]} List of CPU_MODEL fields */
export const CPU_MODEL_FIELDS = [MODEL, FEATURES]

View File

@ -17,19 +17,20 @@
import { BaseSchema, string } from 'yup'
import { BOOT_FIELDS } from './bootSchema'
import { CPU_MODEL_FIELDS } from './cpuModelSchema'
import { FEATURES_FIELDS } from './featuresSchema'
import { KERNEL_FIELDS } from './kernelSchema'
import { RAMDISK_FIELDS } from './ramdiskSchema'
import { FEATURES_FIELDS } from './featuresSchema'
import { RAW_FIELDS } from './rawSchema'
import { HYPERVISORS, T } from 'client/constants'
import {
Field,
Section,
getObjectSchemaFromFields,
filterFieldsByHypervisor,
disableFields,
filterFieldsByHypervisor,
getObjectSchemaFromFields,
} from 'client/utils'
import { T, HYPERVISORS } from 'client/constants'
/**
* @param {HYPERVISORS} [hypervisor] - Template hypervisor
@ -39,10 +40,10 @@ import { T, HYPERVISORS } from 'client/constants'
*/
const SECTIONS = (hypervisor, oneConfig, adminGroup) => [
{
id: 'os-boot',
legend: T.Boot,
id: 'os-cpu-model',
legend: T.CpuModel,
fields: disableFields(
filterFieldsByHypervisor(BOOT_FIELDS, hypervisor),
filterFieldsByHypervisor(CPU_MODEL_FIELDS, hypervisor),
'OS',
oneConfig,
adminGroup
@ -78,6 +79,16 @@ const SECTIONS = (hypervisor, oneConfig, adminGroup) => [
adminGroup
),
},
{
id: 'os-boot',
legend: T.Boot,
fields: disableFields(
filterFieldsByHypervisor(BOOT_FIELDS, hypervisor),
'OS',
oneConfig,
adminGroup
),
},
{
id: 'os-raw',
legend: T.RawData,
@ -117,9 +128,10 @@ const FIELDS = (hypervisor) => [
*/
const SCHEMA = (hypervisor) => getObjectSchemaFromFields(FIELDS(hypervisor))
export { SECTIONS, FIELDS, BOOT_ORDER_FIELD, SCHEMA }
export * from './bootSchema'
export * from './cpuModelSchema'
export * from './featuresSchema'
export * from './kernelSchema'
export * from './ramdiskSchema'
export * from './featuresSchema'
export * from './rawSchema'
export { BOOT_ORDER_FIELD, FIELDS, SCHEMA, SECTIONS }

View File

@ -15,25 +15,25 @@
* ------------------------------------------------------------------------- */
import { reach } from 'yup'
import General, {
STEP_ID as GENERAL_ID,
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/General'
import ExtraConfiguration, {
STEP_ID as EXTRA_ID,
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration'
import CustomVariables, {
STEP_ID as CUSTOM_ID,
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/CustomVariables'
import ExtraConfiguration, {
STEP_ID as EXTRA_ID,
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration'
import General, {
STEP_ID as GENERAL_ID,
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/General'
import { MEMORY_RESIZE_OPTIONS, T } from 'client/constants'
import { jsonToXml, userInputsToArray } from 'client/models/Helper'
import {
convertToMB,
createSteps,
isBase64,
encodeBase64,
getUnknownAttributes,
convertToMB,
isBase64,
} from 'client/utils'
import { T, MEMORY_RESIZE_OPTIONS } from 'client/constants'
/**
* Encodes the start script value to base64 if it is not already encoded.
@ -65,16 +65,26 @@ const Steps = createSteps([General, ExtraConfiguration, CustomVariables], {
order: vmTemplate?.TEMPLATE?.INPUTS_ORDER,
})
const knownTemplate = schema.cast(
{
[GENERAL_ID]: { ...vmTemplate, ...vmTemplate?.TEMPLATE },
[EXTRA_ID]: { ...vmTemplate?.TEMPLATE, USER_INPUTS: userInputs },
const objectSchema = {
[GENERAL_ID]: { ...vmTemplate, ...vmTemplate?.TEMPLATE },
[EXTRA_ID]: {
...vmTemplate?.TEMPLATE,
USER_INPUTS: userInputs,
},
{
stripUnknown: true,
context: { ...vmTemplate, [EXTRA_ID]: vmTemplate.TEMPLATE },
}
// cast CPU_MODEL/FEATURES
if (vmTemplate?.TEMPLATE?.CPU_MODEL?.FEATURES) {
objectSchema[EXTRA_ID].CPU_MODEL = {
...vmTemplate?.TEMPLATE?.CPU_MODEL,
FEATURES: (vmTemplate?.TEMPLATE?.CPU_MODEL?.FEATURES ?? '').split(','),
}
)
}
const knownTemplate = schema.cast(objectSchema, {
stripUnknown: true,
context: { ...vmTemplate, [EXTRA_ID]: vmTemplate.TEMPLATE },
})
const knownAttributes = {
...knownTemplate[GENERAL_ID],
@ -135,6 +145,12 @@ const Steps = createSteps([General, ExtraConfiguration, CustomVariables], {
general.MEMORY = convertToMB(general.MEMORY, general.MEMORYUNIT)
delete general.MEMORYUNIT
// cast CPU_MODEL/FEATURES
if (Array.isArray(extraTemplate?.CPU_MODEL?.FEATURES)) {
extraTemplate.CPU_MODEL.FEATURES =
extraTemplate.CPU_MODEL.FEATURES.join(', ')
}
return jsonToXml({
...customVariables,
...extraTemplate,

View File

@ -920,6 +920,7 @@ module.exports = {
'This attribute allows to define the type of firmware used to boot the VM',
FirmwareSecure: 'Firmware secure',
CpuModel: 'CPU Model',
CpuFeature: 'CPU Features',
CustomPath: 'Customize with path',
/* VM Template schema - OS & CPU - kernel */
Kernel: 'Kernel',

View File

@ -130,6 +130,22 @@ export const getKvmCpuModels = (hosts = []) => {
return [...new Set(hostData)]
}
/**
* Returns list of KVM CPU Features available from the host pool.
*
* @param {Host[]} hosts - Hosts
* @returns {Array} List of KVM Machines from the pool
*/
export const getKvmCpuFeatures = (hosts = []) => {
const machineTypes = hosts
.filter((host) => host?.TEMPLATE?.HYPERVISOR === HYPERVISORS.kvm)
.map((host) => host.TEMPLATE?.KVM_CPU_FEATURES.split(','))
.flat()
// Removes the repeated
return [...new Set(machineTypes)]
}
/**
* Returns list of KVM Machines available from the host pool.
*

View File

@ -295,7 +295,48 @@ define(function(require) {
});
fillMachineTypesAndCPUModel(context);
fillCPUFeatures(context);
}
function fillCPUFeatures (context, cpuModel){
OpenNebulaHost.list({
data : {},
timeout: true,
success: function (request, infoHosts){
var cpuFeatures = []
infoHosts.forEach((host)=> {
if(host && host.HOST && host.HOST.IM_MAD === 'kvm' && host.HOST.TEMPLATE && host.HOST.TEMPLATE.KVM_CPU_FEATURES){
var arrayFeatures = host.HOST.TEMPLATE.KVM_CPU_FEATURES.split(",")
for (var i = 0; i < arrayFeatures.length; i++) {
var currentValue = arrayFeatures[i];
if (cpuFeatures.indexOf(currentValue) === -1) {
cpuFeatures.push(currentValue);
}
}
}
})
var idSelector = 'feature-cpu'
var html = '<select id="'+idSelector+'" wizard_field="FEATURES" multiple>';
$.each(cpuFeatures, function(i, cpuFeature){
html += '<option value="' + cpuFeature + '">' + cpuFeature + '</option>';
});
html += '</select>';
var inputFeatures = $('#cpu-features', context)
inputFeatures.find("#"+idSelector).remove()
$('#cpu-features', context).append(html);
if (cpuModel && cpuModel.FEATURES){
var values = cpuModel.FEATURES.split(",")
$('#'+idSelector+' option').each(function(){
var option = $(this);
var value = option.val();
if ($.inArray(value, values) !== -1) {
option.prop("selected", true);
}
})
}
}
})
}
function fillMachineTypesAndCPUModel(context, cpuModel, machineType){
@ -404,7 +445,6 @@ define(function(require) {
var osJSON = templateJSON["OS"];
var modelJSON = templateJSON["CPU_MODEL"];
if (osJSON) {
if (osJSON["KERNEL_DS"] === undefined && osJSON["KERNEL"] !== undefined){
$("input[value=\"kernel_path\"]", context).click();
}
@ -445,7 +485,8 @@ define(function(require) {
}
fillMachineTypesAndCPUModel(context, modelJSON, osJSON);
fillCPUFeatures(context, modelJSON)
delete templateJSON["OS"];
delete templateJSON["CPU_MODEL"];
}

View File

@ -306,11 +306,16 @@
</div>
<div class="wizard_internal_tab tabs-panel cpuTab" id="cpuTab{{uniqueId}}">
<div class="row">
<div class="medium-4 columns">
<div class="medium-6 columns">
<label id="cpu-model">
{{tr "CPU Model"}}
</label>
</div>
<div class="medium-6 columns">
<label id="cpu-features">
{{tr "CPU Features"}}
</label>
</div>
</div>
</div>
</div>