@xen-orchestra/backups 0.19.1 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ImportVmBackup.js +8 -3
- package/RemoteAdapter.js +6 -4
- package/_backupType.js +1 -1
- package/_backupWorker.js +2 -0
- package/_deltaVm.js +38 -13
- package/package.json +9 -4
package/ImportVmBackup.js
CHANGED
|
@@ -8,9 +8,9 @@ const { Task } = require('./Task.js')
|
|
|
8
8
|
const { watchStreamSize } = require('./_watchStreamSize.js')
|
|
9
9
|
|
|
10
10
|
exports.ImportVmBackup = class ImportVmBackup {
|
|
11
|
-
constructor({ adapter, metadata, srUuid, xapi, settings: { newMacAddresses } = {} }) {
|
|
11
|
+
constructor({ adapter, metadata, srUuid, xapi, settings: { newMacAddresses, mapVdisSrs = {} } = {} }) {
|
|
12
12
|
this._adapter = adapter
|
|
13
|
-
this._importDeltaVmSettings = { newMacAddresses }
|
|
13
|
+
this._importDeltaVmSettings = { newMacAddresses, mapVdisSrs }
|
|
14
14
|
this._metadata = metadata
|
|
15
15
|
this._srUuid = srUuid
|
|
16
16
|
this._xapi = xapi
|
|
@@ -30,7 +30,12 @@ exports.ImportVmBackup = class ImportVmBackup {
|
|
|
30
30
|
} else {
|
|
31
31
|
assert.strictEqual(metadata.mode, 'delta')
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
const ignoredVdis = new Set(
|
|
34
|
+
Object.entries(this._importDeltaVmSettings.mapVdisSrs)
|
|
35
|
+
.filter(([_, srUuid]) => srUuid === null)
|
|
36
|
+
.map(([vdiUuid]) => vdiUuid)
|
|
37
|
+
)
|
|
38
|
+
backup = await adapter.readDeltaVmBackup(metadata, ignoredVdis)
|
|
34
39
|
Object.values(backup.streams).forEach(stream => watchStreamSize(stream, sizeContainer))
|
|
35
40
|
}
|
|
36
41
|
|
package/RemoteAdapter.js
CHANGED
|
@@ -6,6 +6,7 @@ const fromCallback = require('promise-toolbox/fromCallback')
|
|
|
6
6
|
const fromEvent = require('promise-toolbox/fromEvent')
|
|
7
7
|
const pDefer = require('promise-toolbox/defer')
|
|
8
8
|
const groupBy = require('lodash/groupBy.js')
|
|
9
|
+
const pickBy = require('lodash/pickBy.js')
|
|
9
10
|
const { dirname, join, normalize, resolve } = require('path')
|
|
10
11
|
const { createLogger } = require('@xen-orchestra/log')
|
|
11
12
|
const { Constants, createVhdDirectoryFromStream, openVhd, VhdAbstract, VhdDirectory, VhdSynthetic } = require('vhd-lib')
|
|
@@ -576,14 +577,15 @@ class RemoteAdapter {
|
|
|
576
577
|
return stream
|
|
577
578
|
}
|
|
578
579
|
|
|
579
|
-
async readDeltaVmBackup(metadata) {
|
|
580
|
+
async readDeltaVmBackup(metadata, ignoredVdis) {
|
|
580
581
|
const handler = this._handler
|
|
581
|
-
const { vbds,
|
|
582
|
+
const { vbds, vhds, vifs, vm } = metadata
|
|
582
583
|
const dir = dirname(metadata._filename)
|
|
584
|
+
const vdis = ignoredVdis === undefined ? metadata.vdis : pickBy(metadata.vdis, vdi => !ignoredVdis.has(vdi.uuid))
|
|
583
585
|
|
|
584
586
|
const streams = {}
|
|
585
|
-
await asyncMapSettled(Object.keys(vdis), async
|
|
586
|
-
streams[`${
|
|
587
|
+
await asyncMapSettled(Object.keys(vdis), async ref => {
|
|
588
|
+
streams[`${ref}.vhd`] = await this._createSyntheticStream(handler, join(dir, vhds[ref]))
|
|
587
589
|
})
|
|
588
590
|
|
|
589
591
|
return {
|
package/_backupType.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
exports.isMetadataFile = filename => filename.endsWith('.json')
|
|
4
4
|
exports.isVhdFile = filename => filename.endsWith('.vhd')
|
|
5
5
|
exports.isXvaFile = filename => filename.endsWith('.xva')
|
|
6
|
-
exports.isXvaSumFile = filename => filename.endsWith('.xva.
|
|
6
|
+
exports.isXvaSumFile = filename => filename.endsWith('.xva.checksum')
|
package/_backupWorker.js
CHANGED
|
@@ -4,6 +4,8 @@ require('@xen-orchestra/log/configure.js').catchGlobalErrors(
|
|
|
4
4
|
require('@xen-orchestra/log').createLogger('xo:backups:worker')
|
|
5
5
|
)
|
|
6
6
|
|
|
7
|
+
require('@vates/cached-dns.lookup').createCachedLookup().patchGlobal()
|
|
8
|
+
|
|
7
9
|
const Disposable = require('promise-toolbox/Disposable')
|
|
8
10
|
const ignoreErrors = require('promise-toolbox/ignoreErrors')
|
|
9
11
|
const { compose } = require('@vates/compose')
|
package/_deltaVm.js
CHANGED
|
@@ -11,6 +11,8 @@ const { createVhdStreamWithLength } = require('vhd-lib')
|
|
|
11
11
|
const { defer } = require('golike-defer')
|
|
12
12
|
|
|
13
13
|
const { cancelableMap } = require('./_cancelableMap.js')
|
|
14
|
+
const { Task } = require('./Task.js')
|
|
15
|
+
const { pick } = require('lodash')
|
|
14
16
|
|
|
15
17
|
const TAG_BASE_DELTA = 'xo:base_delta'
|
|
16
18
|
exports.TAG_BASE_DELTA = TAG_BASE_DELTA
|
|
@@ -19,6 +21,17 @@ const TAG_COPY_SRC = 'xo:copy_of'
|
|
|
19
21
|
exports.TAG_COPY_SRC = TAG_COPY_SRC
|
|
20
22
|
|
|
21
23
|
const ensureArray = value => (value === undefined ? [] : Array.isArray(value) ? value : [value])
|
|
24
|
+
const resolveUuid = async (xapi, cache, uuid, type) => {
|
|
25
|
+
if (uuid == null) {
|
|
26
|
+
return uuid
|
|
27
|
+
}
|
|
28
|
+
let ref = cache.get(uuid)
|
|
29
|
+
if (ref === undefined) {
|
|
30
|
+
ref = await xapi.call(`${type}.get_by_uuid`, uuid)
|
|
31
|
+
cache.set(uuid, ref)
|
|
32
|
+
}
|
|
33
|
+
return ref
|
|
34
|
+
}
|
|
22
35
|
|
|
23
36
|
exports.exportDeltaVm = async function exportDeltaVm(
|
|
24
37
|
vm,
|
|
@@ -167,6 +180,12 @@ exports.importDeltaVm = defer(async function importDeltaVm(
|
|
|
167
180
|
}
|
|
168
181
|
}
|
|
169
182
|
|
|
183
|
+
const cache = new Map()
|
|
184
|
+
const mapVdisSrRefs = {}
|
|
185
|
+
for (const [vdiUuid, srUuid] of Object.entries(mapVdisSrs)) {
|
|
186
|
+
mapVdisSrRefs[vdiUuid] = await resolveUuid(xapi, cache, srUuid, 'SR')
|
|
187
|
+
}
|
|
188
|
+
|
|
170
189
|
const baseVdis = {}
|
|
171
190
|
baseVm &&
|
|
172
191
|
baseVm.$VBDs.forEach(vbd => {
|
|
@@ -181,19 +200,25 @@ exports.importDeltaVm = defer(async function importDeltaVm(
|
|
|
181
200
|
let suspendVdi
|
|
182
201
|
if (vmRecord.power_state === 'Suspended') {
|
|
183
202
|
const vdi = vdiRecords[vmRecord.suspend_VDI]
|
|
184
|
-
|
|
185
|
-
'VDI',
|
|
186
|
-
|
|
187
|
-
...vdi,
|
|
188
|
-
other_config: {
|
|
189
|
-
...vdi.other_config,
|
|
190
|
-
[TAG_BASE_DELTA]: undefined,
|
|
191
|
-
[TAG_COPY_SRC]: vdi.uuid,
|
|
192
|
-
},
|
|
193
|
-
sr: mapVdisSrs[vdi.uuid] ?? sr.$ref,
|
|
203
|
+
if (vdi === undefined) {
|
|
204
|
+
Task.warning('Suspend VDI not available for this suspended VM', {
|
|
205
|
+
vm: pick(vmRecord, 'uuid', 'name_label'),
|
|
194
206
|
})
|
|
195
|
-
|
|
196
|
-
|
|
207
|
+
} else {
|
|
208
|
+
suspendVdi = await xapi.getRecord(
|
|
209
|
+
'VDI',
|
|
210
|
+
await xapi.VDI_create({
|
|
211
|
+
...vdi,
|
|
212
|
+
other_config: {
|
|
213
|
+
...vdi.other_config,
|
|
214
|
+
[TAG_BASE_DELTA]: undefined,
|
|
215
|
+
[TAG_COPY_SRC]: vdi.uuid,
|
|
216
|
+
},
|
|
217
|
+
sr: mapVdisSrRefs[vdi.uuid] ?? sr.$ref,
|
|
218
|
+
})
|
|
219
|
+
)
|
|
220
|
+
$defer.onFailure(() => suspendVdi.$destroy())
|
|
221
|
+
}
|
|
197
222
|
}
|
|
198
223
|
|
|
199
224
|
// 1. Create the VM.
|
|
@@ -257,7 +282,7 @@ exports.importDeltaVm = defer(async function importDeltaVm(
|
|
|
257
282
|
[TAG_BASE_DELTA]: undefined,
|
|
258
283
|
[TAG_COPY_SRC]: vdi.uuid,
|
|
259
284
|
},
|
|
260
|
-
SR:
|
|
285
|
+
SR: mapVdisSrRefs[vdi.uuid] ?? sr.$ref,
|
|
261
286
|
})
|
|
262
287
|
)
|
|
263
288
|
$defer.onFailure(() => newVdi.$destroy())
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
|
10
10
|
},
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.21.1",
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": ">=14.6"
|
|
14
14
|
},
|
|
@@ -16,12 +16,13 @@
|
|
|
16
16
|
"postversion": "npm publish --access public"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
+
"@vates/cached-dns.lookup": "^1.0.0",
|
|
19
20
|
"@vates/compose": "^2.1.0",
|
|
20
|
-
"@vates/decorate-with": "^
|
|
21
|
+
"@vates/decorate-with": "^2.0.0",
|
|
21
22
|
"@vates/disposable": "^0.1.1",
|
|
22
23
|
"@vates/parse-duration": "^0.1.1",
|
|
23
24
|
"@xen-orchestra/async-map": "^0.1.2",
|
|
24
|
-
"@xen-orchestra/fs": "^0.
|
|
25
|
+
"@xen-orchestra/fs": "^1.0.1",
|
|
25
26
|
"@xen-orchestra/log": "^0.3.0",
|
|
26
27
|
"@xen-orchestra/template": "^0.1.0",
|
|
27
28
|
"compare-versions": "^4.0.1",
|
|
@@ -39,8 +40,12 @@
|
|
|
39
40
|
"vhd-lib": "^3.1.0",
|
|
40
41
|
"yazl": "^2.5.1"
|
|
41
42
|
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"rimraf": "^3.0.2",
|
|
45
|
+
"tmp": "^0.2.1"
|
|
46
|
+
},
|
|
42
47
|
"peerDependencies": {
|
|
43
|
-
"@xen-orchestra/xapi": "^0.
|
|
48
|
+
"@xen-orchestra/xapi": "^0.10.0"
|
|
44
49
|
},
|
|
45
50
|
"license": "AGPL-3.0-or-later",
|
|
46
51
|
"author": {
|