diff --git a/src/components/CreateVmWizard/CreateVmWizard.js b/src/components/CreateVmWizard/CreateVmWizard.js index 62ccd415a..767e1bba3 100644 --- a/src/components/CreateVmWizard/CreateVmWizard.js +++ b/src/components/CreateVmWizard/CreateVmWizard.js @@ -40,6 +40,7 @@ const DEFAULT_STATE = { threads: 1, }, tpmEnabled: undefined, + biosType: undefined, }, network: { nics: [], diff --git a/src/components/CreateVmWizard/dataPropTypes.js b/src/components/CreateVmWizard/dataPropTypes.js index ccf731d72..c63387403 100644 --- a/src/components/CreateVmWizard/dataPropTypes.js +++ b/src/components/CreateVmWizard/dataPropTypes.js @@ -13,6 +13,7 @@ export const BASIC_DATA_SHAPE = { operatingSystemId: PropTypes.string, tpmEnabled: PropTypes.bool, + biosType: PropTypes.string, memory: PropTypes.number, // in MiB cpus: PropTypes.number, optimizedFor: PropTypes.oneOf(['desktop', 'server', 'high_performance']), diff --git a/src/components/CreateVmWizard/helpers.js b/src/components/CreateVmWizard/helpers.js index b3b74d094..917470fdc 100644 --- a/src/components/CreateVmWizard/helpers.js +++ b/src/components/CreateVmWizard/helpers.js @@ -6,6 +6,7 @@ import { getDefaultOSByArchitecture, isWindows, isTpmRequired, + forceUefiBios, } from '_/helpers' const handleClusterIdChange = (clusterId, { blankTemplateId, defaultValues, clusters, templates, operatingSystems, storageDomains, defaultGeneralTimezone, defaultWindowsTimezone, locale }) => { @@ -74,6 +75,7 @@ const handleProvisionSourceChange = (provisionSource, { defaultValues, defaultGe changes.templateId = undefined changes.operatingSystemId = verifyOsIdToCluster(defaultValues.operatingSystemId, clusterId, { clusters, operatingSystems }) changes.tpmEnabled = isTpmRequired(changes.operatingSystemId, operatingSystems) || undefined + changes.biosType = forceUefiBios({ operatingSystemId: changes.operatingSystemId, operatingSystems, clusterId, clusters }) changes.memory = defaultValues.memory changes.cpus = defaultValues.cpus changes.topology = defaultValues.topology @@ -102,6 +104,7 @@ const handleTemplateIdChange = (templateId, defaultOptimizedFor, { templates, op .get('id') changes.operatingSystemId = verifyOsIdToCluster(suggestedOs, clusterId, { clusters, operatingSystems }) changes.tpmEnabled = isTpmRequired(changes.operatingSystemId, operatingSystems) || undefined + changes.biosType = forceUefiBios({ operatingSystemId: changes.operatingSystemId, operatingSystems, clusterId, clusters }) // Check template's timezone compatibility with the template's OS, set the timezone corresponding to the template's OS changes.timeZone = checkTimeZone(changes.operatingSystemId, changes.templateId, { defaultGeneralTimezone, defaultWindowsTimezone, templates, operatingSystems }) changes.cloudInitEnabled = template.getIn(['cloudInit', 'enabled']) diff --git a/src/components/CreateVmWizard/steps/BasicSettings.js b/src/components/CreateVmWizard/steps/BasicSettings.js index edb510a37..0f0226ed7 100644 --- a/src/components/CreateVmWizard/steps/BasicSettings.js +++ b/src/components/CreateVmWizard/steps/BasicSettings.js @@ -1,7 +1,7 @@ import React from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' -import { localeCompare, isTpmRequired } from '_/helpers' +import { localeCompare, isTpmRequired, forceUefiBios } from '_/helpers' import { withMsg } from '_/intl' import { isNumberInRange } from '_/utils' import { BASIC_DATA_SHAPE } from '../dataPropTypes' @@ -316,13 +316,14 @@ class BasicSettings extends React.Component { case 'operatingSystemId': { changes[field] = value - const { data: { templateId } } = this.props + const { data: { templateId }, operatingSystems, clusters, data } = this.props changes.timeZone = checkTimeZone(value, templateId, this.props) // only when changing the OS from one Windows to other Windows changes.initTimezone = this.props.data.cloudInitEnabled && this.props.data.enableInitTimezone && isOsWindows(value, this.props.operatingSystems) ? this.props.data.lastInitTimezone // set the sysprep timezone as the last selected sysprep timezone : '' changes.tpmEnabled = isTpmRequired(value, this.props.operatingSystems) || undefined + changes.biosType = forceUefiBios({ operatingSystemId: value, operatingSystems, clusterId: data.clusterId, clusters }) break } diff --git a/src/components/VmDetails/cards/DetailsCard/index.js b/src/components/VmDetails/cards/DetailsCard/index.js index 3d9282d3f..a43a4459e 100644 --- a/src/components/VmDetails/cards/DetailsCard/index.js +++ b/src/components/VmDetails/cards/DetailsCard/index.js @@ -15,6 +15,9 @@ import { userFormatOfBytes, buildMessageFromRecord, getTpmChange, + isUefiBios, + isTpmRequired, + UEFI_BIOS, } from '_/helpers' import { enumMsg, MsgContext, withMsg } from '_/intl' import { isNumber, isNumberInRange } from '_/utils' @@ -279,6 +282,7 @@ class DetailsCard extends React.Component { operatingSystems, clusters, templates, + vm, } = this.props for (let change = changeQueue.shift(); change; change = changeQueue.shift()) { @@ -389,6 +393,10 @@ class DetailsCard extends React.Component { const tpmChange = getTpmChange(os.get('id'), operatingSystems) updates = updates.set('tpmEnabled', tpmChange) this.tpmUpdate = true + updates = updates.set( + 'biosType', + isTpmRequired(value, operatingSystems) && !isUefiBios(vm.get('biosType')) ? UEFI_BIOS : undefined + ) const timeZoneName = updates.getIn(['timeZone', 'name']) const isWindowsTimeZone = timezones.find(timezone => timezone.id === timeZoneName) const isWindowsVm = isWindows(os.get('name')) @@ -605,6 +613,7 @@ class DetailsCard extends React.Component { if (tpmEnabled !== stateVm.get('tpmEnabled')) { vmUpdates.tpmEnabled = stateVm.get('tpmEnabled') } + vmUpdates.biosType = stateVm.get('biosType') } if (this.trackUpdates.memory) { diff --git a/src/helpers.js b/src/helpers.js index 254a9b509..bcf46c5e4 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -339,3 +339,8 @@ export const getTpmChange = (operatingSystemId, operatingSystems) => { return undefined } } + +export const UEFI_BIOS = 'q35_ovmf' +export const isUefiBios = (biosType) => biosType === UEFI_BIOS || biosType === 'q35_secure_boot' +export const forceUefiBios = ({ operatingSystemId, operatingSystems, clusters, clusterId }) => + isTpmRequired(operatingSystemId, operatingSystems) && !isUefiBios(clusters?.getIn([clusterId, 'biosType'])) ? UEFI_BIOS : undefined diff --git a/src/ovirtapi/transform.js b/src/ovirtapi/transform.js index 1f0178fb6..50810194d 100644 --- a/src/ovirtapi/transform.js +++ b/src/ovirtapi/transform.js @@ -138,6 +138,7 @@ const VM = { creationTime: convertEpoch(vm.creation_time), startPaused: convertBool(vm.start_paused), tpmEnabled: vm.tpm_enabled !== undefined ? convertBool(vm.tpm_enabled) : undefined, + biosType: vm?.bios?.type ?? undefined, stateless: vm.stateless === 'true', @@ -320,9 +321,10 @@ const VM = { utc_offset: vm.timeZone.offset, }, - bios: 'bootMenuEnabled' in vm - ? { boot_menu: { enabled: toApiBoolean(vm.bootMenuEnabled) } } - : undefined, + bios: { + boot_menu: 'bootMenuEnabled' in vm ? { enabled: toApiBoolean(vm.bootMenuEnabled) } : undefined, + type: vm.biosType ?? undefined, + }, // NOTE: Disable cloudInit by sending "initialization: {}" initialization: vm.cloudInit && ( @@ -840,6 +842,7 @@ const Cluster = { const c: Object = { id: cluster.id, + biosType: cluster.bios_type, name: cluster.name, version: `${cluster.version.major}.${cluster.version.minor}`, dataCenterId: cluster.data_center && cluster.data_center.id, diff --git a/src/sagas/vmChanges.js b/src/sagas/vmChanges.js index e967d1913..c42fa6514 100644 --- a/src/sagas/vmChanges.js +++ b/src/sagas/vmChanges.js @@ -50,6 +50,7 @@ function* composeAndCreateVm ({ payload: { basic, nics, disks }, meta: { correla utc_offset: basic.timeZone.offset, }, tpm_enabled: basic.tpmEnabled, + bios: basic.biosType ? { type: basic.biosType } : undefined, initialization: basic.cloudInitEnabled ? {