fix(vhd-lib): fix VhdDirectory merge on non-S3 remote (#6310)

This commit is contained in:
Florent BEAUCHAMP 2022-06-30 11:40:21 +02:00 committed by GitHub
parent 36b31bb0b3
commit 0c3e42e0b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 20 additions and 6 deletions

View File

@ -27,4 +27,5 @@
<!--packages-start-->
- vhd-lib patch
<!--packages-end-->

View File

@ -117,7 +117,7 @@ exports.VhdDirectory = class VhdDirectory extends VhdAbstract {
}
static async create(handler, path, { flags = 'wx+', compression } = {}) {
await handler.mkdir(path)
await handler.mktree(path)
const vhd = new VhdDirectory(handler, path, { flags, compression })
return {
dispose: () => {},
@ -163,8 +163,10 @@ exports.VhdDirectory = class VhdDirectory extends VhdAbstract {
`Can't write a chunk ${partName} in ${this._path} with read permission`
)
// in case of VhdDirectory, we want to create the file if it does not exists
const flags = this._opts?.flags === 'r+' ? 'w' : this._opts?.flags
const compressed = await this.#compressor.compress(buffer)
return this._handler.outputFile(this.#getChunkPath(partName), compressed, this._opts)
return this._handler.outputFile(this.#getChunkPath(partName), compressed, { flags })
}
// put block in subdirectories to limit impact when doing directory listing

View File

@ -106,6 +106,11 @@ const VhdSynthetic = class VhdSynthetic extends VhdAbstract {
const vhd = this.#getVhdWithBlock(blockId)
return vhd?._getFullBlockPath(blockId)
}
// return true if all the vhds ar an instance of cls
checkVhdsClass(cls) {
return this.#vhds.every(vhd => vhd instanceof cls)
}
}
// add decorated static method

View File

@ -8,7 +8,7 @@ const { Disposable } = require('promise-toolbox')
module.exports = async function chain(parentHandler, parentPath, childHandler, childPath, force = false) {
await Disposable.use(
[openVhd(parentHandler, parentPath), openVhd(childHandler, childPath)],
[openVhd(parentHandler, parentPath), openVhd(childHandler, childPath, { flags: 'r+' })],
async ([parentVhd, childVhd]) => {
await childVhd.readHeaderAndFooter()
const { header, footer } = childVhd

View File

@ -1,10 +1,13 @@
'use strict'
const { createLogger } = require('@xen-orchestra/log')
const { parseVhdStream } = require('./parseVhdStream.js')
const { VhdDirectory } = require('./Vhd/VhdDirectory.js')
const { Disposable } = require('promise-toolbox')
const { asyncEach } = require('@vates/async-each')
const { warn } = createLogger('vhd-lib:createVhdDirectoryFromStream')
const buildVhd = Disposable.wrap(async function* (handler, path, inputStream, { concurrency, compression }) {
const vhd = yield VhdDirectory.create(handler, path, { compression })
await asyncEach(
@ -50,7 +53,7 @@ exports.createVhdDirectoryFromStream = async function createVhdDirectoryFromStre
}
} catch (error) {
// cleanup on error
await handler.rmtree(path)
await handler.rmtree(path).catch(warn)
throw error
}
}

View File

@ -107,14 +107,17 @@ module.exports.mergeVhd = limitConcurrency(2)(async function merge(
checkSecondFooter: mergeState === undefined,
})
let childVhd
const parentIsVhdDirectory = parentVhd instanceof VhdDirectory
let childIsVhdDirectory
if (Array.isArray(childPath)) {
childVhd = yield VhdSynthetic.open(childHandler, childPath)
childIsVhdDirectory = childVhd.checkVhdsClass(VhdDirectory)
} else {
childVhd = yield openVhd(childHandler, childPath)
childIsVhdDirectory = childVhd instanceof VhdDirectory
}
const concurrency = childVhd instanceof VhdDirectory ? 16 : 1
const concurrency = parentIsVhdDirectory && childIsVhdDirectory ? 16 : 1
if (mergeState === undefined) {
// merge should be along a vhd chain
assert.strictEqual(UUID.stringify(childVhd.header.parentUuid), UUID.stringify(parentVhd.footer.uuid))