fix(Xapi#moveVdi): XS 7.3 support (#635)
This commit is contained in:
parent
5fe03f2934
commit
ba6393165d
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
}))
|
}))
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user