feat(xo-server/xo-web/VM/new): VTPM creation (#7077)
See #7066 See #6802 See #7085
This commit is contained in:
parent
1a1dd0531d
commit
8834af65f7
@ -11,6 +11,7 @@
|
||||
- [Plugin/backup-report] Errors are now listed in XO tasks
|
||||
- [PIF] Show network name in PIF selectors (PR [#7081](https://github.com/vatesfr/xen-orchestra/pull/7081))
|
||||
- [VM/Advanced] Possibility to create/delete VTPM [#7066](https://github.com/vatesfr/xen-orchestra/issues/7066) [Forum#6578](https://xcp-ng.org/forum/topic/6578/xcp-ng-8-3-public-alpha/109) (PR [#7085](https://github.com/vatesfr/xen-orchestra/pull/7085))
|
||||
- [VM/New] Possibility to create and attach a _VTPM_ to a VM [#7066](https://github.com/vatesfr/xen-orchestra/issues/7066) [Forum#6578](https://xcp-ng.org/forum/topic/6578/xcp-ng-8-3-public-alpha/109) (PR [#7077](https://github.com/vatesfr/xen-orchestra/pull/7077))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
@ -238,6 +238,11 @@ export const create = defer(async function ($defer, params) {
|
||||
await this.allocIpAddresses(vif.$id, concat(vif.ipv4_allowed, vif.ipv6_allowed)).catch(() => xapi.deleteVif(vif))
|
||||
}
|
||||
|
||||
if (params.createVtpm) {
|
||||
const vtpmRef = await xapi.VTPM_create({ VM: xapiVm.$ref })
|
||||
$defer.onFailure(() => xapi.call('VTPM.destroy', vtpmRef))
|
||||
}
|
||||
|
||||
if (params.bootAfterCreate) {
|
||||
startVmAndDestroyCloudConfigVdi(xapi, xapiVm, cloudConfigVdiUuid, params)
|
||||
}
|
||||
@ -258,6 +263,11 @@ create.params = {
|
||||
optional: true,
|
||||
},
|
||||
|
||||
createVtpm: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
|
||||
networkConfig: {
|
||||
type: 'string',
|
||||
optional: true,
|
||||
|
@ -1582,6 +1582,7 @@ const messages = {
|
||||
createVmModalWarningMessage:
|
||||
"You're about to use a large amount of resources available on the resource set. Are you sure you want to continue?",
|
||||
copyHostBiosStrings: 'Copy host BIOS strings to VM',
|
||||
enableVtpm: 'Enable VTPM',
|
||||
newVmCreateNewVmOn: 'Create a new VM on {select}',
|
||||
newVmCreateNewVmNoPermission: 'You have no permission to create a VM',
|
||||
newVmInfoPanel: 'Info',
|
||||
@ -1655,6 +1656,7 @@ const messages = {
|
||||
vmBootFirmwareIsUefi: 'The boot firmware is UEFI',
|
||||
destroyCloudConfigVdiAfterBoot: 'Destroy cloud config drive after first boot',
|
||||
vtpmNotSupported: 'VTPM is only supported on pools running XCP-ng/XS 8.3 or later.',
|
||||
warningVtpmRequired: 'This template requires a VTPM, if you proceed, the VM will likely not be able to boot.',
|
||||
|
||||
// ----- Self -----
|
||||
resourceSets: 'Resource sets',
|
||||
|
@ -100,6 +100,14 @@ $select-input-height: 40px; // Bootstrap input height
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.d-inline-flex {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.align-self-center {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
// COLORS ======================================================================
|
||||
|
||||
.xo-status-running {
|
||||
|
@ -346,6 +346,7 @@ export default class NewVm extends BaseComponent {
|
||||
seqStart: 1,
|
||||
share: this._getResourceSet()?.shareByDefault ?? false,
|
||||
tags: [],
|
||||
createVtpm: this._templateNeedsVtpm(),
|
||||
},
|
||||
callback
|
||||
)
|
||||
@ -493,6 +494,7 @@ export default class NewVm extends BaseComponent {
|
||||
bootAfterCreate: state.bootAfterCreate,
|
||||
copyHostBiosStrings:
|
||||
state.hvmBootFirmware !== 'uefi' && !this._templateHasBiosStrings() && state.copyHostBiosStrings,
|
||||
createVtpm: state.createVtpm,
|
||||
destroyCloudConfigVdiAfterBoot: state.destroyCloudConfigVdiAfterBoot,
|
||||
secureBoot: state.secureBoot,
|
||||
share: state.share,
|
||||
@ -599,6 +601,7 @@ export default class NewVm extends BaseComponent {
|
||||
}),
|
||||
// settings
|
||||
secureBoot: template.secureBoot,
|
||||
createVtpm: this._templateNeedsVtpm(),
|
||||
})
|
||||
|
||||
if (this._isCoreOs()) {
|
||||
@ -748,6 +751,8 @@ export default class NewVm extends BaseComponent {
|
||||
template => template && template.virtualizationMode === 'hvm'
|
||||
)
|
||||
|
||||
_templateNeedsVtpm = () => this.props.template?.platform?.vtpm === 'true'
|
||||
|
||||
// On change -------------------------------------------------------------------
|
||||
|
||||
_onChangeSshKeys = keys => this._setState({ sshKeys: map(keys, key => key.id) })
|
||||
@ -881,7 +886,12 @@ export default class NewVm extends BaseComponent {
|
||||
|
||||
_getRedirectionUrl = id => (this.state.state.multipleVms ? '/home' : `/vms/${id}`)
|
||||
|
||||
_handleBootFirmware = value => this._setState({ hvmBootFirmware: value, secureBoot: false })
|
||||
_handleBootFirmware = value =>
|
||||
this._setState({
|
||||
hvmBootFirmware: value,
|
||||
secureBoot: false,
|
||||
createVtpm: value === 'uefi' ? this._templateNeedsVtpm() : false,
|
||||
})
|
||||
|
||||
// MAIN ------------------------------------------------------------------------
|
||||
|
||||
@ -1531,6 +1541,7 @@ export default class NewVm extends BaseComponent {
|
||||
cpuCap,
|
||||
cpusMax,
|
||||
cpuWeight,
|
||||
createVtpm,
|
||||
destroyCloudConfigVdiAfterBoot,
|
||||
hvmBootFirmware,
|
||||
installMethod,
|
||||
@ -1565,6 +1576,8 @@ export default class NewVm extends BaseComponent {
|
||||
</label>
|
||||
) : null
|
||||
|
||||
const isVtpmSupported = pool.vtpmSupported
|
||||
|
||||
return (
|
||||
<Section icon='new-vm-advanced' title='newVmAdvancedPanel' done={this._isAdvancedDone()}>
|
||||
<SectionContent column>
|
||||
@ -1769,6 +1782,23 @@ export default class NewVm extends BaseComponent {
|
||||
<Item label={_('secureBoot')}>
|
||||
<Toggle onChange={this._toggleState('secureBoot')} value={secureBoot} />
|
||||
</Item>
|
||||
<Item label={_('enableVtpm')} className='d-inline-flex'>
|
||||
<Tooltip content={!isVtpmSupported ? _('vtpmNotSupported') : undefined}>
|
||||
<Toggle onChange={this._toggleState('createVtpm')} value={createVtpm} disabled={!isVtpmSupported} />
|
||||
</Tooltip>
|
||||
{/* FIXME: link to VTPM documentation when ready */}
|
||||
{/*
|
||||
<Tooltip content={_('seeVtpmDocumentation')}>
|
||||
<a className='text-info align-self-center' style={{ cursor: 'pointer' }} href='#'>
|
||||
<Icon icon='info' />
|
||||
</a>
|
||||
</Tooltip> */}
|
||||
{!createVtpm && this._templateNeedsVtpm() && (
|
||||
<span className='align-self-center text-warning ml-1'>
|
||||
<Icon icon='alarm' /> {_('warningVtpmRequired')}
|
||||
</span>
|
||||
)}
|
||||
</Item>
|
||||
</SectionContent>
|
||||
),
|
||||
isAdmin && isHvm && (
|
||||
|
Loading…
Reference in New Issue
Block a user