Continuous replication: do not rely on metadata import/export.
This commit is contained in:
parent
225043e01d
commit
f17ff02f4d
171
src/xapi.js
171
src/xapi.js
@ -870,6 +870,102 @@ export default class Xapi extends XapiBase {
|
|||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Low level create VM.
|
||||||
|
_createVm ({
|
||||||
|
actions_after_crash,
|
||||||
|
actions_after_reboot,
|
||||||
|
actions_after_shutdown,
|
||||||
|
affinity,
|
||||||
|
// appliance,
|
||||||
|
blocked_operations,
|
||||||
|
generation_id,
|
||||||
|
ha_always_run,
|
||||||
|
ha_restart_priority,
|
||||||
|
hardware_platform_version,
|
||||||
|
HVM_boot_params,
|
||||||
|
HVM_boot_policy,
|
||||||
|
HVM_shadow_multiplier,
|
||||||
|
is_a_template,
|
||||||
|
memory_dynamic_max,
|
||||||
|
memory_dynamic_min,
|
||||||
|
memory_static_max,
|
||||||
|
memory_static_min,
|
||||||
|
name_description,
|
||||||
|
name_label,
|
||||||
|
order,
|
||||||
|
other_config,
|
||||||
|
PCI_bus,
|
||||||
|
platform,
|
||||||
|
protection_policy,
|
||||||
|
PV_args,
|
||||||
|
PV_bootloader,
|
||||||
|
PV_bootloader_args,
|
||||||
|
PV_kernel,
|
||||||
|
PV_legacy_args,
|
||||||
|
PV_ramdisk,
|
||||||
|
recommendations,
|
||||||
|
shutdown_delay,
|
||||||
|
start_delay,
|
||||||
|
// suspend_SR,
|
||||||
|
tags,
|
||||||
|
user_version,
|
||||||
|
VCPUs_at_startup,
|
||||||
|
VCPUs_max,
|
||||||
|
VCPUs_params,
|
||||||
|
version,
|
||||||
|
xenstore_data
|
||||||
|
}) {
|
||||||
|
const _ = val => {
|
||||||
|
console.log(val)
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.call('VM.create', _({
|
||||||
|
actions_after_crash,
|
||||||
|
actions_after_reboot,
|
||||||
|
actions_after_shutdown,
|
||||||
|
affinity: affinity == null ? 'OpaqueRef:NULL' : affinity,
|
||||||
|
HVM_boot_params,
|
||||||
|
HVM_boot_policy,
|
||||||
|
is_a_template: Boolean(is_a_template),
|
||||||
|
memory_dynamic_max: String(memory_dynamic_max),
|
||||||
|
memory_dynamic_min: String(memory_dynamic_min),
|
||||||
|
memory_static_max: String(memory_static_max),
|
||||||
|
memory_static_min: String(memory_static_min),
|
||||||
|
other_config,
|
||||||
|
PCI_bus,
|
||||||
|
platform,
|
||||||
|
PV_args,
|
||||||
|
PV_bootloader,
|
||||||
|
PV_bootloader_args,
|
||||||
|
PV_kernel,
|
||||||
|
PV_legacy_args,
|
||||||
|
PV_ramdisk,
|
||||||
|
recommendations,
|
||||||
|
user_version: String(user_version),
|
||||||
|
VCPUs_at_startup: String(VCPUs_at_startup),
|
||||||
|
VCPUs_max: String(VCPUs_max),
|
||||||
|
VCPUs_params,
|
||||||
|
|
||||||
|
// Optional fields.
|
||||||
|
blocked_operations,
|
||||||
|
generation_id,
|
||||||
|
ha_always_run: Boolean(ha_always_run),
|
||||||
|
ha_restart_priority,
|
||||||
|
hardware_platform_version,
|
||||||
|
HVM_shadow_multiplier: +HVM_shadow_multiplier, // float
|
||||||
|
name_description,
|
||||||
|
name_label,
|
||||||
|
order,
|
||||||
|
protection_policy,
|
||||||
|
shutdown_delay: String(shutdown_delay),
|
||||||
|
start_delay: String(start_delay),
|
||||||
|
tags,
|
||||||
|
version: String(version),
|
||||||
|
xenstore_data
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: clean up on error.
|
// TODO: clean up on error.
|
||||||
async createVm (templateId, {
|
async createVm (templateId, {
|
||||||
nameDescription = undefined,
|
nameDescription = undefined,
|
||||||
@ -1113,12 +1209,6 @@ export default class Xapi extends XapiBase {
|
|||||||
// Create a snapshot of the VM and returns a delta export object.
|
// Create a snapshot of the VM and returns a delta export object.
|
||||||
@deferrable.onFailure
|
@deferrable.onFailure
|
||||||
async exportDeltaVm (onFailure, vmId, baseVmId = undefined) {
|
async exportDeltaVm (onFailure, vmId, baseVmId = undefined) {
|
||||||
const streams = {
|
|
||||||
'metadata.xva': this.exportVm(vmId, {
|
|
||||||
onlyMetadata: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const vm = await this.snapshotVm(vmId)
|
const vm = await this.snapshotVm(vmId)
|
||||||
onFailure(() => this._deleteVm(vm, true))
|
onFailure(() => this._deleteVm(vm, true))
|
||||||
|
|
||||||
@ -1129,6 +1219,7 @@ export default class Xapi extends XapiBase {
|
|||||||
baseVdis[vbd.VDI] = vbd.$VDI
|
baseVdis[vbd.VDI] = vbd.$VDI
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const streams = {}
|
||||||
const vdis = {}
|
const vdis = {}
|
||||||
const vbds = {}
|
const vbds = {}
|
||||||
forEach(vm.$VBDs, vbd => {
|
forEach(vm.$VBDs, vbd => {
|
||||||
@ -1170,12 +1261,18 @@ export default class Xapi extends XapiBase {
|
|||||||
streams[`${vdiId}.vhd`] = this._exportVdi(vdi, baseVdi, VDI_FORMAT_VHD)
|
streams[`${vdiId}.vhd`] = this._exportVdi(vdi, baseVdi, VDI_FORMAT_VHD)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const vifs = {}
|
||||||
|
forEach(vm.$VIFs, vif => {
|
||||||
|
vifs[vif.$ref] = vif
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// TODO: make non-enumerable?
|
// TODO: make non-enumerable?
|
||||||
streams: await streams::pAll(),
|
streams: await streams::pAll(),
|
||||||
|
|
||||||
vbds,
|
vbds,
|
||||||
vdis,
|
vdis,
|
||||||
|
vifs,
|
||||||
vm: baseVm
|
vm: baseVm
|
||||||
? {
|
? {
|
||||||
...vm,
|
...vm,
|
||||||
@ -1216,9 +1313,13 @@ export default class Xapi extends XapiBase {
|
|||||||
|
|
||||||
const { streams } = delta
|
const { streams } = delta
|
||||||
|
|
||||||
// 1. Import metadata.
|
// 1. Create the VMs.
|
||||||
const vm = await this._getOrWaitObject(
|
const vm = await this._getOrWaitObject(
|
||||||
await this._importVm(streams['metadata.xva'], sr, true)
|
await this._createVm({
|
||||||
|
...delta.vm,
|
||||||
|
affinity: null,
|
||||||
|
is_a_template: false
|
||||||
|
})
|
||||||
)
|
)
|
||||||
onFailure(() => this._deleteVm(vm))
|
onFailure(() => this._deleteVm(vm))
|
||||||
|
|
||||||
@ -1274,6 +1375,12 @@ export default class Xapi extends XapiBase {
|
|||||||
return newVdi
|
return newVdi
|
||||||
})::pAll()
|
})::pAll()
|
||||||
|
|
||||||
|
const networksOnPoolMasterByDevice = {}
|
||||||
|
let defaultNetwork
|
||||||
|
forEach(this.pool.$master.$PIFs, pif => {
|
||||||
|
defaultNetwork = networksOnPoolMasterByDevice[pif.device] = pif.$network
|
||||||
|
})
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
// Create VBDs.
|
// Create VBDs.
|
||||||
Promise.all(mapToArray(
|
Promise.all(mapToArray(
|
||||||
@ -1285,7 +1392,14 @@ export default class Xapi extends XapiBase {
|
|||||||
Promise.all(mapToArray(
|
Promise.all(mapToArray(
|
||||||
newVdis,
|
newVdis,
|
||||||
(vdi, id) => this._importVdiContent(vdi, streams[`${id}.vhd`], VDI_FORMAT_VHD)
|
(vdi, id) => this._importVdiContent(vdi, streams[`${id}.vhd`], VDI_FORMAT_VHD)
|
||||||
))
|
)),
|
||||||
|
|
||||||
|
// Create VIs.
|
||||||
|
defaultNetwork && Promise.all(mapToArray(delta.vifs, vif => this._createVif(
|
||||||
|
vm,
|
||||||
|
networksOnPoolMasterByDevice[vif.device] || defaultNetwork,
|
||||||
|
vif
|
||||||
|
)))
|
||||||
])
|
])
|
||||||
|
|
||||||
if (deleteBase && baseVm) {
|
if (deleteBase && baseVm) {
|
||||||
@ -1890,28 +2004,33 @@ export default class Xapi extends XapiBase {
|
|||||||
async _createVif (vm, network, {
|
async _createVif (vm, network, {
|
||||||
mac = '',
|
mac = '',
|
||||||
mtu = 1500,
|
mtu = 1500,
|
||||||
position = undefined
|
position = undefined,
|
||||||
} = {}) {
|
|
||||||
// TODO: use VM.get_allowed_VIF_devices()?
|
|
||||||
if (position == null) {
|
|
||||||
forEach(vm.$VIFs, vif => {
|
|
||||||
const curPos = +vif.device
|
|
||||||
if (!(position > curPos)) {
|
|
||||||
position = curPos
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
position = position == null ? 0 : position + 1
|
device = position && String(position),
|
||||||
|
ipv4_allowed = undefined,
|
||||||
|
ipv6_allowed = undefined,
|
||||||
|
locking_mode = undefined,
|
||||||
|
MAC = mac,
|
||||||
|
MTU = mtu,
|
||||||
|
other_config,
|
||||||
|
qos_algorithm_params = {},
|
||||||
|
qos_algorithm_type = ''
|
||||||
|
} = {}) {
|
||||||
|
if (device == null) {
|
||||||
|
device = (await this.call('VM.get_allowed_VIF_devices', vm.$ref))[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
const vifRef = await this.call('VIF.create', {
|
const vifRef = await this.call('VIF.create', {
|
||||||
device: String(position),
|
device,
|
||||||
MAC: String(mac),
|
ipv4_allowed,
|
||||||
MTU: String(mtu),
|
ipv6_allowed,
|
||||||
|
locking_mode,
|
||||||
|
MAC,
|
||||||
|
MTU: String(MTU),
|
||||||
network: network.$ref,
|
network: network.$ref,
|
||||||
other_config: {},
|
other_config,
|
||||||
qos_algorithm_params: {},
|
qos_algorithm_params,
|
||||||
qos_algorithm_type: '',
|
qos_algorithm_type,
|
||||||
VM: vm.$ref
|
VM: vm.$ref
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user