mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-23 22:50:09 +03:00
parent
3008f8ab69
commit
d59f30c382
@ -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]
|
@ -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 }
|
||||
|
@ -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,
|
||||
|
@ -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',
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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"];
|
||||
}
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user