fix(@xen-orchestra/backups/isValidXva): move as RemoteAdapter method (#5741)

This commit is contained in:
badrAZ
2021-04-21 16:27:13 +02:00
committed by GitHub
parent e0d6b501c7
commit c262dd06e6
4 changed files with 21 additions and 22 deletions

View File

@@ -16,6 +16,7 @@ const { BACKUP_DIR } = require('./_getVmBackupDir')
const { cleanVm } = require('./_cleanVm')
const { getTmpDir } = require('./_getTmpDir')
const { isMetadataFile, isVhdFile } = require('./_backupType')
const { isValidXva } = require('./_isValidXva')
const { listPartitions, LVM_PARTITION_TYPE } = require('./_listPartitions')
const { lvs, pvs } = require('./_lvm')
@@ -551,8 +552,11 @@ class RemoteAdapter {
}
}
RemoteAdapter.prototype.cleanVm = function (vmDir) {
return Disposable.use(this._handler.lock(vmDir), () => cleanVm.apply(this, arguments))
}
Object.assign(RemoteAdapter.prototype, {
cleanVm(vmDir) {
return Disposable.use(this._handler.lock(vmDir), () => cleanVm.apply(this, arguments))
},
isValidXva,
})
exports.RemoteAdapter = RemoteAdapter

View File

@@ -5,7 +5,6 @@ const { default: Vhd, mergeVhd } = require('vhd-lib')
const { dirname, resolve } = require('path')
const { DISK_TYPE_DIFFERENCING } = require('vhd-lib/dist/_constants')
const { isMetadataFile, isVhdFile, isXvaFile, isXvaSumFile } = require('./_backupType')
const { isValidXva } = require('./isValidXva')
// chain is an array of VHDs from child to parent
//
@@ -184,7 +183,7 @@ exports.cleanVm = async function cleanVm(vmDir, { remove, merge, onLog = noop })
await asyncMap(xvas, async path => {
// check is not good enough to delete the file, the best we can do is report
// it
if (!(await isValidXva(path))) {
if (!(await this.isValidXva(path))) {
onLog(`the XVA with path ${path} is potentially broken`)
}
})

View File

@@ -1,10 +1,10 @@
const assert = require('assert')
const fs = require('fs-extra')
const isGzipFile = async fd => {
const isGzipFile = async (handler, fd) => {
// https://tools.ietf.org/html/rfc1952.html#page-5
const magicNumber = Buffer.allocUnsafe(2)
assert.strictEqual((await fs.read(fd, magicNumber, 0, magicNumber.length, 0)).bytesRead, magicNumber.length)
assert.strictEqual((await handler.read(fd, magicNumber, 0)).bytesRead, magicNumber.length)
return magicNumber[0] === 31 && magicNumber[1] === 139
}
@@ -21,32 +21,33 @@ const isGzipFile = async fd => {
// /^Ref:\d+/\d+\.checksum$/ and then validating the tar structure from it
//
// https://github.com/npm/node-tar/issues/234#issuecomment-538190295
const isValidTar = async (size, fd) => {
const isValidTar = async (handler, size, fd) => {
if (size <= 1024 || size % 512 !== 0) {
return false
}
const buf = Buffer.allocUnsafe(1024)
assert.strictEqual((await fs.read(fd, buf, 0, buf.length, size - buf.length)).bytesRead, buf.length)
assert.strictEqual((await handler.read(fd, buf, size - buf.length)).bytesRead, buf.length)
return buf.every(_ => _ === 0)
}
// TODO: find an heuristic for compressed files
const isValidXva = async path => {
async function isValidXva(path) {
const handler = this._handler
try {
const fd = await fs.open(path, 'r')
const fd = await handler.openFile(path, 'r')
try {
const { size } = await fs.fstat(fd)
const size = await handler.getSize(fd)
if (size < 20) {
// neither a valid gzip not tar
return false
}
return (await isGzipFile(fd))
return (await isGzipFile(handler, fd))
? true // gzip files cannot be validated at this time
: await isValidTar(size, fd)
: await isValidTar(handler, size, fd)
} finally {
fs.close(fd).catch(noop)
handler.closeFile(fd).catch(noop)
}
} catch (error) {
// never throw, log and report as valid to avoid side effects

View File

@@ -1,7 +1,6 @@
const { formatFilenameDate } = require('../_filenameDate')
const { getOldEntries } = require('../_getOldEntries')
const { getVmBackupDir } = require('../_getVmBackupDir')
const { isValidXva } = require('../isValidXva')
const { Task } = require('../Task')
const { MixinBackupWriter } = require('./_MixinBackupWriter')
@@ -68,11 +67,7 @@ exports.FullBackupWriter = class FullBackupWriter extends MixinBackupWriter(Abst
await Task.run({ name: 'transfer' }, async () => {
await adapter.outputStream(dataFilename, stream, {
validator: tmpPath => {
if (handler._getFilePath !== undefined) {
return isValidXva(handler._getFilePath('/' + tmpPath))
}
},
validator: tmpPath => adapter.isValidXva(tmpPath),
})
return { size: sizeContainer.size }
})