From 5a933bad933e5bcffb7e56186645ff8c36ed716f Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Wed, 15 Dec 2021 16:36:18 +0100 Subject: [PATCH] fix(vhd-lib/merge): dont fail on invalid state file Fixes zammad#4227 --- CHANGELOG.unreleased.md | 2 ++ packages/vhd-lib/src/merge.js | 31 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 023dd680c..cdabed5fe 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -18,6 +18,7 @@ - [Tables/actions] Fix collapsed actions being clickable despite being disabled (PRĀ [#6023](https://github.com/vatesfr/xen-orchestra/pull/6023)) - [Continuous Replication] Fix `could not find the base VM` - [Backup/Smart mode] Always ignore replicated VMs created by the current job +- [Backup] Fix `Unexpected end of JSON input` during merge step ### Packages to release @@ -36,6 +37,7 @@ > > In case of conflict, the highest (lowest in previous list) `$version` wins. +- vhd-lib patch - @xen-orchestra/backups minor - @xen-orchestra/proxy minor - xo-server minor diff --git a/packages/vhd-lib/src/merge.js b/packages/vhd-lib/src/merge.js index 35aac7115..28ddf00f1 100644 --- a/packages/vhd-lib/src/merge.js +++ b/packages/vhd-lib/src/merge.js @@ -25,12 +25,23 @@ export default limitConcurrency(2)(async function merge( const mergeStatePath = dirname(parentPath) + '/' + '.' + basename(parentPath) + '.merge.json' return await Disposable.use(async function* () { - let mergeState = await parentHandler.readFile(mergeStatePath).catch(error => { - if (error.code !== 'ENOENT') { - throw error - } - // no merge state in case of missing file - }) + let mergeState = await parentHandler + .readFile(mergeStatePath) + .then(content => { + const state = JSON.parse(content) + + // ensure the correct merge will be continued + assert.strictEqual(parentVhd.header.checksum, state.parent.header) + assert.strictEqual(childVhd.header.checksum, state.child.header) + + return state + }) + .catch(error => { + if (error.code !== 'ENOENT') { + warn('problem while checking the merge state', { error }) + } + }) + // during merging, the end footer of the parent can be overwritten by new blocks // we should use it as a way to check vhd health const parentVhd = yield openVhd(parentHandler, parentPath, { @@ -38,13 +49,7 @@ export default limitConcurrency(2)(async function merge( checkSecondFooter: mergeState === undefined, }) const childVhd = yield openVhd(childHandler, childPath) - if (mergeState !== undefined) { - mergeState = JSON.parse(mergeState) - - // ensure the correct merge will be continued - assert.strictEqual(parentVhd.header.checksum, mergeState.parent.header) - assert.strictEqual(childVhd.header.checksum, mergeState.child.header) - } else { + if (mergeState === undefined) { assert.strictEqual(childVhd.header.blockSize, parentVhd.header.blockSize) const parentDiskType = parentVhd.footer.diskType