@xen-orchestra/backups 0.73.0 → 0.73.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.mjs
CHANGED
|
@@ -300,7 +300,20 @@ export class RemoteAdapter {
|
|
|
300
300
|
async deleteFullVmBackups(backups) {
|
|
301
301
|
const handler = this._handler
|
|
302
302
|
await asyncMapSettled(backups, ({ _filename, xva }) =>
|
|
303
|
-
Promise.all([
|
|
303
|
+
Promise.all([
|
|
304
|
+
handler.unlink(_filename).catch(error => {
|
|
305
|
+
warn('error while removing full vm backup metadata', { error, filename: _filename })
|
|
306
|
+
if (error.code !== 'ENOENT') throw error
|
|
307
|
+
}),
|
|
308
|
+
handler.unlink(resolveRelativeFromFile(_filename, xva)).catch(error => {
|
|
309
|
+
warn('error while removing full vm backup file', { error, filename: _filename })
|
|
310
|
+
if (error.code !== 'ENOENT') throw error
|
|
311
|
+
}),
|
|
312
|
+
handler.unlink(resolveRelativeFromFile(_filename, `${xva}.checksum`)).catch(error => {
|
|
313
|
+
// checksum can be missing , it's not an issue
|
|
314
|
+
if (error.code !== 'ENOENT') throw error
|
|
315
|
+
}),
|
|
316
|
+
])
|
|
304
317
|
)
|
|
305
318
|
|
|
306
319
|
await this.#removeVmBackupsFromCache(backups)
|
|
@@ -311,18 +324,46 @@ export class RemoteAdapter {
|
|
|
311
324
|
}
|
|
312
325
|
|
|
313
326
|
async deleteVmBackups(files) {
|
|
314
|
-
const
|
|
315
|
-
|
|
327
|
+
const metadataOrNull = await asyncMap(files, async file => {
|
|
328
|
+
try {
|
|
329
|
+
return await this.readVmBackupMetadata(file)
|
|
330
|
+
} catch (error) {
|
|
331
|
+
if (error.code === 'ENOENT') {
|
|
332
|
+
// File was already removed (e.g. by coalescing); clean the stale cache entry
|
|
333
|
+
warn('backup metadata not found, removing stale cache entry', { file })
|
|
334
|
+
return null
|
|
335
|
+
}
|
|
336
|
+
throw error
|
|
337
|
+
}
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
const presentMetadata = []
|
|
341
|
+
const missingFiles = []
|
|
342
|
+
for (let i = 0; i < files.length; i++) {
|
|
343
|
+
if (metadataOrNull[i] === null) {
|
|
344
|
+
missingFiles.push({ _filename: files[i] })
|
|
345
|
+
} else {
|
|
346
|
+
presentMetadata.push(metadataOrNull[i])
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const { delta, full, ...others } = groupBy(presentMetadata, 'mode')
|
|
316
351
|
|
|
317
352
|
const unsupportedModes = Object.keys(others)
|
|
318
353
|
if (unsupportedModes.length !== 0) {
|
|
319
354
|
throw new Error('no deleter for backup modes: ' + unsupportedModes.join(', '))
|
|
320
355
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
356
|
+
const promises = []
|
|
357
|
+
if (delta !== undefined) {
|
|
358
|
+
promises.push(this.deleteDeltaVmBackups(delta))
|
|
359
|
+
}
|
|
360
|
+
if (full !== undefined) {
|
|
361
|
+
promises.push(this.deleteFullVmBackups(full))
|
|
362
|
+
}
|
|
363
|
+
if (missingFiles.length) {
|
|
364
|
+
promises.push(this.#removeVmBackupsFromCache(missingFiles))
|
|
365
|
+
}
|
|
366
|
+
await Promise.all(promises)
|
|
326
367
|
|
|
327
368
|
await asyncMap(new Set(files.map(file => dirname(file))), dir =>
|
|
328
369
|
// - don't merge in main process, unused VHDs will be merged in the next backup run
|
|
@@ -229,13 +229,14 @@ export class IncrementalRemoteWriter extends MixinRemoteWriter(AbstractIncrement
|
|
|
229
229
|
Object.entries(deltaExport.disks),
|
|
230
230
|
async ([diskRef, disk]) => {
|
|
231
231
|
const path = `${this._vmBackupDir}/${vhds[diskRef]}`
|
|
232
|
-
|
|
232
|
+
const transferred = await adapter.writeVhd(path, disk, {
|
|
233
233
|
// no checksum for VHDs, because they will be invalidated by
|
|
234
234
|
// merges and chains
|
|
235
235
|
checksum: false,
|
|
236
236
|
validator: tmpPath => checkVhd(handler, tmpPath),
|
|
237
237
|
writeBlockConcurrency: this._config.writeBlockConcurrency,
|
|
238
238
|
})
|
|
239
|
+
size += transferred
|
|
239
240
|
},
|
|
240
241
|
{
|
|
241
242
|
concurrency: settings.diskPerVmConcurrency,
|
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.73.
|
|
11
|
+
"version": "0.73.2",
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": ">=14.18"
|
|
14
14
|
},
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"@vates/nbd-client": "^3.4.0",
|
|
31
31
|
"@vates/parse-duration": "^0.1.1",
|
|
32
32
|
"@vates/task": "^0.7.0",
|
|
33
|
-
"@vates/types": "^1.
|
|
33
|
+
"@vates/types": "^1.26.0",
|
|
34
34
|
"@xen-orchestra/async-map": "^0.1.3",
|
|
35
35
|
"@xen-orchestra/disk-transform": "^1.3.0",
|
|
36
36
|
"@xen-orchestra/fs": "^4.9.0",
|
|
37
37
|
"@xen-orchestra/log": "^0.7.2",
|
|
38
38
|
"@xen-orchestra/qcow2": "^1.3.0",
|
|
39
39
|
"@xen-orchestra/template": "^0.1.1",
|
|
40
|
-
"@xen-orchestra/backup-archive": "^
|
|
40
|
+
"@xen-orchestra/backup-archive": "^1.0.1",
|
|
41
41
|
"app-conf": "^3.0.0",
|
|
42
42
|
"compare-versions": "^6.0.0",
|
|
43
43
|
"d3-time-format": "^4.1.0",
|