@xen-orchestra/backups 0.25.0 → 0.27.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/RemoteAdapter.js +14 -11
- package/_cleanVm.js +29 -16
- package/package.json +4 -4
package/RemoteAdapter.js
CHANGED
|
@@ -15,7 +15,7 @@ const { deduped } = require('@vates/disposable/deduped.js')
|
|
|
15
15
|
const { decorateMethodsWith } = require('@vates/decorate-with')
|
|
16
16
|
const { compose } = require('@vates/compose')
|
|
17
17
|
const { execFile } = require('child_process')
|
|
18
|
-
const { readdir,
|
|
18
|
+
const { readdir, lstat } = require('fs-extra')
|
|
19
19
|
const { v4: uuidv4 } = require('uuid')
|
|
20
20
|
const { ZipFile } = require('yazl')
|
|
21
21
|
const zlib = require('zlib')
|
|
@@ -47,13 +47,12 @@ const resolveSubpath = (root, path) => resolve(root, `.${resolve('/', path)}`)
|
|
|
47
47
|
const RE_VHDI = /^vhdi(\d+)$/
|
|
48
48
|
|
|
49
49
|
async function addDirectory(files, realPath, metadataPath) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
await asyncMap(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
50
|
+
const stats = await lstat(realPath)
|
|
51
|
+
if (stats.isDirectory()) {
|
|
52
|
+
await asyncMap(await readdir(realPath), file =>
|
|
53
|
+
addDirectory(files, realPath + '/' + file, metadataPath + '/' + file)
|
|
54
|
+
)
|
|
55
|
+
} else if (stats.isFile()) {
|
|
57
56
|
files.push({
|
|
58
57
|
realPath,
|
|
59
58
|
metadataPath,
|
|
@@ -292,7 +291,7 @@ class RemoteAdapter {
|
|
|
292
291
|
}
|
|
293
292
|
|
|
294
293
|
#useVhdDirectory() {
|
|
295
|
-
return this.handler.
|
|
294
|
+
return this.handler.useVhdDirectory()
|
|
296
295
|
}
|
|
297
296
|
|
|
298
297
|
#useAlias() {
|
|
@@ -383,8 +382,12 @@ class RemoteAdapter {
|
|
|
383
382
|
const entriesMap = {}
|
|
384
383
|
await asyncMap(await readdir(path), async name => {
|
|
385
384
|
try {
|
|
386
|
-
const stats = await
|
|
387
|
-
|
|
385
|
+
const stats = await lstat(`${path}/${name}`)
|
|
386
|
+
if (stats.isDirectory()) {
|
|
387
|
+
entriesMap[name + '/'] = {}
|
|
388
|
+
} else if (stats.isFile()) {
|
|
389
|
+
entriesMap[name] = {}
|
|
390
|
+
}
|
|
388
391
|
} catch (error) {
|
|
389
392
|
if (error == null || error.code !== 'ENOENT') {
|
|
390
393
|
throw error
|
package/_cleanVm.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const assert = require('assert')
|
|
4
4
|
const sum = require('lodash/sum')
|
|
5
|
+
const UUID = require('uuid')
|
|
5
6
|
const { asyncMap } = require('@xen-orchestra/async-map')
|
|
6
7
|
const { Constants, mergeVhd, openVhd, VhdAbstract, VhdFile } = require('vhd-lib')
|
|
7
8
|
const { isVhdAlias, resolveVhdAlias } = require('vhd-lib/aliases')
|
|
@@ -50,7 +51,7 @@ const computeVhdsSize = (handler, vhdPaths) =>
|
|
|
50
51
|
async function mergeVhdChain(chain, { handler, logInfo, remove, merge }) {
|
|
51
52
|
assert(chain.length >= 2)
|
|
52
53
|
const chainCopy = [...chain]
|
|
53
|
-
const parent = chainCopy.
|
|
54
|
+
const parent = chainCopy.shift()
|
|
54
55
|
const children = chainCopy
|
|
55
56
|
|
|
56
57
|
if (merge) {
|
|
@@ -59,30 +60,20 @@ async function mergeVhdChain(chain, { handler, logInfo, remove, merge }) {
|
|
|
59
60
|
let done, total
|
|
60
61
|
const handle = setInterval(() => {
|
|
61
62
|
if (done !== undefined) {
|
|
62
|
-
logInfo(`merging children in progress`, { children, parent, doneCount: done, totalCount: total})
|
|
63
|
+
logInfo(`merging children in progress`, { children, parent, doneCount: done, totalCount: total })
|
|
63
64
|
}
|
|
64
65
|
}, 10e3)
|
|
65
66
|
|
|
66
67
|
const mergedSize = await mergeVhd(handler, parent, handler, children, {
|
|
68
|
+
logInfo,
|
|
67
69
|
onProgress({ done: d, total: t }) {
|
|
68
70
|
done = d
|
|
69
71
|
total = t
|
|
70
72
|
},
|
|
73
|
+
remove,
|
|
71
74
|
})
|
|
72
75
|
|
|
73
76
|
clearInterval(handle)
|
|
74
|
-
const mergeTargetChild = children.shift()
|
|
75
|
-
await Promise.all([
|
|
76
|
-
VhdAbstract.rename(handler, parent, mergeTargetChild),
|
|
77
|
-
asyncMap(children, child => {
|
|
78
|
-
logInfo(`the VHD child is already merged`, { child })
|
|
79
|
-
if (remove) {
|
|
80
|
-
logInfo(`deleting merged VHD child`, { child })
|
|
81
|
-
return VhdAbstract.unlink(handler, child)
|
|
82
|
-
}
|
|
83
|
-
}),
|
|
84
|
-
])
|
|
85
|
-
|
|
86
77
|
return mergedSize
|
|
87
78
|
}
|
|
88
79
|
}
|
|
@@ -197,6 +188,7 @@ exports.cleanVm = async function cleanVm(
|
|
|
197
188
|
const handler = this._handler
|
|
198
189
|
|
|
199
190
|
const vhdsToJSons = new Set()
|
|
191
|
+
const vhdById = new Map()
|
|
200
192
|
const vhdParents = { __proto__: null }
|
|
201
193
|
const vhdChildren = { __proto__: null }
|
|
202
194
|
|
|
@@ -218,6 +210,27 @@ exports.cleanVm = async function cleanVm(
|
|
|
218
210
|
}
|
|
219
211
|
vhdChildren[parent] = path
|
|
220
212
|
}
|
|
213
|
+
// Detect VHDs with the same UUIDs
|
|
214
|
+
//
|
|
215
|
+
// Due to a bug introduced in a1bcd35e2
|
|
216
|
+
const duplicate = vhdById.get(UUID.stringify(vhd.footer.uuid))
|
|
217
|
+
let vhdKept = vhd
|
|
218
|
+
if (duplicate !== undefined) {
|
|
219
|
+
logWarn('uuid is duplicated', { uuid: UUID.stringify(vhd.footer.uuid) })
|
|
220
|
+
if (duplicate.containsAllDataOf(vhd)) {
|
|
221
|
+
logWarn(`should delete ${path}`)
|
|
222
|
+
vhdKept = duplicate
|
|
223
|
+
vhds.delete(path)
|
|
224
|
+
} else if (vhd.containsAllDataOf(duplicate)) {
|
|
225
|
+
logWarn(`should delete ${duplicate._path}`)
|
|
226
|
+
vhds.delete(duplicate._path)
|
|
227
|
+
} else {
|
|
228
|
+
logWarn(`same ids but different content`)
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
logInfo('not duplicate', UUID.stringify(vhd.footer.uuid), path)
|
|
232
|
+
}
|
|
233
|
+
vhdById.set(UUID.stringify(vhdKept.footer.uuid), vhdKept)
|
|
221
234
|
})
|
|
222
235
|
} catch (error) {
|
|
223
236
|
vhds.delete(path)
|
|
@@ -372,7 +385,7 @@ exports.cleanVm = async function cleanVm(
|
|
|
372
385
|
const unusedVhdsDeletion = []
|
|
373
386
|
const toMerge = []
|
|
374
387
|
{
|
|
375
|
-
// VHD chains (as list from
|
|
388
|
+
// VHD chains (as list from oldest to most recent) to merge indexed by most recent
|
|
376
389
|
// ancestor
|
|
377
390
|
const vhdChainsToMerge = { __proto__: null }
|
|
378
391
|
|
|
@@ -396,7 +409,7 @@ exports.cleanVm = async function cleanVm(
|
|
|
396
409
|
if (child !== undefined) {
|
|
397
410
|
const chain = getUsedChildChainOrDelete(child)
|
|
398
411
|
if (chain !== undefined) {
|
|
399
|
-
chain.
|
|
412
|
+
chain.unshift(vhd)
|
|
400
413
|
return chain
|
|
401
414
|
}
|
|
402
415
|
}
|
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.27.1",
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": ">=14.6"
|
|
14
14
|
},
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@vates/disposable": "^0.1.1",
|
|
23
23
|
"@vates/parse-duration": "^0.1.1",
|
|
24
24
|
"@xen-orchestra/async-map": "^0.1.2",
|
|
25
|
-
"@xen-orchestra/fs": "^
|
|
25
|
+
"@xen-orchestra/fs": "^2.0.0",
|
|
26
26
|
"@xen-orchestra/log": "^0.3.0",
|
|
27
27
|
"@xen-orchestra/template": "^0.1.0",
|
|
28
28
|
"compare-versions": "^4.0.1",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"promise-toolbox": "^0.21.0",
|
|
39
39
|
"proper-lockfile": "^4.1.2",
|
|
40
40
|
"uuid": "^8.3.2",
|
|
41
|
-
"vhd-lib": "^3.2
|
|
41
|
+
"vhd-lib": "^3.3.2",
|
|
42
42
|
"yazl": "^2.5.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"tmp": "^0.2.1"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@xen-orchestra/xapi": "^1.
|
|
49
|
+
"@xen-orchestra/xapi": "^1.4.0"
|
|
50
50
|
},
|
|
51
51
|
"license": "AGPL-3.0-or-later",
|
|
52
52
|
"author": {
|