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
|
- [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))
|
- [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/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
|
### 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))
|
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) {
|
if (params.bootAfterCreate) {
|
||||||
startVmAndDestroyCloudConfigVdi(xapi, xapiVm, cloudConfigVdiUuid, params)
|
startVmAndDestroyCloudConfigVdi(xapi, xapiVm, cloudConfigVdiUuid, params)
|
||||||
}
|
}
|
||||||
@ -258,6 +263,11 @@ create.params = {
|
|||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createVtpm: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
networkConfig: {
|
networkConfig: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true,
|
optional: true,
|
||||||
|
@ -1582,6 +1582,7 @@ const messages = {
|
|||||||
createVmModalWarningMessage:
|
createVmModalWarningMessage:
|
||||||
"You're about to use a large amount of resources available on the resource set. Are you sure you want to continue?",
|
"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',
|
copyHostBiosStrings: 'Copy host BIOS strings to VM',
|
||||||
|
enableVtpm: 'Enable VTPM',
|
||||||
newVmCreateNewVmOn: 'Create a new VM on {select}',
|
newVmCreateNewVmOn: 'Create a new VM on {select}',
|
||||||
newVmCreateNewVmNoPermission: 'You have no permission to create a VM',
|
newVmCreateNewVmNoPermission: 'You have no permission to create a VM',
|
||||||
newVmInfoPanel: 'Info',
|
newVmInfoPanel: 'Info',
|
||||||
@ -1655,6 +1656,7 @@ const messages = {
|
|||||||
vmBootFirmwareIsUefi: 'The boot firmware is UEFI',
|
vmBootFirmwareIsUefi: 'The boot firmware is UEFI',
|
||||||
destroyCloudConfigVdiAfterBoot: 'Destroy cloud config drive after first boot',
|
destroyCloudConfigVdiAfterBoot: 'Destroy cloud config drive after first boot',
|
||||||
vtpmNotSupported: 'VTPM is only supported on pools running XCP-ng/XS 8.3 or later.',
|
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 -----
|
// ----- Self -----
|
||||||
resourceSets: 'Resource sets',
|
resourceSets: 'Resource sets',
|
||||||
|
@ -100,6 +100,14 @@ $select-input-height: 40px; // Bootstrap input height
|
|||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.d-inline-flex {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-self-center {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
// COLORS ======================================================================
|
// COLORS ======================================================================
|
||||||
|
|
||||||
.xo-status-running {
|
.xo-status-running {
|
||||||
|
@ -346,6 +346,7 @@ export default class NewVm extends BaseComponent {
|
|||||||
seqStart: 1,
|
seqStart: 1,
|
||||||
share: this._getResourceSet()?.shareByDefault ?? false,
|
share: this._getResourceSet()?.shareByDefault ?? false,
|
||||||
tags: [],
|
tags: [],
|
||||||
|
createVtpm: this._templateNeedsVtpm(),
|
||||||
},
|
},
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
@ -493,6 +494,7 @@ export default class NewVm extends BaseComponent {
|
|||||||
bootAfterCreate: state.bootAfterCreate,
|
bootAfterCreate: state.bootAfterCreate,
|
||||||
copyHostBiosStrings:
|
copyHostBiosStrings:
|
||||||
state.hvmBootFirmware !== 'uefi' && !this._templateHasBiosStrings() && state.copyHostBiosStrings,
|
state.hvmBootFirmware !== 'uefi' && !this._templateHasBiosStrings() && state.copyHostBiosStrings,
|
||||||
|
createVtpm: state.createVtpm,
|
||||||
destroyCloudConfigVdiAfterBoot: state.destroyCloudConfigVdiAfterBoot,
|
destroyCloudConfigVdiAfterBoot: state.destroyCloudConfigVdiAfterBoot,
|
||||||
secureBoot: state.secureBoot,
|
secureBoot: state.secureBoot,
|
||||||
share: state.share,
|
share: state.share,
|
||||||
@ -599,6 +601,7 @@ export default class NewVm extends BaseComponent {
|
|||||||
}),
|
}),
|
||||||
// settings
|
// settings
|
||||||
secureBoot: template.secureBoot,
|
secureBoot: template.secureBoot,
|
||||||
|
createVtpm: this._templateNeedsVtpm(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this._isCoreOs()) {
|
if (this._isCoreOs()) {
|
||||||
@ -748,6 +751,8 @@ export default class NewVm extends BaseComponent {
|
|||||||
template => template && template.virtualizationMode === 'hvm'
|
template => template && template.virtualizationMode === 'hvm'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_templateNeedsVtpm = () => this.props.template?.platform?.vtpm === 'true'
|
||||||
|
|
||||||
// On change -------------------------------------------------------------------
|
// On change -------------------------------------------------------------------
|
||||||
|
|
||||||
_onChangeSshKeys = keys => this._setState({ sshKeys: map(keys, key => key.id) })
|
_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}`)
|
_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 ------------------------------------------------------------------------
|
// MAIN ------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -1531,6 +1541,7 @@ export default class NewVm extends BaseComponent {
|
|||||||
cpuCap,
|
cpuCap,
|
||||||
cpusMax,
|
cpusMax,
|
||||||
cpuWeight,
|
cpuWeight,
|
||||||
|
createVtpm,
|
||||||
destroyCloudConfigVdiAfterBoot,
|
destroyCloudConfigVdiAfterBoot,
|
||||||
hvmBootFirmware,
|
hvmBootFirmware,
|
||||||
installMethod,
|
installMethod,
|
||||||
@ -1565,6 +1576,8 @@ export default class NewVm extends BaseComponent {
|
|||||||
</label>
|
</label>
|
||||||
) : null
|
) : null
|
||||||
|
|
||||||
|
const isVtpmSupported = pool.vtpmSupported
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Section icon='new-vm-advanced' title='newVmAdvancedPanel' done={this._isAdvancedDone()}>
|
<Section icon='new-vm-advanced' title='newVmAdvancedPanel' done={this._isAdvancedDone()}>
|
||||||
<SectionContent column>
|
<SectionContent column>
|
||||||
@ -1769,6 +1782,23 @@ export default class NewVm extends BaseComponent {
|
|||||||
<Item label={_('secureBoot')}>
|
<Item label={_('secureBoot')}>
|
||||||
<Toggle onChange={this._toggleState('secureBoot')} value={secureBoot} />
|
<Toggle onChange={this._toggleState('secureBoot')} value={secureBoot} />
|
||||||
</Item>
|
</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>
|
</SectionContent>
|
||||||
),
|
),
|
||||||
isAdmin && isHvm && (
|
isAdmin && isHvm && (
|
||||||
|
Loading…
Reference in New Issue
Block a user