@xen-orchestra/backups 0.29.3 → 0.29.5
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/Backup.js +1 -1
- package/RemoteAdapter.js +6 -2
- package/Task.js +1 -1
- package/_backupWorker.js +1 -1
- package/merge-worker/cli.js +1 -1
- package/package.json +10 -10
- package/writers/DeltaBackupWriter.js +14 -14
- package/writers/FullBackupWriter.js +1 -3
- package/writers/_MixinBackupWriter.js +3 -4
package/Backup.js
CHANGED
package/RemoteAdapter.js
CHANGED
|
@@ -28,6 +28,7 @@ const { isMetadataFile } = require('./_backupType.js')
|
|
|
28
28
|
const { isValidXva } = require('./_isValidXva.js')
|
|
29
29
|
const { listPartitions, LVM_PARTITION_TYPE } = require('./_listPartitions.js')
|
|
30
30
|
const { lvs, pvs } = require('./_lvm.js')
|
|
31
|
+
const { watchStreamSize } = require('./_watchStreamSize')
|
|
31
32
|
// @todo : this import is marked extraneous , sould be fixed when lib is published
|
|
32
33
|
const { mount } = require('@vates/fuse-vhd')
|
|
33
34
|
const { asyncEach } = require('@vates/async-each')
|
|
@@ -661,7 +662,7 @@ class RemoteAdapter {
|
|
|
661
662
|
const handler = this._handler
|
|
662
663
|
if (this.#useVhdDirectory()) {
|
|
663
664
|
const dataPath = `${dirname(path)}/data/${uuidv4()}.vhd`
|
|
664
|
-
await createVhdDirectoryFromStream(handler, dataPath, input, {
|
|
665
|
+
const size = await createVhdDirectoryFromStream(handler, dataPath, input, {
|
|
665
666
|
concurrency: writeBlockConcurrency,
|
|
666
667
|
compression: this.#getCompressionType(),
|
|
667
668
|
async validator() {
|
|
@@ -671,12 +672,14 @@ class RemoteAdapter {
|
|
|
671
672
|
nbdClient,
|
|
672
673
|
})
|
|
673
674
|
await VhdAbstract.createAlias(handler, path, dataPath)
|
|
675
|
+
return size
|
|
674
676
|
} else {
|
|
675
|
-
|
|
677
|
+
return this.outputStream(path, input, { checksum, validator })
|
|
676
678
|
}
|
|
677
679
|
}
|
|
678
680
|
|
|
679
681
|
async outputStream(path, input, { checksum = true, validator = noop } = {}) {
|
|
682
|
+
const container = watchStreamSize(input)
|
|
680
683
|
await this._handler.outputStream(path, input, {
|
|
681
684
|
checksum,
|
|
682
685
|
dirMode: this._dirMode,
|
|
@@ -685,6 +688,7 @@ class RemoteAdapter {
|
|
|
685
688
|
return validator.apply(this, arguments)
|
|
686
689
|
},
|
|
687
690
|
})
|
|
691
|
+
return container.size
|
|
688
692
|
}
|
|
689
693
|
|
|
690
694
|
// open the hierarchy of ancestors until we find a full one
|
package/Task.js
CHANGED
|
@@ -100,7 +100,7 @@ class Task {
|
|
|
100
100
|
* In case of error, the task will be failed.
|
|
101
101
|
*
|
|
102
102
|
* @typedef Result
|
|
103
|
-
* @param {() => Result
|
|
103
|
+
* @param {() => Result} fn
|
|
104
104
|
* @param {boolean} last - Whether the task should succeed if there is no error
|
|
105
105
|
* @returns Result
|
|
106
106
|
*/
|
package/_backupWorker.js
CHANGED
package/merge-worker/cli.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict'
|
|
6
6
|
|
|
7
|
-
const { catchGlobalErrors } = require('@xen-orchestra/log/configure
|
|
7
|
+
const { catchGlobalErrors } = require('@xen-orchestra/log/configure')
|
|
8
8
|
const { createLogger } = require('@xen-orchestra/log')
|
|
9
9
|
const { getSyncedHandler } = require('@xen-orchestra/fs')
|
|
10
10
|
const { join } = require('path')
|
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.29.
|
|
11
|
+
"version": "0.29.5",
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": ">=14.6"
|
|
14
14
|
},
|
|
@@ -21,38 +21,38 @@
|
|
|
21
21
|
"@vates/cached-dns.lookup": "^1.0.0",
|
|
22
22
|
"@vates/compose": "^2.1.0",
|
|
23
23
|
"@vates/decorate-with": "^2.0.0",
|
|
24
|
-
"@vates/disposable": "^0.1.
|
|
24
|
+
"@vates/disposable": "^0.1.4",
|
|
25
25
|
"@vates/fuse-vhd": "^1.0.0",
|
|
26
26
|
"@vates/nbd-client": "*",
|
|
27
27
|
"@vates/parse-duration": "^0.1.1",
|
|
28
28
|
"@xen-orchestra/async-map": "^0.1.2",
|
|
29
|
-
"@xen-orchestra/fs": "^3.3.
|
|
30
|
-
"@xen-orchestra/log": "^0.
|
|
29
|
+
"@xen-orchestra/fs": "^3.3.1",
|
|
30
|
+
"@xen-orchestra/log": "^0.6.0",
|
|
31
31
|
"@xen-orchestra/template": "^0.1.0",
|
|
32
32
|
"compare-versions": "^5.0.1",
|
|
33
33
|
"d3-time-format": "^3.0.0",
|
|
34
34
|
"decorator-synchronized": "^0.6.0",
|
|
35
35
|
"end-of-stream": "^1.4.4",
|
|
36
|
-
"fs-extra": "^
|
|
36
|
+
"fs-extra": "^11.1.0",
|
|
37
37
|
"golike-defer": "^0.5.1",
|
|
38
38
|
"limit-concurrency-decorator": "^0.5.0",
|
|
39
39
|
"lodash": "^4.17.20",
|
|
40
40
|
"node-zone": "^0.4.0",
|
|
41
|
-
"parse-pairs": "^
|
|
41
|
+
"parse-pairs": "^2.0.0",
|
|
42
42
|
"promise-toolbox": "^0.21.0",
|
|
43
43
|
"proper-lockfile": "^4.1.2",
|
|
44
44
|
"uuid": "^9.0.0",
|
|
45
|
-
"vhd-lib": "^4.2.
|
|
45
|
+
"vhd-lib": "^4.2.1",
|
|
46
46
|
"yazl": "^2.5.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"rimraf": "^
|
|
50
|
-
"sinon": "^
|
|
49
|
+
"rimraf": "^4.1.1",
|
|
50
|
+
"sinon": "^15.0.1",
|
|
51
51
|
"test": "^3.2.1",
|
|
52
52
|
"tmp": "^0.2.1"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@xen-orchestra/xapi": "^1.
|
|
55
|
+
"@xen-orchestra/xapi": "^1.6.0"
|
|
56
56
|
},
|
|
57
57
|
"license": "AGPL-3.0-or-later",
|
|
58
58
|
"author": {
|
|
@@ -11,7 +11,6 @@ const { dirname } = require('path')
|
|
|
11
11
|
|
|
12
12
|
const { formatFilenameDate } = require('../_filenameDate.js')
|
|
13
13
|
const { getOldEntries } = require('../_getOldEntries.js')
|
|
14
|
-
const { getVmBackupDir } = require('../_getVmBackupDir.js')
|
|
15
14
|
const { Task } = require('../Task.js')
|
|
16
15
|
|
|
17
16
|
const { MixinBackupWriter } = require('./_MixinBackupWriter.js')
|
|
@@ -21,7 +20,7 @@ const { packUuid } = require('./_packUuid.js')
|
|
|
21
20
|
const { Disposable } = require('promise-toolbox')
|
|
22
21
|
const NbdClient = require('@vates/nbd-client')
|
|
23
22
|
|
|
24
|
-
const { debug, warn } = createLogger('xo:backups:DeltaBackupWriter')
|
|
23
|
+
const { debug, warn, info } = createLogger('xo:backups:DeltaBackupWriter')
|
|
25
24
|
|
|
26
25
|
exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(AbstractDeltaWriter) {
|
|
27
26
|
async checkBaseVdis(baseUuidToSrcVdi) {
|
|
@@ -29,8 +28,7 @@ exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(Ab
|
|
|
29
28
|
const backup = this._backup
|
|
30
29
|
const adapter = this._adapter
|
|
31
30
|
|
|
32
|
-
const
|
|
33
|
-
const vdisDir = `${backupDir}/vdis/${backup.job.id}`
|
|
31
|
+
const vdisDir = `${this._vmBackupDir}/vdis/${backup.job.id}`
|
|
34
32
|
|
|
35
33
|
await asyncMap(baseUuidToSrcVdi, async ([baseUuid, srcVdi]) => {
|
|
36
34
|
let found = false
|
|
@@ -135,7 +133,7 @@ exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(Ab
|
|
|
135
133
|
}
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
async _transfer({ timestamp, deltaExport
|
|
136
|
+
async _transfer({ timestamp, deltaExport }) {
|
|
139
137
|
const adapter = this._adapter
|
|
140
138
|
const backup = this._backup
|
|
141
139
|
|
|
@@ -143,7 +141,6 @@ exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(Ab
|
|
|
143
141
|
|
|
144
142
|
const jobId = job.id
|
|
145
143
|
const handler = adapter.handler
|
|
146
|
-
const backupDir = getVmBackupDir(vm.uuid)
|
|
147
144
|
|
|
148
145
|
// TODO: clean VM backup directory
|
|
149
146
|
|
|
@@ -175,9 +172,10 @@ exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(Ab
|
|
|
175
172
|
}
|
|
176
173
|
|
|
177
174
|
const { size } = await Task.run({ name: 'transfer' }, async () => {
|
|
175
|
+
let transferSize = 0
|
|
178
176
|
await Promise.all(
|
|
179
177
|
map(deltaExport.vdis, async (vdi, id) => {
|
|
180
|
-
const path = `${
|
|
178
|
+
const path = `${this._vmBackupDir}/${vhds[id]}`
|
|
181
179
|
|
|
182
180
|
const isDelta = vdi.other_config['xo:base_delta'] !== undefined
|
|
183
181
|
let parentPath
|
|
@@ -203,21 +201,25 @@ exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(Ab
|
|
|
203
201
|
const vdiRef = vm.$xapi.getObject(vdi.uuid).$ref
|
|
204
202
|
|
|
205
203
|
let nbdClient
|
|
206
|
-
if (
|
|
204
|
+
if (this._backup.config.useNbd) {
|
|
205
|
+
debug('useNbd is enabled', { vdi: id, path })
|
|
207
206
|
// get nbd if possible
|
|
208
207
|
try {
|
|
209
208
|
// this will always take the first host in the list
|
|
210
209
|
const [nbdInfo] = await vm.$xapi.call('VDI.get_nbd_info', vdiRef)
|
|
210
|
+
debug('got NBD info', { nbdInfo, vdi: id, path })
|
|
211
211
|
nbdClient = new NbdClient(nbdInfo)
|
|
212
212
|
await nbdClient.connect()
|
|
213
|
-
|
|
213
|
+
info('NBD client ready', { vdi: id, path })
|
|
214
214
|
} catch (error) {
|
|
215
215
|
nbdClient = undefined
|
|
216
|
-
|
|
216
|
+
warn('error connecting to NBD server', { error, vdi: id, path })
|
|
217
217
|
}
|
|
218
|
+
} else {
|
|
219
|
+
debug('useNbd is disabled', { vdi: id, path })
|
|
218
220
|
}
|
|
219
221
|
|
|
220
|
-
await adapter.writeVhd(path, deltaExport.streams[`${id}.vhd`], {
|
|
222
|
+
transferSize += await adapter.writeVhd(path, deltaExport.streams[`${id}.vhd`], {
|
|
221
223
|
// no checksum for VHDs, because they will be invalidated by
|
|
222
224
|
// merges and chainings
|
|
223
225
|
checksum: false,
|
|
@@ -238,9 +240,7 @@ exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(Ab
|
|
|
238
240
|
})
|
|
239
241
|
})
|
|
240
242
|
)
|
|
241
|
-
return {
|
|
242
|
-
size: Object.values(sizeContainers).reduce((sum, { size }) => sum + size, 0),
|
|
243
|
-
}
|
|
243
|
+
return { size: transferSize }
|
|
244
244
|
})
|
|
245
245
|
metadataContent.size = size
|
|
246
246
|
this._metadataFileName = await adapter.writeVmBackupMetadata(vm.uuid, metadataContent)
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const { formatFilenameDate } = require('../_filenameDate.js')
|
|
4
4
|
const { getOldEntries } = require('../_getOldEntries.js')
|
|
5
|
-
const { getVmBackupDir } = require('../_getVmBackupDir.js')
|
|
6
5
|
const { Task } = require('../Task.js')
|
|
7
6
|
|
|
8
7
|
const { MixinBackupWriter } = require('./_MixinBackupWriter.js')
|
|
@@ -34,7 +33,6 @@ exports.FullBackupWriter = class FullBackupWriter extends MixinBackupWriter(Abst
|
|
|
34
33
|
const { job, scheduleId, vm } = backup
|
|
35
34
|
|
|
36
35
|
const adapter = this._adapter
|
|
37
|
-
const backupDir = getVmBackupDir(vm.uuid)
|
|
38
36
|
|
|
39
37
|
// TODO: clean VM backup directory
|
|
40
38
|
|
|
@@ -47,7 +45,7 @@ exports.FullBackupWriter = class FullBackupWriter extends MixinBackupWriter(Abst
|
|
|
47
45
|
const basename = formatFilenameDate(timestamp)
|
|
48
46
|
|
|
49
47
|
const dataBasename = basename + '.xva'
|
|
50
|
-
const dataFilename =
|
|
48
|
+
const dataFilename = this._vmBackupDir + '/' + dataBasename
|
|
51
49
|
|
|
52
50
|
const metadata = {
|
|
53
51
|
jobId: job.id,
|
|
@@ -16,7 +16,6 @@ const { info, warn } = createLogger('xo:backups:MixinBackupWriter')
|
|
|
16
16
|
exports.MixinBackupWriter = (BaseClass = Object) =>
|
|
17
17
|
class MixinBackupWriter extends BaseClass {
|
|
18
18
|
#lock
|
|
19
|
-
#vmBackupDir
|
|
20
19
|
|
|
21
20
|
constructor({ remoteId, ...rest }) {
|
|
22
21
|
super(rest)
|
|
@@ -24,13 +23,13 @@ exports.MixinBackupWriter = (BaseClass = Object) =>
|
|
|
24
23
|
this._adapter = rest.backup.remoteAdapters[remoteId]
|
|
25
24
|
this._remoteId = remoteId
|
|
26
25
|
|
|
27
|
-
this
|
|
26
|
+
this._vmBackupDir = getVmBackupDir(this._backup.vm.uuid)
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
async _cleanVm(options) {
|
|
31
30
|
try {
|
|
32
31
|
return await Task.run({ name: 'clean-vm' }, () => {
|
|
33
|
-
return this._adapter.cleanVm(this
|
|
32
|
+
return this._adapter.cleanVm(this._vmBackupDir, {
|
|
34
33
|
...options,
|
|
35
34
|
fixMetadata: true,
|
|
36
35
|
logInfo: info,
|
|
@@ -50,7 +49,7 @@ exports.MixinBackupWriter = (BaseClass = Object) =>
|
|
|
50
49
|
|
|
51
50
|
async beforeBackup() {
|
|
52
51
|
const { handler } = this._adapter
|
|
53
|
-
const vmBackupDir = this
|
|
52
|
+
const vmBackupDir = this._vmBackupDir
|
|
54
53
|
await handler.mktree(vmBackupDir)
|
|
55
54
|
this.#lock = await handler.lock(vmBackupDir)
|
|
56
55
|
}
|