@xen-orchestra/backups 0.27.1 → 0.27.2
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 +1 -1
- package/_cleanVm.js +39 -30
- package/merge-worker/cli.js +1 -1
- package/package.json +3 -3
package/RemoteAdapter.js
CHANGED
|
@@ -279,7 +279,7 @@ class RemoteAdapter {
|
|
|
279
279
|
const dirs = new Set(files.map(file => dirname(file)))
|
|
280
280
|
for (const dir of dirs) {
|
|
281
281
|
// don't merge in main process, unused VHDs will be merged in the next backup run
|
|
282
|
-
await this.cleanVm(dir, { remove: true,
|
|
282
|
+
await this.cleanVm(dir, { remove: true, logWarn: warn })
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
const dedupedVmUuid = new Set(metadatas.map(_ => _.vm.uuid))
|
package/_cleanVm.js
CHANGED
|
@@ -55,12 +55,17 @@ async function mergeVhdChain(chain, { handler, logInfo, remove, merge }) {
|
|
|
55
55
|
const children = chainCopy
|
|
56
56
|
|
|
57
57
|
if (merge) {
|
|
58
|
-
logInfo(
|
|
58
|
+
logInfo('will merge children into parent', { children, parent })
|
|
59
59
|
|
|
60
60
|
let done, total
|
|
61
61
|
const handle = setInterval(() => {
|
|
62
62
|
if (done !== undefined) {
|
|
63
|
-
logInfo(
|
|
63
|
+
logInfo('merge in progress', {
|
|
64
|
+
done,
|
|
65
|
+
parent,
|
|
66
|
+
progress: Math.round((100 * done) / total),
|
|
67
|
+
total,
|
|
68
|
+
})
|
|
64
69
|
}
|
|
65
70
|
}, 10e3)
|
|
66
71
|
|
|
@@ -122,15 +127,15 @@ async function checkAliases(
|
|
|
122
127
|
{ handler, logInfo = noop, logWarn = console.warn, remove = false }
|
|
123
128
|
) {
|
|
124
129
|
const aliasFound = []
|
|
125
|
-
for (const
|
|
126
|
-
const target = await resolveVhdAlias(handler,
|
|
130
|
+
for (const alias of aliasPaths) {
|
|
131
|
+
const target = await resolveVhdAlias(handler, alias)
|
|
127
132
|
|
|
128
133
|
if (!isVhdFile(target)) {
|
|
129
|
-
logWarn('alias references non VHD target', {
|
|
134
|
+
logWarn('alias references non VHD target', { alias, target })
|
|
130
135
|
if (remove) {
|
|
131
|
-
logInfo('removing alias and non VHD target', {
|
|
136
|
+
logInfo('removing alias and non VHD target', { alias, target })
|
|
132
137
|
await handler.unlink(target)
|
|
133
|
-
await handler.unlink(
|
|
138
|
+
await handler.unlink(alias)
|
|
134
139
|
}
|
|
135
140
|
continue
|
|
136
141
|
}
|
|
@@ -143,13 +148,13 @@ async function checkAliases(
|
|
|
143
148
|
// error during dispose should not trigger a deletion
|
|
144
149
|
}
|
|
145
150
|
} catch (error) {
|
|
146
|
-
logWarn('missing or broken alias target', {
|
|
151
|
+
logWarn('missing or broken alias target', { alias, target, error })
|
|
147
152
|
if (remove) {
|
|
148
153
|
try {
|
|
149
|
-
await VhdAbstract.unlink(handler,
|
|
154
|
+
await VhdAbstract.unlink(handler, alias)
|
|
150
155
|
} catch (error) {
|
|
151
156
|
if (error.code !== 'ENOENT') {
|
|
152
|
-
logWarn('error deleting alias target', {
|
|
157
|
+
logWarn('error deleting alias target', { alias, target, error })
|
|
153
158
|
}
|
|
154
159
|
}
|
|
155
160
|
}
|
|
@@ -159,17 +164,17 @@ async function checkAliases(
|
|
|
159
164
|
aliasFound.push(resolve('/', target))
|
|
160
165
|
}
|
|
161
166
|
|
|
162
|
-
const
|
|
167
|
+
const vhds = await handler.list(targetDataRepository, {
|
|
163
168
|
ignoreMissing: true,
|
|
164
169
|
prependDir: true,
|
|
165
170
|
})
|
|
166
171
|
|
|
167
|
-
|
|
168
|
-
if (!aliasFound.includes(
|
|
169
|
-
logWarn('no alias references VHD', {
|
|
172
|
+
await asyncMap(vhds, async path => {
|
|
173
|
+
if (!aliasFound.includes(path)) {
|
|
174
|
+
logWarn('no alias references VHD', { path })
|
|
170
175
|
if (remove) {
|
|
171
|
-
logInfo('deleting
|
|
172
|
-
await VhdAbstract.unlink(handler,
|
|
176
|
+
logInfo('deleting unused VHD', { path })
|
|
177
|
+
await VhdAbstract.unlink(handler, path)
|
|
173
178
|
}
|
|
174
179
|
}
|
|
175
180
|
})
|
|
@@ -225,7 +230,7 @@ exports.cleanVm = async function cleanVm(
|
|
|
225
230
|
logWarn(`should delete ${duplicate._path}`)
|
|
226
231
|
vhds.delete(duplicate._path)
|
|
227
232
|
} else {
|
|
228
|
-
logWarn(
|
|
233
|
+
logWarn('same ids but different content')
|
|
229
234
|
}
|
|
230
235
|
} else {
|
|
231
236
|
logInfo('not duplicate', UUID.stringify(vhd.footer.uuid), path)
|
|
@@ -236,7 +241,7 @@ exports.cleanVm = async function cleanVm(
|
|
|
236
241
|
vhds.delete(path)
|
|
237
242
|
logWarn('VHD check error', { path, error })
|
|
238
243
|
if (error?.code === 'ERR_ASSERTION' && remove) {
|
|
239
|
-
logInfo('deleting broken
|
|
244
|
+
logInfo('deleting broken VHD', { path })
|
|
240
245
|
return VhdAbstract.unlink(handler, path)
|
|
241
246
|
}
|
|
242
247
|
}
|
|
@@ -284,9 +289,9 @@ exports.cleanVm = async function cleanVm(
|
|
|
284
289
|
if (!vhds.has(parent)) {
|
|
285
290
|
vhds.delete(vhdPath)
|
|
286
291
|
|
|
287
|
-
logWarn('parent VHD is missing', { parent, vhdPath })
|
|
292
|
+
logWarn('parent VHD is missing', { parent, child: vhdPath })
|
|
288
293
|
if (remove) {
|
|
289
|
-
logInfo('deleting orphan VHD', { vhdPath })
|
|
294
|
+
logInfo('deleting orphan VHD', { path: vhdPath })
|
|
290
295
|
deletions.push(VhdAbstract.unlink(handler, vhdPath))
|
|
291
296
|
}
|
|
292
297
|
}
|
|
@@ -337,7 +342,7 @@ exports.cleanVm = async function cleanVm(
|
|
|
337
342
|
try {
|
|
338
343
|
metadata = JSON.parse(await handler.readFile(json))
|
|
339
344
|
} catch (error) {
|
|
340
|
-
logWarn('failed to read metadata
|
|
345
|
+
logWarn('failed to read backup metadata', { path: json, error })
|
|
341
346
|
jsons.delete(json)
|
|
342
347
|
return
|
|
343
348
|
}
|
|
@@ -348,9 +353,9 @@ exports.cleanVm = async function cleanVm(
|
|
|
348
353
|
if (xvas.has(linkedXva)) {
|
|
349
354
|
unusedXvas.delete(linkedXva)
|
|
350
355
|
} else {
|
|
351
|
-
logWarn('
|
|
356
|
+
logWarn('the XVA linked to the backup is missing', { backup: json, xva: linkedXva })
|
|
352
357
|
if (remove) {
|
|
353
|
-
logInfo('deleting incomplete backup', { json })
|
|
358
|
+
logInfo('deleting incomplete backup', { path: json })
|
|
354
359
|
jsons.delete(json)
|
|
355
360
|
await handler.unlink(json)
|
|
356
361
|
}
|
|
@@ -371,9 +376,9 @@ exports.cleanVm = async function cleanVm(
|
|
|
371
376
|
vhdsToJSons[path] = json
|
|
372
377
|
})
|
|
373
378
|
} else {
|
|
374
|
-
logWarn('some
|
|
379
|
+
logWarn('some VHDs linked to the backup are missing', { backup: json, missingVhds })
|
|
375
380
|
if (remove) {
|
|
376
|
-
logInfo('deleting incomplete backup', { json })
|
|
381
|
+
logInfo('deleting incomplete backup', { path: json })
|
|
377
382
|
jsons.delete(json)
|
|
378
383
|
await handler.unlink(json)
|
|
379
384
|
}
|
|
@@ -414,9 +419,9 @@ exports.cleanVm = async function cleanVm(
|
|
|
414
419
|
}
|
|
415
420
|
}
|
|
416
421
|
|
|
417
|
-
logWarn('unused VHD', { vhd })
|
|
422
|
+
logWarn('unused VHD', { path: vhd })
|
|
418
423
|
if (remove) {
|
|
419
|
-
logInfo('deleting unused VHD', { vhd })
|
|
424
|
+
logInfo('deleting unused VHD', { path: vhd })
|
|
420
425
|
unusedVhdsDeletion.push(VhdAbstract.unlink(handler, vhd))
|
|
421
426
|
}
|
|
422
427
|
}
|
|
@@ -497,11 +502,15 @@ exports.cleanVm = async function cleanVm(
|
|
|
497
502
|
|
|
498
503
|
// don't warn if the size has changed after a merge
|
|
499
504
|
if (!merged && fileSystemSize !== size) {
|
|
500
|
-
logWarn('incorrect size in metadata', {
|
|
505
|
+
logWarn('incorrect backup size in metadata', {
|
|
506
|
+
path: metadataPath,
|
|
507
|
+
actual: size ?? 'none',
|
|
508
|
+
expected: fileSystemSize,
|
|
509
|
+
})
|
|
501
510
|
}
|
|
502
511
|
}
|
|
503
512
|
} catch (error) {
|
|
504
|
-
logWarn('failed to get
|
|
513
|
+
logWarn('failed to get backup size', { backup: metadataPath, error })
|
|
505
514
|
return
|
|
506
515
|
}
|
|
507
516
|
|
|
@@ -511,7 +520,7 @@ exports.cleanVm = async function cleanVm(
|
|
|
511
520
|
try {
|
|
512
521
|
await handler.writeFile(metadataPath, JSON.stringify(metadata), { flags: 'w' })
|
|
513
522
|
} catch (error) {
|
|
514
|
-
logWarn('
|
|
523
|
+
logWarn('failed to update backup size in metadata', { path: metadataPath, error })
|
|
515
524
|
}
|
|
516
525
|
}
|
|
517
526
|
})
|
package/merge-worker/cli.js
CHANGED
|
@@ -64,7 +64,7 @@ const main = Disposable.wrap(async function* main(args) {
|
|
|
64
64
|
try {
|
|
65
65
|
const vmDir = getVmBackupDir(String(await handler.readFile(taskFile)))
|
|
66
66
|
try {
|
|
67
|
-
await adapter.cleanVm(vmDir, { merge: true,
|
|
67
|
+
await adapter.cleanVm(vmDir, { merge: true, logInfo: info, logWarn: warn, remove: true })
|
|
68
68
|
} catch (error) {
|
|
69
69
|
// consider the clean successful if the VM dir is missing
|
|
70
70
|
if (error.code !== 'ENOENT') {
|
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.27.
|
|
11
|
+
"version": "0.27.2",
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": ">=14.6"
|
|
14
14
|
},
|
|
@@ -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.3.
|
|
41
|
+
"vhd-lib": "^3.3.3",
|
|
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.4.
|
|
49
|
+
"@xen-orchestra/xapi": "^1.4.1"
|
|
50
50
|
},
|
|
51
51
|
"license": "AGPL-3.0-or-later",
|
|
52
52
|
"author": {
|