fix(Xapi#moveVdi): XS 7.3 support (#635)

This commit is contained in:
Julien Fontanet 2017-12-29 09:57:32 +01:00 committed by GitHub
parent 5fe03f2934
commit ba6393165d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 59 deletions

View File

@ -21,10 +21,12 @@ export async function create ({ name, size, sr, vm, bootable, position, mode })
}) })
if (attach) { if (attach) {
await xapi.attachVdiToVm(vdi.$id, vm._xapiId, { await xapi.createVbd({
bootable, bootable,
position, mode,
readOnly: mode === 'RO', userdevice: position,
vdi: vdi.$id,
vm: vm._xapiId,
}) })
} }

View File

@ -1146,10 +1146,12 @@ exports.import = import_
# FIXME: if position is used, all other disks after this position # FIXME: if position is used, all other disks after this position
# should be shifted. # should be shifted.
attachDisk = $coroutine ({vm, vdi, position, mode, bootable}) -> attachDisk = $coroutine ({vm, vdi, position, mode, bootable}) ->
yield @getXapi(vm).attachVdiToVm(vdi._xapiId, vm._xapiId, { yield @getXapi(vm).createVbd({
bootable, bootable,
position, mode,
readOnly: mode is 'RO' userdevice: position,
vdi: vdi._xapiId,
vm: vm._xapiId,
}) })
return return

View File

@ -590,7 +590,7 @@ async function createVDIOnLVMWithoutSizeLimit (xapi, lvmSr, diskSize) {
async function createNewDisk (xapi, sr, vm, diskSize) { async function createNewDisk (xapi, sr, vm, diskSize) {
const newDisk = await createVDIOnLVMWithoutSizeLimit(xapi, sr, diskSize) const newDisk = await createVDIOnLVMWithoutSizeLimit(xapi, sr, diskSize)
await xapi.attachVdiToVm(newDisk, vm) await xapi.createVbd({ vdi: newDisk, vm })
let vbd = await xapi._waitObjectState(newDisk.$id, disk => Boolean(disk.$VBDs.length)).$VBDs[0] let vbd = await xapi._waitObjectState(newDisk.$id, disk => Boolean(disk.$VBDs.length)).$VBDs[0]
vbd = await xapi._waitObjectState(vbd.$id, vbd => Boolean(vbd.device.length)) vbd = await xapi._waitObjectState(vbd.$id, vbd => Boolean(vbd.device.length))
return '/dev/' + vbd.device return '/dev/' + vbd.device

View File

@ -1015,7 +1015,11 @@ export default class Xapi extends XapiBase {
// Create VBDs. // Create VBDs.
asyncMap( asyncMap(
delta.vbds, delta.vbds,
vbd => this._createVbd(vm, newVdis[vbd.VDI], vbd) vbd => this.createVbd({
...vbd,
vdi: newVdis[vbd.VDI],
vm,
})
), ),
// Import VDI contents. // Import VDI contents.
@ -1266,7 +1270,11 @@ export default class Xapi extends XapiBase {
}) })
$defer.onFailure(() => this._deleteVdi(vdi)) $defer.onFailure(() => this._deleteVdi(vdi))
return this._createVbd(vm, vdi, { position: disk.position }) return this.createVbd({
userdevice: disk.position,
vdi,
vm,
})
}).concat(map(networks, (networkId, i) => ( }).concat(map(networks, (networkId, i) => (
this._createVif(vm, this.getObject(networkId), { this._createVif(vm, this.getObject(networkId), {
device: vifDevices[i], device: vifDevices[i],
@ -1530,54 +1538,62 @@ export default class Xapi extends XapiBase {
// ================================================================= // =================================================================
async _createVbd (vm, vdi, { async createVbd ({
bootable = false, bootable = false,
empty = !vdi, other_config = {},
qos_algorithm_params = {},
qos_algorithm_type = '',
type = 'Disk', type = 'Disk',
unpluggable = false, unpluggable = false,
userdevice = undefined, userdevice,
VDI,
VM,
vdi = VDI,
empty = vdi === undefined,
mode = (type === 'Disk') ? 'RW' : 'RO', mode = (type === 'Disk') ? 'RW' : 'RO',
position = userdevice, vm = VM,
readOnly = (mode === 'RO'),
} = {}) { } = {}) {
vdi = this.getObject(vdi)
vm = this.getObject(vm)
debug(`Creating VBD for VDI ${vdi.name_label} on VM ${vm.name_label}`) debug(`Creating VBD for VDI ${vdi.name_label} on VM ${vm.name_label}`)
if (position == null) { if (userdevice == null) {
const allowed = await this.call('VM.get_allowed_VBD_devices', vm.$ref) const allowed = await this.call('VM.get_allowed_VBD_devices', vm.$ref)
const {length} = allowed const {length} = allowed
if (!length) { if (length === 0) {
throw new Error('no allowed VBD positions (devices)') throw new Error('no allowed VBD devices')
} }
if (type === 'CD') { if (type === 'CD') {
// Choose position 3 if allowed. // Choose position 3 if allowed.
position = includes(allowed, '3') userdevice = includes(allowed, '3')
? '3' ? '3'
: allowed[0] : allowed[0]
} else { } else {
position = allowed[0] userdevice = allowed[0]
// Avoid position 3 if possible. // Avoid userdevice 3 if possible.
if (position === '3' && length > 1) { if (userdevice === '3' && length > 1) {
position = allowed[1] userdevice = allowed[1]
} }
} }
} }
// By default a VBD is unpluggable. // By default a VBD is unpluggable.
const vbdRef = await this.call('VBD.create', { const vbdRef = await this.call('VBD.create', {
bootable: Boolean(bootable), bootable,
empty: Boolean(empty), empty,
mode: readOnly ? 'RO' : 'RW', mode,
other_config: {}, other_config,
qos_algorithm_params: {}, qos_algorithm_params,
qos_algorithm_type: '', qos_algorithm_type,
type, type,
unpluggable: Boolean(unpluggable), unpluggable,
userdevice: String(position), userdevice,
VDI: vdi.$ref, VDI: vdi && vdi.$ref,
VM: vm.$ref, VM: vm.$ref,
}) })
@ -1649,24 +1665,21 @@ export default class Xapi extends XapiBase {
try { try {
await this.call('VDI.pool_migrate', vdi.$ref, sr.$ref, {}) await this.call('VDI.pool_migrate', vdi.$ref, sr.$ref, {})
} catch (error) { } catch (error) {
if (error.code !== 'VDI_NEEDS_VM_FOR_MIGRATE') { const { code } = error
if (code !== 'LICENCE_RESTRICTION' && code !== 'VDI_NEEDS_VM_FOR_MIGRATE') {
throw error throw error
} }
const newVdiref = await this.call('VDI.copy', vdi.$ref, sr.$ref) const newVdi = await this.barrier(
const newVdi = await this._getOrWaitObject(newVdiref) await this.call('VDI.copy', vdi.$ref, sr.$ref)
await Promise.all(mapToArray(vdi.$VBDs, async vbd => { )
// Remove the old VBD await asyncMap(vdi.$VBDs, vbd => Promise.all([
await this.call('VBD.destroy', vbd.$ref) this.call('VBD.destroy', vbd.$ref),
// Attach the new VDI to the VM with old VBD settings this.createVbd({
await this._createVbd(vbd.$VM, newVdi, { ...vbd,
bootable: vbd.bootable, vdi: newVdi,
position: vbd.userdevice, }),
type: vbd.type, ]))
readOnly: vbd.mode === 'RO', await this._deleteVdi(vdi)
})
// Remove the old VDI
await this._deleteVdi(vdi)
}))
} }
} }
@ -1728,21 +1741,15 @@ export default class Xapi extends XapiBase {
await this._setObjectProperties(cdDrive, {bootable}) await this._setObjectProperties(cdDrive, {bootable})
} }
} else { } else {
await this._createVbd(vm, cd, { await this.createVbd({
bootable, bootable,
type: 'CD', type: 'CD',
vdi: cd,
vm,
}) })
} }
} }
async attachVdiToVm (vdiId, vmId, opts = undefined) {
await this._createVbd(
this.getObject(vmId),
this.getObject(vdiId),
opts
)
}
async connectVbd (vbdId) { async connectVbd (vbdId) {
await this.call('VBD.plug', vbdId) await this.call('VBD.plug', vbdId)
} }
@ -2128,7 +2135,7 @@ export default class Xapi extends XapiBase {
// because it works // because it works
await this._importVdiContent(vdi, buffer, VDI_FORMAT_RAW).catch(console.warn) await this._importVdiContent(vdi, buffer, VDI_FORMAT_RAW).catch(console.warn)
await this._createVbd(vm, vdi) await this.createVbd({ vdi, vm })
} }
@deferrable @deferrable

View File

@ -162,10 +162,13 @@ export default {
} }
) )
.then(ref => this._getOrWaitObject(ref)) .then(ref => this._getOrWaitObject(ref))
.then(vdi => this._createVbd(vm, vdi, { .then(vdi => this.createVbd({
// Either the CD or the 1st disk is bootable (only useful for PV VMs) // Either the CD or the 1st disk is bootable (only useful for PV VMs)
bootable: !(hasBootableDisk || i), bootable: !(hasBootableDisk || i),
userdevice: devices[i], userdevice: devices[i],
vdi,
vm,
})) }))
)) ))
} }