Skip to content

Commit

Permalink
F #1636: Add CPU_MODEL in VM Template (#2751)
Browse files Browse the repository at this point in the history
  • Loading branch information
jloboescalona2 authored Sep 22, 2023
1 parent 3008f8a commit d59f30c
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -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]
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 }
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/fireedge/src/client/constants/translates.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
16 changes: 16 additions & 0 deletions src/fireedge/src/client/models/Host.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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){
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -445,7 +485,8 @@ define(function(require) {
}

fillMachineTypesAndCPUModel(context, modelJSON, osJSON);

fillCPUFeatures(context, modelJSON)

delete templateJSON["OS"];
delete templateJSON["CPU_MODEL"];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit d59f30c

Please sign in to comment.