feat(xo-server/vm.migrate): call VM.assert_can_migrate before (#6245)

Fixes #5301
This commit is contained in:
Thierry Goettelmann
2022-05-30 15:04:12 +02:00
committed by GitHub
parent 7451f45885
commit d7d81431ef
3 changed files with 32 additions and 17 deletions

View File

@@ -11,6 +11,7 @@
- [Backup] Implement file cache for listing the backups of a VM (PR [#6220](https://github.com/vatesfr/xen-orchestra/pull/6220))
- [Backup] Add setting `backups.metadata.defaultSettings.unconditionalSnapshot` in `xo-server`'s configuration file to force a snapshot even when not required by the backup, this is useful to avoid locking the VM halted during the backup (PR [#6221](https://github.com/vatesfr/xen-orchestra/pull/6221))
- [XO Web] Add ability to configure a default filter for Storage [#6236](https://github.com/vatesfr/xen-orchestra/issues/6236) (PR [#6237](https://github.com/vatesfr/xen-orchestra/pull/6237))
- [VM migration] Ensure the VM can be migrated before performing the migration to avoid issues [#5301](https://github.com/vatesfr/xen-orchestra/issues/5301) (PR [#6245](https://github.com/vatesfr/xen-orchestra/pull/6245))
- [Backup] VMs with USB Pass-through devices are now supported! The advanced _Offline Snapshot Mode_ setting must be enabled. For Full Backup or Disaster Recovery jobs, Rolling Snapshot needs to be anabled as well. (PR [#6239](https://github.com/vatesfr/xen-orchestra/pull/6239))
- [RPU/Host] If some backup jobs are running on the pool, ask for confirmation before starting an RPU, shutdown/rebooting a host or restarting a host's toolstack (PR [6232](https://github.com/vatesfr/xen-orchestra/pull/6232))

View File

@@ -444,7 +444,7 @@ insertCd.resolve = {
// -------------------------------------------------------------------
export async function migrate({ vm, host, sr, mapVdisSrs, mapVifsNetworks, migrationNetwork, force }) {
export async function migrate({ vm, host, sr, mapVdisSrs, mapVifsNetworks, migrationNetwork, force, bypassAssert = false }) {
let mapVdisSrsXapi, mapVifsNetworksXapi
const permissions = []
@@ -475,6 +475,7 @@ export async function migrate({ vm, host, sr, mapVdisSrs, mapVifsNetworks, migra
mapVifsNetworks: mapVifsNetworksXapi,
mapVdisSrs: mapVdisSrsXapi,
force,
bypassAssert,
})
.catch(error => {
if (error?.code !== undefined) {
@@ -507,6 +508,12 @@ migrate.params = {
// Identifier of the Network use for the migration
migrationNetwork: { type: 'string', optional: true },
bypassAssert: {
description: 'Bypass the verification asserting whether a VM can be migrated to the specified destination,
optional: true,
type: 'boolean',
},
}
migrate.resolve = {

View File

@@ -593,6 +593,7 @@ export default class Xapi extends XapiBase {
mapVdisSrs = {},
mapVifsNetworks,
force = false,
bypassAssert = false,
}
) {
const getDefaultSrRef = once(() => {
@@ -661,23 +662,28 @@ export default class Xapi extends XapiBase {
}
}
const token = await hostXapi.call('host.migrate_receive', host.$ref, migrationNetwork.$ref, {})
const params = [
vm.$ref,
await hostXapi.call('host.migrate_receive', host.$ref, migrationNetwork.$ref, {}), // token
true, // Live migration.
vdis,
vifsMap,
{
force: force ? 'true' : 'false',
},
// FIXME: missing param `vgu_map`, it does not cause issues ATM but it
// might need to be changed one day.
// {},
]
if (!bypassAssert) {
await this.callAsync('VM.assert_can_migrate', ...params)
}
const loop = () =>
this.callAsync(
'VM.migrate_send',
vm.$ref,
token,
true, // Live migration.
vdis,
vifsMap,
{
force: force ? 'true' : 'false',
}
// FIXME: missing param `vgu_map`, it does not cause issues ATM but it
// might need to be changed one day.
// {},
)::pCatch({ code: 'TOO_MANY_STORAGE_MIGRATES' }, () => pDelay(1e4).then(loop))
this.callAsync('VM.migrate_send', ...params)::pCatch({ code: 'TOO_MANY_STORAGE_MIGRATES' }, () =>
pDelay(1e4).then(loop)
)
return loop().then(noop)
}
@@ -913,7 +919,7 @@ export default class Xapi extends XapiBase {
throw new Error(`unsupported type: '${type}'`)
}
async migrateVm(vmId, hostXapi, hostId, { force = false, mapVdisSrs, mapVifsNetworks, migrationNetworkId, sr } = {}) {
async migrateVm(vmId, hostXapi, hostId, { force = false, mapVdisSrs, mapVifsNetworks, migrationNetworkId, sr, bypassAssert } = {}) {
const vm = this.getObject(vmId)
const host = hostXapi.getObject(hostId)
@@ -932,6 +938,7 @@ export default class Xapi extends XapiBase {
mapVdisSrs,
mapVifsNetworks,
force,
bypassAssert,
})
} else {
try {