fix(ova import): drain disk entry completly (#6284)

This commit is contained in:
Florent BEAUCHAMP
2022-06-20 16:09:20 +02:00
committed by GitHub
parent 1741f395dd
commit c483929a0d
4 changed files with 19 additions and 5 deletions

View File

@@ -13,6 +13,7 @@
- [VDI Import] Fix `this._getOrWaitObject is not a function`
- [VM] Attempting to delete a protected VM should display a modal with the error and the ability to bypass it (PR [#6290](https://github.com/vatesfr/xen-orchestra/pull/6290))
- [OVA Import] Fix import stuck after first disk
### Packages to release
@@ -35,5 +36,6 @@
- @xen-orchestra/xapi minor
- xo-remote-parser minor
- xo-server patch
- xo-vmdk-to-vhd patch
<!--packages-end-->

View File

@@ -762,7 +762,8 @@ export default class Xapi extends XapiBase {
stream,
table.grainLogicalAddressList,
table.grainFileOffsetList,
compression[entry.name] === 'gzip'
compression[entry.name] === 'gzip',
entry.size
)
try {
await vdi.$importContent(vhdStream, { format: VDI_FORMAT_VHD })

View File

@@ -16,8 +16,8 @@ export { default as readVmdkGrainTable, readCapacityAndGrainTable } from './vmdk
* @param gzipped
* @returns a stream whose bytes represent a VHD file containing the VMDK data
*/
async function vmdkToVhd(vmdkReadStream, grainLogicalAddressList, grainFileOffsetList, gzipped = false) {
const parser = new VMDKDirectParser(vmdkReadStream, grainLogicalAddressList, grainFileOffsetList, gzipped)
async function vmdkToVhd(vmdkReadStream, grainLogicalAddressList, grainFileOffsetList, gzipped = false, length) {
const parser = new VMDKDirectParser(vmdkReadStream, grainLogicalAddressList, grainFileOffsetList, gzipped, length)
const header = await parser.readHeader()
return createReadableSparseStream(
header.capacitySectors * 512,

View File

@@ -64,7 +64,7 @@ function alignSectors(number) {
}
export default class VMDKDirectParser {
constructor(readStream, grainLogicalAddressList, grainFileOffsetList, gzipped = false) {
constructor(readStream, grainLogicalAddressList, grainFileOffsetList, gzipped = false, length) {
if (gzipped) {
const unzipStream = zlib.createGunzip()
readStream.pipe(unzipStream)
@@ -74,6 +74,7 @@ export default class VMDKDirectParser {
this.grainFileOffsetList = grainFileOffsetList
this.virtualBuffer = new VirtualBuffer(readStream)
this.header = null
this._length = length
}
// I found a VMDK file whose L1 and L2 table did not have a marker, but they were at the top
@@ -195,6 +196,16 @@ export default class VMDKDirectParser {
}
yield { logicalAddressBytes: lba, data: grain }
}
console.log('yielded last VMDK block')
// drain remaining
// stream.resume does not seems to be enough to consume completly the stream
// especially when this stream is part of a tar ( ova) , potentially gzipped
if (this._length !== undefined) {
while (this.virtualBuffer.position < this._length) {
await this.virtualBuffer.readChunk(
Math.min(this._length - this.virtualBuffer.position, 1024 * 1024),
'draining'
)
}
}
}
}