1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-05 09:17:41 +03:00

F OpenNebula/one#6286: Sunstone video section (#2769)

This commit is contained in:
David 2023-10-04 10:28:28 +02:00 committed by GitHub
parent 686c434389
commit 1770041757
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 653 additions and 2 deletions

View File

@ -20,6 +20,7 @@ import { Stack } from '@mui/material'
import { FormWithSchema } from 'client/components/Forms'
import InputsSection from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/inputOutput/inputsSection'
import VideoSection from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/inputOutput/videoSection'
import { GRAPHICS_FIELDS } from 'client/components/Forms/Vm/UpdateConfigurationForm/inputOutput/schema'
import { T, HYPERVISORS } from 'client/constants'
@ -40,6 +41,7 @@ const InputOutput = ({ hypervisor }) => (
legend={T.Graphics}
/>
<InputsSection hypervisor={hypervisor} />
<VideoSection hypervisor={hypervisor} />
</Stack>
)

View File

@ -17,6 +17,8 @@ import { object, ObjectSchema } from 'yup'
import * as ioSchema from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/inputOutput/schema'
import { VIDEO_SCHEMA } from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/inputOutput/videoSchema'
import {
Field,
filterFieldsByHypervisor,
@ -55,3 +57,4 @@ export const SCHEMA = ({ hypervisor }) =>
object()
.concat(ioSchema.INPUTS_SCHEMA)
.concat(GRAPHICS_SCHEMA({ hypervisor }))
.concat(VIDEO_SCHEMA(hypervisor))

View File

@ -25,10 +25,11 @@ import {
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration'
import InputsSection, { SECTION_ID as INPUT_ID } from './inputsSection'
import PciDevicesSection, { SECTION_ID as PCI_ID } from './pciDevicesSection'
import VideoSection, { SECTION_ID as VIDEO_ID } from './videoSection'
import { GRAPHICS_FIELDS } from './schema'
import { T } from 'client/constants'
export const TAB_ID = ['GRAPHICS', INPUT_ID, PCI_ID]
export const TAB_ID = ['GRAPHICS', INPUT_ID, PCI_ID, VIDEO_ID]
const InputOutput = ({ hypervisor, oneConfig, adminGroup }) => (
<Stack
@ -54,6 +55,12 @@ const InputOutput = ({ hypervisor, oneConfig, adminGroup }) => (
oneConfig={oneConfig}
adminGroup={adminGroup}
/>
<VideoSection
stepId={EXTRA_ID}
hypervisor={hypervisor}
oneConfig={oneConfig}
adminGroup={adminGroup}
/>
</Stack>
)

View File

@ -18,6 +18,7 @@ import { object, ObjectSchema } from 'yup'
import { GRAPHICS_SCHEMA } from './graphicsSchema'
import { INPUTS_SCHEMA } from './inputsSchema'
import { PCI_DEVICES_SCHEMA } from './pciDevicesSchema'
import { VIDEO_SCHEMA } from './videoSchema'
/**
* @param {string} [hypervisor] - VM hypervisor
@ -28,7 +29,9 @@ export const SCHEMA = (hypervisor) =>
.concat(INPUTS_SCHEMA)
.concat(PCI_DEVICES_SCHEMA)
.concat(GRAPHICS_SCHEMA(hypervisor))
.concat(VIDEO_SCHEMA(hypervisor))
export * from './graphicsSchema'
export * from './inputsSchema'
export * from './pciDevicesSchema'
export * from './videoSchema'

View File

@ -0,0 +1,284 @@
/* ------------------------------------------------------------------------- *
* 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 { string, ObjectSchema, boolean, number } from 'yup'
import {
Field,
arrayToOptions,
filterFieldsByHypervisor,
getObjectSchemaFromFields,
disableFields,
} from 'client/utils'
import {
T,
INPUT_TYPES,
HYPERVISORS,
VIDEO_TYPES,
COMMON_RESOLUTIONS,
} from 'client/constants'
const { kvm, dummy } = HYPERVISORS
/**
* Schema for VIDEO section of the template. Considerations about fields behavior according to the core:
* - Only if the hypervisor it's kvm.
* - If the user select VIDEO_TYPE auto, the rest of the fields will be hidden and the request has not any VIDEO section.
* - If the user select VIDEO_TYPE none, the rest of the fields will be hidden and the request has VIDEO section but only with type=none.
* - If the user select VIDEO_TYPE cirrus, ATS, IOMMU and resolution will be hidden.
* - If the user select VIDEO_TYPE vga, ATS and IOMMU will be hidden.
* - If the user select VIDEO_TYPE virtio, all attributes will be show to the user.
* - Resolution will be one of the values of the COMMON_RESOLUTIONS or a custom resolution.
*/
/** @type {Field} Type field */
export const VIDEO_TYPE = {
name: 'VIDEO.TYPE',
type: INPUT_TYPES.SELECT,
label: T.VideoType,
tooltip: T.VideoTypeConcept,
onlyOnHypervisors: [kvm, dummy],
values: arrayToOptions(Object.values(VIDEO_TYPES), { addEmpty: false }),
validation: string()
.trim()
.default(() => VIDEO_TYPES.auto)
.afterSubmit((value, { context }) => {
// A valid hypervisor will be if the hypervisor it's kvm (when creating or updating templates) or when it's undefined (when updating the config of a vm)
const validHypervisor =
context?.general?.HYPERVISOR === kvm ||
context?.general?.HYPERVISOR === dummy ||
!context?.general?.HYPERVISOR
// Not send to the request the value if it's not a valid hypervisor
return validHypervisor && value !== VIDEO_TYPES.auto ? value : undefined
}),
grid: { sm: 3, md: 3 },
}
/** @type {Field} IOMMU field */
export const IOMMU = {
name: 'VIDEO.IOMMU',
label: T.IOMMU,
tooltip: T.IOMMUConcept,
onlyOnHypervisors: [kvm, dummy],
type: INPUT_TYPES.SWITCH,
dependOf: VIDEO_TYPE.name,
htmlType: (type) =>
(!type || type !== VIDEO_TYPES.virtio) && INPUT_TYPES.HIDDEN,
validation: boolean()
.yesOrNo(false)
.afterSubmit((value, { context }) => {
// A valid hypervisor will be if the hypervisor it's kvm (when creating or updating templates) or when it's undefined (when updating the config of a vm)
const validHypervisor =
context?.general?.HYPERVISOR === kvm ||
context?.general?.HYPERVISOR === dummy ||
!context?.general?.HYPERVISOR
// Get video type from the context on extra step (templates) or no step (vm)
const videoType = context?.extra?.VIDEO?.TYPE || context?.VIDEO?.TYPE
// Not send to the request the value if it's not a valid hypervisor
return validHypervisor && videoType === VIDEO_TYPES.virtio
? value
? 'YES'
: 'NO'
: undefined
}),
grid: { sm: 12, md: 12 },
}
/** @type {Field} ATS field */
export const ATS = {
name: 'VIDEO.ATS',
label: T.ATS,
tooltip: T.ATSConcept,
onlyOnHypervisors: [kvm, dummy],
type: INPUT_TYPES.SWITCH,
dependOf: VIDEO_TYPE.name,
htmlType: (type) =>
(!type || type !== VIDEO_TYPES.virtio) && INPUT_TYPES.HIDDEN,
validation: boolean()
.yesOrNo(false)
.afterSubmit((value, { context }) => {
// A valid hypervisor will be if the hypervisor it's kvm (when creating or updating templates) or when it's undefined (when updating the config of a vm)
const validHypervisor =
context?.general?.HYPERVISOR === kvm ||
context?.general?.HYPERVISOR === dummy ||
!context?.general?.HYPERVISOR
// Get video type from the context on extra step (templates) or no step (vm)
const videoType = context?.extra?.VIDEO?.TYPE || context?.VIDEO?.TYPE
// Not send to the request the value if it's not a valid hypervisor
return validHypervisor && videoType === VIDEO_TYPES.virtio
? value
? 'YES'
: 'NO'
: undefined
}),
grid: { sm: 12, md: 12 },
}
/** @type {Field} VRAM field */
export const VRAM = {
name: 'VIDEO.VRAM',
label: T.VRAM,
tooltip: T.VRAMConcept,
onlyOnHypervisors: [kvm, dummy],
type: INPUT_TYPES.TEXT,
dependOf: VIDEO_TYPE.name,
htmlType: (type) =>
(!type || type === VIDEO_TYPES.auto || type === VIDEO_TYPES.none) &&
INPUT_TYPES.HIDDEN,
validation: number()
.min(1024)
.afterSubmit((value, { context }) => {
// A valid hypervisor will be if the hypervisor it's kvm (when creating or updating templates) or when it's undefined (when updating the config of a vm)
const validHypervisor =
context?.general?.HYPERVISOR === kvm ||
context?.general?.HYPERVISOR === dummy ||
!context?.general?.HYPERVISOR
// Get video type from the context on extra step (templates) or no step (vm)
const videoType = context?.extra?.VIDEO?.TYPE || context?.VIDEO?.TYPE
// Not send to the request the value if it's not a valid hypervisor
return validHypervisor &&
videoType !== VIDEO_TYPES.auto &&
videoType !== VIDEO_TYPES.none
? value
: undefined
}),
grid: { sm: 3, md: 3 },
}
/** @type {Field} Resolution field */
export const RESOLUTION = {
name: 'VIDEO.RESOLUTION',
type: INPUT_TYPES.SELECT,
label: T.Resolution,
tooltip: T.ResolutionConcept,
onlyOnHypervisors: [kvm, dummy],
dependOf: VIDEO_TYPE.name,
htmlType: (type) =>
(!type ||
type === VIDEO_TYPES.auto ||
type === VIDEO_TYPES.none ||
type === VIDEO_TYPES.cirrus) &&
INPUT_TYPES.HIDDEN,
values: arrayToOptions(Object.values(COMMON_RESOLUTIONS), { addEmpty: true }),
validation: string()
.trim()
.afterSubmit((value, { context }) => {
// Video type could be on extra (when creating or updating templates) or VIDEO (when updating the config of a vm) attributes
const videoType = context?.extra?.VIDEO?.TYPE || context?.VIDEO?.TYPE
// A valid hypervisor will be if the hypervisor it's kvm (when creating or updating templates) or when it's undefined (when updating the config of a vm)
const validHypervisor =
context?.general?.HYPERVISOR === kvm ||
context?.general?.HYPERVISOR === dummy ||
!context?.general?.HYPERVISOR
// Resolution (width and height, that only is set by the user when resolution it's custom) could be on extra (when creating or updating templates) or VIDEO (when updating the config of a vm) attributes
const resolutionWidth =
context?.extra?.VIDEO?.RESOLUTION_WIDTH ||
context?.VIDEO?.RESOLUTION_WIDTH
const resolutionHeight =
context?.extra?.VIDEO?.RESOLUTION_HEIGHT ||
context?.VIDEO?.RESOLUTION_HEIGHT
// Return resolution only if the video type is not auto/none/cirrus and hypervisor is kvm (templates) or undefined (vms)
return !validHypervisor ||
videoType === VIDEO_TYPES.auto ||
videoType === VIDEO_TYPES.none ||
videoType === VIDEO_TYPES.cirrus
? undefined
: value === 'custom'
? resolutionWidth + 'x' + resolutionHeight
: value
}),
grid: { sm: 6, md: 6 },
}
/** @type {Field} RESOLUTION_WIDTH field */
export const RESOLUTION_WIDTH = {
name: 'VIDEO.RESOLUTION_WIDTH',
label: T.ResolutionWidth,
tooltip: T.ResolutionWidthConcept,
onlyOnHypervisors: [kvm, dummy],
type: INPUT_TYPES.TEXT,
dependOf: [RESOLUTION.name, VIDEO_TYPE.name],
htmlType: (type) =>
(!type ||
type[0] !== COMMON_RESOLUTIONS.custom ||
type[1] === VIDEO_TYPES.auto ||
type[1] === VIDEO_TYPES.none ||
type[1] === VIDEO_TYPES.cirrus) &&
INPUT_TYPES.HIDDEN,
validation: number()
.positive()
.afterSubmit(() => undefined),
grid: { sm: 3, md: 3 },
}
/** @type {Field} RESOLUTION_HEIGHT field */
export const RESOLUTION_HEIGHT = {
name: 'VIDEO.RESOLUTION_HEIGHT',
label: T.ResolutionHeight,
tooltip: T.ResolutionHeightConcept,
onlyOnHypervisors: [kvm, dummy],
type: INPUT_TYPES.TEXT,
dependOf: [RESOLUTION.name, VIDEO_TYPE.name],
htmlType: (type) =>
(!type ||
type[0] !== COMMON_RESOLUTIONS.custom ||
type[1] === VIDEO_TYPES.auto ||
type[1] === VIDEO_TYPES.none ||
type[1] === VIDEO_TYPES.cirrus) &&
INPUT_TYPES.HIDDEN,
validation: number()
.positive()
.afterSubmit(() => undefined),
grid: { sm: 3, md: 3 },
}
/**
* @param {string} [hypervisor] - VM hypervisor
* @param {object} oneConfig - Config of oned.conf
* @param {boolean} adminGroup - User is admin or not
* @returns {Field[]} List of Video fields
*/
export const VIDEO_FIELDS = (hypervisor, oneConfig, adminGroup) =>
disableFields(
filterFieldsByHypervisor(
[
VIDEO_TYPE,
VRAM,
RESOLUTION,
RESOLUTION_WIDTH,
RESOLUTION_HEIGHT,
IOMMU,
ATS,
],
hypervisor
),
'VIDEO',
oneConfig,
adminGroup
)
/** @type {ObjectSchema} Video schema */
export const VIDEO_SCHEMA = (hypervisor) =>
getObjectSchemaFromFields(VIDEO_FIELDS(hypervisor))

View File

@ -0,0 +1,79 @@
/* ------------------------------------------------------------------------- *
* 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 { useMemo } from 'react'
import PropTypes from 'prop-types'
import { VIDEO_FIELDS } from './schema'
import { T, COMMON_RESOLUTIONS } from 'client/constants'
import { FormWithSchema } from 'client/components/Forms'
import { useFormContext } from 'react-hook-form'
export const SECTION_ID = 'VIDEO'
/**
* Video section to set values about VIDEO attribute.
*
* @param {object} param - Properties to use in the form
* @param {string} param.stepId - Name of the step
* @param {string} param.hypervisor - Type of hypervisor
* @param {object} param.oneConfig - ONE config
* @param {boolean} param.adminGroup - If the user is admin
* @returns {object} - The component rendered
*/
const VideoSection = ({ stepId, hypervisor, oneConfig, adminGroup }) => {
// Check resolution value to get if it's a custom value or one of the common resolutions
const { getValues, setValue } = useFormContext()
// If the context has extra field, we are in template create/update that use extra.VIDEO fiel. If not, we are on update config on a vm, that uses VIDEO field
const videoField = getValues('extra') ? 'extra.VIDEO' : 'VIDEO'
const resolution = getValues(`${videoField}.RESOLUTION`)
const commonsResolutions = Object.values(COMMON_RESOLUTIONS)
// If resolution it's a custom value, set custom as resolution and set widht and height resolution
if (resolution && !commonsResolutions.includes(resolution)) {
setValue(`${videoField}.RESOLUTION`, 'custom')
const resolutionValues = resolution.split('x')
setValue(`${videoField}.RESOLUTION_WIDTH`, resolutionValues[0])
setValue(`${videoField}.RESOLUTION_HEIGHT`, resolutionValues[1])
}
// Get video fields
const fields = useMemo(
() => VIDEO_FIELDS(hypervisor, oneConfig, adminGroup),
[hypervisor]
)
// Generate a form from the schema
return (
<FormWithSchema
cy={[stepId, 'io-video'].filter(Boolean).join('.')}
fields={fields}
legend={T.Video}
rootProps={{ sx: { gridColumn: '1 / -1' } }}
id={stepId}
/>
)
}
VideoSection.propTypes = {
hypervisor: PropTypes.string,
stepId: PropTypes.string,
oneConfig: PropTypes.object,
adminGroup: PropTypes.bool,
}
VideoSection.displayName = 'VideoSection'
export default VideoSection

View File

@ -1005,6 +1005,26 @@ module.exports = {
Device: 'Device',
Vendor: 'Vendor',
Class: 'Class',
Video: 'Video',
VideoType: 'Video device type',
VideoTypeConcept:
'Select the driver for the virtual video device, auto will be generated by OpenNebula.',
IOMMU: 'Enable IOMMU',
IOMMUConcept:
'Enable the use of emulated Input/Output Memory Management Unit by the device',
ATS: 'Enable ATS',
ATSConcept: 'Enable Address Translation Service support',
VRAM: 'VRAM (KB)',
VRAMConcept:
'Define the amount of VRAM to assign to the video device in KB. Must be greater than or equal to 1024',
Resolution: 'Resolution',
ResolutionConcept: 'Set the default resolution for the video device',
ResolutionWidth: 'Resolution width',
ResolutionWidthConcept:
'Set the default width resolution for the video device',
ResolutionHeight: 'Resolution height',
ResolutionHeightConcept:
'Set the default heigth resolution for the video device',
/* VM Template schema - Input/Output - graphics */
Graphics: 'Graphics',
ListenOnIp: 'Listen on IP',

View File

@ -81,6 +81,21 @@ export const SD_DISK_BUSES = ['scsi', 'sata']
export const DEVICE_TYPES = { mouse: 'mouse', tablet: 'tablet' }
export const DEVICE_BUS_TYPES = { usb: 'usb', ps2: 'ps2' }
export const VIDEO_TYPES = {
auto: 'auto',
none: 'none',
vga: 'vga',
cirrus: 'cirrus',
virtio: 'virtio',
}
export const COMMON_RESOLUTIONS = {
'1920x1080': '1920x1080',
'1366x768': '1366x768',
'1536x864': '1536x864',
'1440x900': '1440x900',
'1280x720': '1280x720',
custom: 'custom',
}
export const FIRMWARE_TYPES = ['BIOS']

View File

@ -74,6 +74,7 @@ define(function(require) {
function _setup(context) {
$("input[name='graphics_type']", context).change(function() {
if ($(this).attr("value") !== '') {
if($('input[wizard_field="LISTEN"]', context).val() == ""){
$('input[wizard_field="LISTEN"]', context).val("0.0.0.0");
@ -125,11 +126,96 @@ define(function(require) {
});
CreateUtils.setupPCIRows($(".pci_devices", context));
// Hide video section if the hypervisor it's kvm (Done here because there is a bug if we used the css classes)
$("input[name='hypervisor']").change(function() {
if (this.value === "kvm") {
$(".video").show()
}
else {
$(".video").hide()
}
})
// Event on change video type attribute
$("input[name='video_type']", context).change(function() {
/**
* - Only if the hypervisor it's kvm.
* - If the user select VIDEO_TYPE auto, the rest of the fields will be hidden and the request has not any VIDEO section.
* - If the user select VIDEO_TYPE none, the rest of the fields will be hidden and the request has VIDEO section but only with type=none.
* - If the user select VIDEO_TYPE cirrus, ATS, IOMMU and resolution will be hidden.
* - If the user select VIDEO_TYPE vga, ATS and IOMMU will be hidden.
* - If the user select VIDEO_TYPE virtio, all attributes will be show to the user.
* - Resolution will be one of the values of the COMMON_RESOLUTIONS or a custom resolution.
*/
if ($(this).attr("value") === 'auto' || $(this).attr("value") === 'none') {
$('.video-settings', context).css('display', 'none');
}
else if ($(this).attr("value") === 'cirrus') {
$('.video-settings', context).css('display', '');
$('.video-settings-iommu', context).css('display', 'none');
$('.video-settings-iommu-label', context).css('display', 'none');
$('.video-settings-ats', context).css('display', 'none');
$('.video-settings-ats-label', context).css('display', 'none');
$('.video-settings-vram', context).css('display', '');
$('.video-settings-resolution', context).css('display', 'none');
$('.video-settings-resolution-label', context).css('display', 'none');
$('.video-settings-resolution-width', context).css('display', 'none');
$('.video-settings-resolution-height', context).css('display', 'none');
}
else if ($(this).attr("value") === 'vga') {
$('.video-settings', context).css('display', '');
$('.video-settings-iommu', context).css('display', 'none');
$('.video-settings-iommu-label', context).css('display', 'none');
$('.video-settings-ats', context).css('display', 'none');
$('.video-settings-ats-label', context).css('display', 'none');
$('.video-settings-vram', context).css('display', '');
$('.video-settings-resolution', context).css('display', '');
$('.video-settings-resolution-label', context).css('display', '');
$('.video-settings-resolution-width', context).css('display', '');
$('.video-settings-resolution-height', context).css('display', '');
$("select[name='resolution']", context).change()
}
else if ($(this).attr("value") === 'virtio') {
$('.video-settings', context).css('display', '');
$('.video-settings-iommu', context).css('display', '');
$('.video-settings-iommu-label', context).css('display', '');
$('.video-settings-ats', context).css('display', '');
$('.video-settings-ats-label', context).css('display', '');
$('.video-settings-vram', context).css('display', '');
$('.video-settings-resolution', context).css('display', '');
$('.video-settings-resolution-label', context).css('display', '');
$('.video-settings-resolution-width', context).css('display', '');
$('.video-settings-resolution-height', context).css('display', '');
$("select[name='resolution']", context).change()
}
});
// Manage custom resolution
$("select[name='resolution']", context).change(function() {
if ($(this).val() === "custom") {
$('.video-settings-resolution-width', context).css('display', '');
$('.video-settings-resolution-height', context).css('display', '');
}
else {
$('.video-settings-resolution-width', context).css('display', 'none');
$('.video-settings-resolution-height', context).css('display', 'none');
}
})
}
function _retrieve(context) {
var templateJSON = {};
var graphicsJSON = WizardFields.retrieve(context);
var graphicsJSON = WizardFields.retrieve(context.find("div.graphics"));
if (!$.isEmptyObject(graphicsJSON) && $(".RANDOM_PASSWD:checked", context).length > 0) {
graphicsJSON["RANDOM_PASSWD"] = "YES";
@ -161,6 +247,43 @@ define(function(require) {
}
});
// Add video section to the request
// - If video type is auto, don't send any video section
// - If video type is none, send only video type
// - Checkbox attributes will be YES/NO
var videoJSON = WizardFields.retrieve(context.find("div.video"));
videoJSON.TYPE = videoJSON.VIDEO_TYPE
delete videoJSON.VIDEO_TYPE
if (videoJSON.TYPE === "auto") {
videoJSON = {}
}
if (videoJSON.TYPE === "none") {
videoJSON = {
"TYPE": "none"
}
}
if (!$.isEmptyObject(videoJSON) && $(".video-settings-iommu:checked", context).length > 0) {
videoJSON["IOMMU"] = "YES";
}
if (!$.isEmptyObject(videoJSON) && $(".video-settings-ats:checked", context).length > 0) {
videoJSON["ATS"] = "YES";
}
if (!$.isEmptyObject(videoJSON) && videoJSON.RESOLUTION == "custom") {
videoJSON.RESOLUTION = videoJSON.RESOLUTION_WIDTH + "x" + videoJSON.RESOLUTION_HEIGHT
}
delete videoJSON.RESOLUTION_WIDTH
delete videoJSON.RESOLUTION_HEIGHT
if (!$.isEmptyObject(videoJSON)) { templateJSON['VIDEO'] = videoJSON; };
return templateJSON;
}
@ -236,5 +359,49 @@ define(function(require) {
});
delete templateJSON.PCI;
// Video section
var videoJSON = templateJSON['VIDEO'];
if (videoJSON) {
var type = videoJSON.TYPE;
if (type) {
$(".video input[wizard_field='VIDEO_TYPE'][value='" + type + "']", context).click();
} else {
$(".video input[wizard_field='VIDEO_TYPE'][value='']", context).click();
}
videoJSON.VIDEO_TYPE = type
delete videoJSON.TYPE
if (videoJSON["IOMMU"] == "YES") {
$(".video-settings-iommu", context).attr("checked", "checked");
delete videoJSON["IOMMU"]
}
if (videoJSON["ATS"] == "YES") {
$(".video-settings-ats", context).attr("checked", "checked");
delete videoJSON["ATS"]
}
// Manage resolution if it's a custom value
let resolutions = $("select[name='resolution'] option").map(function() { return this.value; }).get();
let resolution = videoJSON.RESOLUTION
if (resolutions && resolution && (resolution!== "") && !resolutions.includes(resolution)) {
let storeResolutions = resolution.split("x")
videoJSON.RESOLUTION_WIDTH = storeResolutions[0]
videoJSON.RESOLUTION_HEIGHT = storeResolutions[1]
videoJSON.RESOLUTION = "custom"
}
WizardFields.fill(context, videoJSON);
delete templateJSON['VIDEO']
} else {
$(".video input[wizard_field='TYPE'][value='']", context).click();
}
}
});

View File

@ -160,4 +160,75 @@
</div>
</fieldset>
</div>
<div class="medium-12 columns video hypervisor">
<fieldset>
<legend>
{{tr "Video"}}
{{{tip (tr "Select the driver for the virtual video device, auto will be generated by OpenNebula.")}}}
</legend>
<div class="">
<div class="large-12 columns text-left">
<input type="radio" wizard_field="VIDEO_TYPE" name="video_type" ID="radioAutoType{{uniqueId}}" value="auto" checked><label for="radioAutoType{{uniqueId}}">{{tr "Auto"}}</label>
<input type="radio" wizard_field="VIDEO_TYPE" name="video_type" ID="radioNoneType{{uniqueId}}" value="none"><label for="radioNoneType{{uniqueId}}">{{tr "None"}}</label>
<input type="radio" wizard_field="VIDEO_TYPE" name="video_type" ID="radioVgaType{{uniqueId}}" value="vga"><label for="radioVgaType{{uniqueId}}">{{tr "Vga"}}</label>
<input type="radio" wizard_field="VIDEO_TYPE" name="video_type" ID="radioCirrusType{{uniqueId}}" value="cirrus"><label for="radioCirrusType{{uniqueId}}">{{tr "Cirrus"}}</label>
<input type="radio" wizard_field="VIDEO_TYPE" name="video_type" ID="radioVirtioType{{uniqueId}}" value="virtio"><label for="radioVirtioType{{uniqueId}}">{{tr "Virtio"}}</label>
</div>
</div>
<div class="video-settings" style="display: none">
<div class="large-12 columns text-left">
<div class="large-3 columns text-left">
<label class="video-settings-vram">
{{tr "VRAM (KB)"}}
{{{tip (tr "Define the amount of VRAM to assign to the video device in KB. Must be >= 1024")}}}
<input type="text" wizard_field="VRAM"/>
</label>
</div>
<div class="large-3 columns text-left">
<label class="video-settings-resolution-label">
{{tr "Resolution"}}
{{{tip (tr "Set the default resolution for the video device")}}}
<select id="RESOLUTION" name="resolution" class="video-settings-resolution" wizard_field="RESOLUTION">
<option value=""></option>
<option value="1920x1080">{{tr "1920x1080"}}</option>
<option value="1366x768">{{tr "1366x768"}}</option>
<option value="1536x864">{{tr "1536x864"}}</option>
<option value="1440x900">{{tr "1440x900"}}</option>
<option value="1280x720">{{tr "1280x720"}}</option>
<option value="custom">{{tr "custom"}}</option>
</select>
</label>
</div>
<div class="large-3 columns text-left">
<label class="video-settings-resolution-width" style="display: none">
{{tr "Resolution width"}}
{{{tip (tr "Set the default width resolution for the video device")}}}
<input type="text" wizard_field="RESOLUTION_WIDTH"/>
</label>
</div>
<div class="large-3 columns text-left">
<label class="video-settings-resolution-height" style="display: none">
{{tr "Resolution height"}}
{{{tip (tr "Set the default height resolution for the video device")}}}
<input type="text" wizard_field="RESOLUTION_HEIGHT"/>
</label>
</div>
</div>
<div class="large-12 columns text-left">
<div class="large-12 columns text-left">
<input type="checkbox" class="video-settings-iommu" id="IOMMU{{uniqueId}}" wizard_field="IOMMU"><label class="video-settings-iommu-label" for="IOMMU{{uniqueId}}">
{{tr "IOMMU"}}
{{{tip (tr "Enable the use of emulated Input/Output Memory Management Unit by the device")}}}
</label>
</div>
<div class="large-12 columns text-left">
<input type="checkbox" class="video-settings-ats" id="ATS{{uniqueId}}" wizard_field="ATS"><label class="video-settings-ats-label" for="ATS{{uniqueId}}">
{{tr "ATS"}}
{{{tip (tr "Enable Address Translation Service support")}}}
</label>
</div>
</div>
</div>
</fieldset>
</div>
</div>