feat(xo-web/vm-import): don't block the UI when dropping a big OVA file (#4018)

This commit is contained in:
Nicolas Raynaud 2019-04-04 01:59:44 -07:00 committed by Pierre Donias
parent 95bcf0c080
commit 975de1954e
4 changed files with 18 additions and 12 deletions

View File

@ -4,6 +4,7 @@
- [Settings/remotes] Expose mount options field for SMB [#4063](https://github.com/vatesfr/xen-orchestra/issues/4063) (PR [#4067](https://github.com/vatesfr/xen-orchestra/pull/4067)) - [Settings/remotes] Expose mount options field for SMB [#4063](https://github.com/vatesfr/xen-orchestra/issues/4063) (PR [#4067](https://github.com/vatesfr/xen-orchestra/pull/4067))
- [Backup/Schedule] Add warning regarding DST when you add a schedule [#4042](https://github.com/vatesfr/xen-orchestra/issues/4042) (PR [#4056](https://github.com/vatesfr/xen-orchestra/pull/4056)) - [Backup/Schedule] Add warning regarding DST when you add a schedule [#4042](https://github.com/vatesfr/xen-orchestra/issues/4042) (PR [#4056](https://github.com/vatesfr/xen-orchestra/pull/4056))
- [Import] Avoid blocking the UI when dropping a big OVA file on the UI (PR [#4018](https://github.com/vatesfr/xen-orchestra/pull/4018))
### Bug fixes ### Bug fixes
@ -11,6 +12,7 @@
### Released packages ### Released packages
- xo-vmdk-to-vhd v0.1.7
- vhd-lib v0.6.1 - vhd-lib v0.6.1
- xo-server v5.39.0 - xo-server v5.39.0
- xo-web v5.39.0 - xo-web v5.39.0

View File

@ -12,10 +12,10 @@ const GRAIN_ADDRESS_OFFSET = 56
*/ */
export default async function readVmdkGrainTable(fileAccessor) { export default async function readVmdkGrainTable(fileAccessor) {
const getLongLong = (buffer, offset, name) => { const getLongLong = (buffer, offset, name) => {
if (buffer.length < offset + 8) { if (buffer.byteLength < offset + 8) {
throw new Error( throw new Error(
`buffer ${name} is too short, expecting ${offset + 8} minimum, got ${ `buffer ${name} is too short, expecting ${offset + 8} minimum, got ${
buffer.length buffer.byteLength
}` }`
) )
} }
@ -61,11 +61,12 @@ export default async function readVmdkGrainTable(fileAccessor) {
const grainTablePhysicalSize = numGTEsPerGT * 4 const grainTablePhysicalSize = numGTEsPerGT * 4
const grainDirectoryEntries = Math.ceil(grainCount / numGTEsPerGT) const grainDirectoryEntries = Math.ceil(grainCount / numGTEsPerGT)
const grainDirectoryPhysicalSize = grainDirectoryEntries * 4 const grainDirectoryPhysicalSize = grainDirectoryEntries * 4
const grainDirBuffer = await fileAccessor( const grainDir = new Uint32Array(
grainDirPosBytes, await fileAccessor(
grainDirPosBytes + grainDirectoryPhysicalSize grainDirPosBytes,
grainDirPosBytes + grainDirectoryPhysicalSize
)
) )
const grainDir = new Uint32Array(grainDirBuffer)
const cachedGrainTables = [] const cachedGrainTables = []
for (let i = 0; i < grainDirectoryEntries; i++) { for (let i = 0; i < grainDirectoryEntries; i++) {
const grainTableAddr = grainDir[i] * SECTOR_SIZE const grainTableAddr = grainDir[i] * SECTOR_SIZE

View File

@ -1373,11 +1373,15 @@ export const fetchVmStats = (vm, granularity) =>
export const getVmsHaValues = () => _call('vm.getHaValues') export const getVmsHaValues = () => _call('vm.getHaValues')
export const importVm = (file, type = 'xva', data = undefined, sr) => { export const importVm = async (file, type = 'xva', data = undefined, sr) => {
const { name } = file const { name } = file
info(_('startVmImport'), name) info(_('startVmImport'), name)
if (data !== undefined && data.tables !== undefined) {
for (const k in data.tables) {
data.tables[k] = await data.tables[k]
}
}
return _call('vm.import', { type, data, sr: resolveId(sr) }).then( return _call('vm.import', { type, data, sr: resolveId(sr) }).then(
({ $sendTo }) => ({ $sendTo }) =>
post($sendTo, file) post($sendTo, file)

View File

@ -217,7 +217,8 @@ async function parseTarFile(file) {
const fileSlice = file.slice(offset, offset + header.fileSize) const fileSlice = file.slice(offset, offset + header.fileSize)
const readFile = async (start, end) => const readFile = async (start, end) =>
readFileFragment(fileSlice, start, end) readFileFragment(fileSlice, start, end)
data.tables[header.fileName] = await readVmdkGrainTable(readFile) // storing the promise, not the value
data.tables[header.fileName] = readVmdkGrainTable(readFile)
} }
} }
offset += Math.ceil(header.fileSize / 512) * 512 offset += Math.ceil(header.fileSize / 512) * 512
@ -228,6 +229,4 @@ async function parseTarFile(file) {
} }
} }
const parseOvaFile = async file => parseTarFile(file) export { parseTarFile as default }
export { parseOvaFile as default }