diff --git a/CHANGELOG.md b/CHANGELOG.md index f43b8c7d5..8d40d17c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - [Backup NG] Errors listing backups on SMB remotes with extraneous files (PR [#3685](https://github.com/vatesfr/xen-orchestra/pull/3685)) - [Remotes] Don't expose credentials to users [#3682](https://github.com/vatesfr/xen-orchestra/issues/3682) (PR [#3687](https://github.com/vatesfr/xen-orchestra/pull/3687)) - [VM] Correctly display guest metrics updates (tools, network, etc.) [#3533](https://github.com/vatesfr/xen-orchestra/issues/3533) (PR [#3694](https://github.com/vatesfr/xen-orchestra/pull/3694)) +- [VM Templates] Fix deletion [#3498](https://github.com/vatesfr/xen-orchestra/issues/3498) (PR [#3695](https://github.com/vatesfr/xen-orchestra/pull/3695)) ### Released packages diff --git a/packages/xo-server/src/xapi/index.js b/packages/xo-server/src/xapi/index.js index f8fbb0991..b12ea8a01 100644 --- a/packages/xo-server/src/xapi/index.js +++ b/packages/xo-server/src/xapi/index.js @@ -658,23 +658,32 @@ export default class Xapi extends XapiBase { // ensure the vm record is up-to-date vm = await this.barrier($ref) + if (!force && 'destroy' in vm.blocked_operations) { + throw forbiddenOperation('destroy', vm.blocked_operations.destroy.reason) + } + + if ( + !forceDeleteDefaultTemplate && + vm.other_config.default_template === 'true' + ) { + throw forbiddenOperation('destroy', 'VM is default template') + } + // It is necessary for suspended VMs to be shut down // to be able to delete their VDIs. if (vm.power_state !== 'Halted') { await this.call('VM.hard_shutdown', $ref) } - if (force) { - await this._updateObjectMapProperty(vm, 'blocked_operations', { + await Promise.all( + this.call('VM.set_is_a_template', vm.$ref, false), + this._updateObjectMapProperty(vm, 'blocked_operations', { destroy: null, - }) - } - - if (forceDeleteDefaultTemplate) { - await this._updateObjectMapProperty(vm, 'other_config', { + }), + this._updateObjectMapProperty(vm, 'other_config', { default_template: null, }) - } + ) // must be done before destroying the VM const disks = getVmDisks(vm)