fix(proxy/backup.importVmBackup): only dispose resources at the end (#7152)

Fixes #7052

Fixes zammad#17383

When a stream is returned, the handler immediately returned a stream which disposed the resource.

Due to the disposable having a 5 mins debounce delay, the problem was only apparent after 5 mins.
This commit is contained in:
Julien Fontanet
2023-11-06 10:30:34 +01:00
committed by GitHub
parent 457fec0bc8
commit c9dbcf1384
2 changed files with 44 additions and 30 deletions
+42 -30
View File
@@ -5,7 +5,6 @@ import { compose } from '@vates/compose'
import { createLogger } from '@xen-orchestra/log'
import { decorateMethodsWith } from '@vates/decorate-with'
import { deduped } from '@vates/disposable/deduped.js'
import { defer } from 'golike-defer'
import { DurablePartition } from '@xen-orchestra/backups/DurablePartition.mjs'
import { execFile } from 'child_process'
import { formatVmBackups } from '@xen-orchestra/backups/formatVmBackups.mjs'
@@ -23,16 +22,18 @@ const noop = Function.prototype
const { warn } = createLogger('xo:proxy:backups')
const runWithLogs = (runner, args) =>
const runWithLogs = (runner, args, onEnd) =>
new Readable({
objectMode: true,
read() {
this._read = noop
runner(args, log => this.push(log)).then(
() => this.push(null),
error => this.emit('error', error)
)
runner(args, log => this.push(log))
.then(
() => this.push(null),
error => this.emit('error', error)
)
.then(onEnd)
},
})[Symbol.asyncIterator]()
@@ -190,30 +191,41 @@ export default class Backups {
},
],
importVmBackup: [
defer(($defer, { backupId, remote, srUuid, settings, streamLogs = false, xapi: xapiOpts }) =>
Disposable.use(this.getAdapter(remote), this.getXapi(xapiOpts), async (adapter, xapi) => {
const metadata = await adapter.readVmBackupMetadata(backupId)
const run = () => new ImportVmBackup({ adapter, metadata, settings, srUuid, xapi }).run()
return streamLogs
? runWithLogs(
async (args, onLog) =>
Task.run(
{
data: {
backupId,
jobId: metadata.jobId,
srId: srUuid,
time: metadata.timestamp,
},
name: 'restore',
onLog,
},
run
).catch(() => {}) // errors are handled by logs
)
: run()
})
),
async ({ backupId, remote, srUuid, settings, streamLogs = false, xapi: xapiOpts }) => {
const {
dispose,
value: [adapter, xapi],
} = await Disposable.all([this.getAdapter(remote), this.getXapi(xapiOpts)])
const metadata = await adapter.readVmBackupMetadata(backupId)
const run = () => new ImportVmBackup({ adapter, metadata, settings, srUuid, xapi }).run()
if (streamLogs) {
return runWithLogs(
async (args, onLog) =>
Task.run(
{
data: {
backupId,
jobId: metadata.jobId,
srId: srUuid,
time: metadata.timestamp,
},
name: 'restore',
onLog,
},
run
).catch(() => {}), // errors are handled by logs,
dispose
)
}
try {
return await run()
} finally {
await dispose()
}
},
{
description: 'create a new VM from a backup',
params: {
+2
View File
@@ -13,6 +13,7 @@
- [Netbox] Fix VMs' `site` property being unnecessarily updated on some versions of Netbox (PR [#7145](https://github.com/vatesfr/xen-orchestra/pull/7145))
- [Netbox] Fix "400 Bad Request" error (PR [#7153](https://github.com/vatesfr/xen-orchestra/pull/7153))
- [Backup/Restore] Fix timeout after 5 minutes [#7052](https://github.com/vatesfr/xen-orchestra/issues/7052)
### Packages to release
@@ -30,6 +31,7 @@
<!--packages-start-->
- @xen-orchestra/proxy patch
- xo-server-netbox patch
<!--packages-end-->