feat(xo-server/vm.migrate): call VM.assert_can_migrate before (#6245)
Fixes #5301
This commit is contained in:
committed by
GitHub
parent
7451f45885
commit
d7d81431ef
@@ -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))
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user