mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-21 14:50:08 +03:00
(cherry picked from commit de2f61a84c04629499bacf28f5678fbf3a19528d)
This commit is contained in:
parent
d071573da9
commit
dbbfd85a40
@ -32,6 +32,7 @@ import SubmitButton, {
|
||||
} from 'client/components/FormControl/SubmitButton'
|
||||
import FormStepper from 'client/components/FormStepper'
|
||||
import { Translate } from 'client/components/HOC'
|
||||
import { isDevelopment } from 'client/utils'
|
||||
|
||||
const ButtonToTriggerForm = ({ buttonProps = {}, options = [] }) => {
|
||||
const buttonId = buttonProps['data-cy'] ?? 'main-button'
|
||||
@ -59,6 +60,8 @@ const ButtonToTriggerForm = ({ buttonProps = {}, options = [] }) => {
|
||||
try {
|
||||
const data = transformBeforeSubmit?.(formData) ?? formData
|
||||
await handleSubmit?.(data)
|
||||
} catch (error) {
|
||||
isDevelopment() && console.error(error)
|
||||
} finally {
|
||||
hide()
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import { T, INPUT_TYPES, HYPERVISORS } from 'client/constants'
|
||||
import {
|
||||
Field,
|
||||
Section,
|
||||
getValidationFromFields,
|
||||
getObjectSchemaFromFields,
|
||||
filterFieldsByHypervisor,
|
||||
} from 'client/utils'
|
||||
|
||||
@ -90,6 +90,6 @@ const FIELDS = (hypervisor) =>
|
||||
* @param {HYPERVISORS} hypervisor - Hypervisor
|
||||
* @returns {ObjectSchema} Advanced options schema
|
||||
*/
|
||||
const SCHEMA = (hypervisor) => getValidationFromFields(FIELDS(hypervisor))
|
||||
const SCHEMA = (hypervisor) => getObjectSchemaFromFields(FIELDS(hypervisor))
|
||||
|
||||
export { SECTIONS, FIELDS, SCHEMA }
|
||||
|
@ -15,6 +15,7 @@
|
||||
* ------------------------------------------------------------------------- */
|
||||
import PropTypes from 'prop-types'
|
||||
import { ElectronicsChip as NumaIcon } from 'iconoir-react'
|
||||
import { useWatch } from 'react-hook-form'
|
||||
|
||||
import FormWithSchema from 'client/components/Forms/FormWithSchema'
|
||||
import { STEP_ID as GENERAL_ID } from 'client/components/Forms/VmTemplate/CreateForm/Steps/General'
|
||||
@ -23,25 +24,39 @@ import {
|
||||
TabType,
|
||||
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration'
|
||||
import { VIRTUAL_CPU as VCPU_FIELD } from 'client/components/Forms/VmTemplate/CreateForm/Steps/General/capacitySchema'
|
||||
import { FIELDS as NUMA_FIELDS } from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/numa/schema'
|
||||
import {
|
||||
NUMA_FIELDS,
|
||||
ENABLE_NUMA,
|
||||
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/numa/schema'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
export const TAB_ID = 'NUMA'
|
||||
|
||||
const Numa = ({ hypervisor }) => (
|
||||
<>
|
||||
<FormWithSchema
|
||||
cy={`${EXTRA_ID}-vcpu`}
|
||||
fields={[VCPU_FIELD]}
|
||||
id={GENERAL_ID}
|
||||
/>
|
||||
<FormWithSchema
|
||||
cy={`${EXTRA_ID}-numa`}
|
||||
fields={NUMA_FIELDS(hypervisor)}
|
||||
id={EXTRA_ID}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
const Numa = ({ hypervisor }) => {
|
||||
const enableNuma = useWatch({ name: `${EXTRA_ID}.${ENABLE_NUMA.name}` })
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormWithSchema
|
||||
cy={`${EXTRA_ID}-vcpu`}
|
||||
fields={[VCPU_FIELD]}
|
||||
id={GENERAL_ID}
|
||||
/>
|
||||
<FormWithSchema
|
||||
cy={`${EXTRA_ID}-numa-enable`}
|
||||
fields={[ENABLE_NUMA]}
|
||||
id={EXTRA_ID}
|
||||
/>
|
||||
{enableNuma && (
|
||||
<FormWithSchema
|
||||
cy={`${EXTRA_ID}-numa`}
|
||||
fields={NUMA_FIELDS(hypervisor)}
|
||||
id={EXTRA_ID}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Numa.propTypes = {
|
||||
data: PropTypes.any,
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { string, number } from 'yup'
|
||||
import { string, number, boolean, lazy } from 'yup'
|
||||
|
||||
import { useGetHostsQuery } from 'client/features/OneApi/host'
|
||||
import { getHugepageSizes } from 'client/models/Host'
|
||||
@ -37,6 +37,17 @@ const { vcenter, firecracker } = HYPERVISORS
|
||||
|
||||
const threadsValidation = number().nullable().notRequired().integer()
|
||||
|
||||
const ENABLE_NUMA = {
|
||||
name: 'TOPOLOGY.ENABLE_NUMA',
|
||||
label: T.NumaTopology,
|
||||
type: INPUT_TYPES.CHECKBOX,
|
||||
tooltip: T.NumaTopologyConcept,
|
||||
validation: lazy((_, { context }) =>
|
||||
boolean().default(() => !!context?.extra?.TOPOLOGY)
|
||||
),
|
||||
grid: { md: 12 },
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HYPERVISORS} hypervisor - VM hypervisor
|
||||
* @returns {Field} Pin policy field
|
||||
@ -61,7 +72,7 @@ const PIN_POLICY = (hypervisor) => {
|
||||
() =>
|
||||
isFirecracker
|
||||
? NUMA_PIN_POLICIES[2] // SHARED
|
||||
: NUMA_PIN_POLICIES[0] // NONE
|
||||
: undefined // NONE
|
||||
),
|
||||
fieldProps: { disabled: isVCenter || isFirecracker },
|
||||
}
|
||||
@ -98,7 +109,7 @@ const SOCKETS = (hypervisor) => ({
|
||||
validation: number()
|
||||
.notRequired()
|
||||
.integer()
|
||||
.default(() => 1),
|
||||
.default(() => undefined),
|
||||
fieldProps: {
|
||||
disabled: hypervisor === firecracker,
|
||||
},
|
||||
@ -177,10 +188,16 @@ const MEMORY_ACCESS = {
|
||||
* @param {string} [hypervisor] - VM hypervisor
|
||||
* @returns {Field[]} List of NUMA fields
|
||||
*/
|
||||
const FIELDS = (hypervisor) =>
|
||||
const NUMA_FIELDS = (hypervisor) =>
|
||||
filterFieldsByHypervisor(
|
||||
[PIN_POLICY, CORES, SOCKETS, THREADS, HUGEPAGES, MEMORY_ACCESS],
|
||||
hypervisor
|
||||
)
|
||||
|
||||
export { FIELDS }
|
||||
/**
|
||||
* @param {string} [hypervisor] - VM hypervisor
|
||||
* @returns {Field[]} List of NUMA fields
|
||||
*/
|
||||
const SCHEMA_FIELDS = (hypervisor) => [ENABLE_NUMA, ...NUMA_FIELDS(hypervisor)]
|
||||
|
||||
export { NUMA_FIELDS, SCHEMA_FIELDS as FIELDS, ENABLE_NUMA }
|
||||
|
@ -60,6 +60,7 @@ const Steps = createSteps([General, ExtraConfiguration, CustomVariables], {
|
||||
[CUSTOM_ID]: customVariables = {},
|
||||
[EXTRA_ID]: {
|
||||
CONTEXT: { START_SCRIPT, ENCODE_START_SCRIPT, ...restOfContext },
|
||||
TOPOLOGY: { ENABLE_NUMA, ...restOfTopology },
|
||||
...extraTemplate
|
||||
} = {},
|
||||
} = formData ?? {}
|
||||
@ -72,6 +73,7 @@ const Steps = createSteps([General, ExtraConfiguration, CustomVariables], {
|
||||
? btoa(unescape(encodeURIComponent(START_SCRIPT)))
|
||||
: START_SCRIPT,
|
||||
}
|
||||
const topology = ENABLE_NUMA ? { TOPOLOGY: restOfTopology } : {}
|
||||
|
||||
// add user inputs to context
|
||||
Object.keys(extraTemplate?.USER_INPUTS ?? {}).forEach((name) => {
|
||||
@ -83,6 +85,7 @@ const Steps = createSteps([General, ExtraConfiguration, CustomVariables], {
|
||||
...customVariables,
|
||||
...extraTemplate,
|
||||
...general,
|
||||
...topology,
|
||||
CONTEXT: context,
|
||||
})
|
||||
},
|
||||
|
@ -47,11 +47,20 @@ const Steps = createSteps(
|
||||
const {
|
||||
[TEMPLATE_ID]: [templateSelected] = [],
|
||||
[BASIC_ID]: { name, instances, hold, persistent, ...restOfConfig } = {},
|
||||
[EXTRA_ID]: extraTemplate = {},
|
||||
[EXTRA_ID]: {
|
||||
TOPOLOGY: { ENABLE_NUMA, ...restOfTopology },
|
||||
...extraTemplate
|
||||
} = {},
|
||||
} = formData ?? {}
|
||||
|
||||
const topology = ENABLE_NUMA ? { TOPOLOGY: restOfTopology } : {}
|
||||
|
||||
// merge with template disks to get TYPE attribute
|
||||
const templateXML = jsonToXml({ ...extraTemplate, ...restOfConfig })
|
||||
const templateXML = jsonToXml({
|
||||
...extraTemplate,
|
||||
...topology,
|
||||
...restOfConfig,
|
||||
})
|
||||
const data = { instances, hold, persistent, template: templateXML }
|
||||
|
||||
const templates = [...new Array(instances)].map((_, idx) => ({
|
||||
|
@ -76,7 +76,10 @@ const Actions = () => {
|
||||
icon: CloudDownload,
|
||||
options: [
|
||||
{
|
||||
dialogProps: { title: T.DownloadAppToOpenNebula },
|
||||
dialogProps: {
|
||||
title: T.DownloadAppToOpenNebula,
|
||||
dataCy: 'modal-export',
|
||||
},
|
||||
form: (rows) => {
|
||||
const app = rows?.map(({ original }) => original)[0]
|
||||
|
||||
|
@ -48,7 +48,7 @@ const Row = ({ original, value, ...props }) => {
|
||||
const timeAgo = `registered ${time.toRelative()}`
|
||||
|
||||
return (
|
||||
<div {...props}>
|
||||
<div {...props} data-cy={`app-${ID}`}>
|
||||
<div>
|
||||
<StatusCircle color={stateColor} tooltip={stateName} />
|
||||
</div>
|
||||
|
@ -580,6 +580,9 @@ module.exports = {
|
||||
Command: 'Command',
|
||||
Bus: 'BUS',
|
||||
/* VM Template schema - NUMA */
|
||||
NumaTopology: 'NUMA Topology',
|
||||
NumaTopologyConcept:
|
||||
'These settings will help you to fine tune the performance of VMs',
|
||||
PinPolicy: 'Pin Policy',
|
||||
PinPolicyConcept: 'Virtual CPU pinning preference: %s',
|
||||
NumaSocketsConcept: 'Number of sockets or NUMA nodes',
|
||||
|
@ -347,7 +347,7 @@ const marketAppApi = oneApi.injectEndpoints({
|
||||
* @returns {number} Marketplace app id
|
||||
* @throws Fails when response isn't code 200
|
||||
*/
|
||||
query: async (params) => {
|
||||
query: (params) => {
|
||||
const name = ExtraActions.MARKETAPP_EXPORT
|
||||
const command = { name, ...ExtraCommands[name] }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user