fix(xo-vmdk-to-vhd): improve compatibilty of ova with disk bigger than 8.2GB (#7183)

following #7047, from https://xcp-ng.org/forum/topic/7946/ova-export-not-functional?_=1700051758755

ova exported from xo with more than 8.2G data per disk can't be imported in virtual box 

tar-stream@3 pack and entry are now streams
This commit is contained in:
Florent BEAUCHAMP 2023-11-15 16:23:33 +01:00 committed by GitHub
parent 511908bb7d
commit 9ca3f3df26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 20 deletions

View File

@ -15,6 +15,7 @@
- [Backup/Restore] In case of snapshot with memory, create the suspend VDI on the correct SR instead of the default one
- [Import/ESXi] Handle `Cannot read properties of undefined (reading 'perDatastoreUsage')` error when importing VM without storage (PR [#7168](https://github.com/vatesfr/xen-orchestra/pull/7168))
- [Export/OVA] Handle export with resulting disk larger than 8.2GB (PR [#7183](https://github.com/vatesfr/xen-orchestra/pull/7183))
### Packages to release
@ -36,6 +37,7 @@
- @xen-orchestra/backups patch
- @xen-orchestra/vmware-explorer patch
- xo-server-netbox minor
- xo-vmdk-to-vhd patch
- xo-web patch
<!--packages-end-->

View File

@ -18,14 +18,14 @@
"preferGlobal": false,
"main": "dist/",
"engines": {
"node": ">=12"
"node": ">=12.3"
},
"dependencies": {
"child-process-promise": "^2.0.3",
"lodash": "^4.17.15",
"pako": "^2.0.4",
"promise-toolbox": "^0.21.0",
"tar-stream": "^2.2.0",
"tar-stream": "^3.1.6",
"vhd-lib": "^4.6.1",
"xml2js": "^0.4.23"
},

View File

@ -1,12 +1,13 @@
import tar from 'tar-stream'
import { computeVmdkLength, vhdToVMDKIterator } from '.'
import { fromCallback } from 'promise-toolbox'
import { pipeline } from 'stream'
// WE MIGHT WANT TO HAVE A LOOK HERE: https://opennodecloud.com/howto/2013/12/25/howto-ON-ovf-reference.html
/**
*
* @param writeStream
* @param outStream
* @param vmName
* @param vmDescription
* @param disks [{name, fileName, capacityMB, getStream}]
@ -16,19 +17,13 @@ import { fromCallback } from 'promise-toolbox'
* @returns readStream
*/
export async function writeOvaOn(
writeStream,
outStream,
{ vmName, vmDescription = '', disks = [], firmware = 'bios', nics = [], vmMemoryMB = 64, cpuCount = 1 }
) {
const ovf = createOvf(vmName, vmDescription, disks, nics, vmMemoryMB, cpuCount, firmware)
const pack = tar.pack()
const pipe = pack.pipe(writeStream)
await fromCallback.call(pack, pack.entry, { name: `metadata.ovf` }, Buffer.from(ovf, 'utf8'))
async function writeDisk(entry, blockIterator) {
for await (const block of blockIterator) {
await fromCallback.call(entry, entry.write, block)
}
}
const tarStream = tar.pack()
pipeline(tarStream, outStream, () => {})
await fromCallback.call(tarStream, tarStream.entry, { name: `metadata.ovf` }, Buffer.from(ovf, 'utf8'))
// https://github.com/mafintosh/tar-stream/issues/24#issuecomment-558358268
async function pushDisk(disk) {
@ -38,23 +33,20 @@ export async function writeOvaOn(
}
disk.fileSize = size
return new Promise((resolve, reject) => {
const entry = pack.entry({ name: `${disk.name}.vmdk`, size }, err => {
const entryWriteStream = tarStream.entry({ name: `${disk.name}.vmdk`, size, type: 'file' }, err => {
if (err == null) {
return resolve()
} else return reject(err)
})
return writeDisk(entry, iterator).then(
() => entry.end(),
e => reject(e)
)
pipeline(iterator, entryWriteStream, () => {})
})
}
for (const disk of disks) {
await pushDisk(disk)
}
pack.finalize()
return pipe
tarStream.finalize()
return outStream
}
function createDiskSections(disks) {