fix(vm/import): make the UI respond instantly to .ova file drop (#5274)

When dropping a file on the import zone, the UI didn't acknowledge the file until the vmdk table were parsed.

Now the UI parses the XML instantly, displays it on the UI, and start parsing the tables in the background. If the user clicks the "import" button, the system will finish parsing the tables and start the upload in when fell swoop. Hiding the parsing time in the upload time.
This commit is contained in:
Nicolas Raynaud 2020-09-27 19:45:32 +02:00 committed by GitHub
parent fdbe84cb1e
commit f3527a44d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 11 deletions

View File

@ -20,6 +20,7 @@
- [Import VMDK] Fix `No position specified for vmdisk1` error (PR [#5255](https://github.com/vatesfr/xen-orchestra/pull/5255)) - [Import VMDK] Fix `No position specified for vmdisk1` error (PR [#5255](https://github.com/vatesfr/xen-orchestra/pull/5255))
- [API] Fix `this.removeSubjectFromResourceSet is not a function` error on calling `resourceSet.removeSubject` via `xo-cli` [#5265](https://github.com/vatesfr/xen-orchestra/issues/5265) (PR [#5266](https://github.com/vatesfr/xen-orchestra/pull/5266)) - [API] Fix `this.removeSubjectFromResourceSet is not a function` error on calling `resourceSet.removeSubject` via `xo-cli` [#5265](https://github.com/vatesfr/xen-orchestra/issues/5265) (PR [#5266](https://github.com/vatesfr/xen-orchestra/pull/5266))
- [Import OVA] Fix frozen UI when dropping a big OVA on the page (PR [#5274](https://github.com/vatesfr/xen-orchestra/pull/5274))
### Packages to release ### Packages to release

View File

@ -79,6 +79,9 @@ test('An ova file is parsed correctly', async () => {
return Buffer.from(buffer).toString(encoder) return Buffer.from(buffer).toString(encoder)
} }
) )
for (const fileName in data.tables) {
data.tables[fileName] = await data.tables[fileName]
}
expect(data).toEqual(expectedResult) expect(data).toEqual(expectedResult)
}) })

View File

@ -5,6 +5,7 @@ import sum from 'lodash/sum'
import xml2js, { processors } from 'xml2js' import xml2js, { processors } from 'xml2js'
import { readVmdkGrainTable } from '.' import { readVmdkGrainTable } from '.'
import { suppressUnhandledRejection } from './util'
/******** /********
* *
@ -327,7 +328,9 @@ export async function parseOVAFile(
const fileSlice = parsableFile.slice(offset, offset + header.fileSize) const fileSlice = parsableFile.slice(offset, offset + header.fileSize)
const readFile = async (start, end) => const readFile = async (start, end) =>
fileSlice.slice(start, end).read() fileSlice.slice(start, end).read()
data.tables[header.fileName] = await readVmdkGrainTable(readFile) data.tables[header.fileName] = suppressUnhandledRejection(
readVmdkGrainTable(readFile)
)
} }
} }
if (!skipVmdk && header.fileName.toLowerCase().endsWith('.vmdk.gz')) { if (!skipVmdk && header.fileName.toLowerCase().endsWith('.vmdk.gz')) {
@ -342,7 +345,9 @@ export async function parseOVAFile(
return parseGzipFromEnd(start, end, fileSlice, header) return parseGzipFromEnd(start, end, fileSlice, header)
} }
} }
data.tables[header.fileName] = await readVmdkGrainTable(readFile) data.tables[header.fileName] = suppressUnhandledRejection(
readVmdkGrainTable(readFile)
)
} }
offset += Math.ceil(header.fileSize / 512) * 512 offset += Math.ceil(header.fileSize / 512) * 512
} }

View File

@ -0,0 +1,4 @@
export function suppressUnhandledRejection(p) {
p.catch(Function.prototype)
return p
}

View File

@ -1,3 +1,5 @@
import { suppressUnhandledRejection } from './util'
const SECTOR_SIZE = 512 const SECTOR_SIZE = 512
const HEADER_SIZE = 512 const HEADER_SIZE = 512
const FOOTER_POSITION = -1024 const FOOTER_POSITION = -1024
@ -138,5 +140,8 @@ export async function readCapacityAndGrainTable(fileAccessor) {
return { grainLogicalAddressList: fragmentAddressList, grainFileOffsetList } return { grainLogicalAddressList: fragmentAddressList, grainFileOffsetList }
} }
return { tablePromise: readTable(), capacityBytes: capacity } return {
tablePromise: suppressUnhandledRejection(readTable()),
capacityBytes: capacity,
}
} }

View File

@ -21,14 +21,9 @@ class BrowserParsableFile extends ParsableFile {
} }
async function parseTarFile(file) { async function parseTarFile(file) {
document.body.style.cursor = 'wait' return await parseOVAFile(new BrowserParsableFile(file), (buffer, encoding) =>
try {
return parseOVAFile(new BrowserParsableFile(file), (buffer, encoding) =>
new TextDecoder(encoding).decode(buffer) new TextDecoder(encoding).decode(buffer)
) )
} finally {
document.body.style.cursor = null
}
} }
export { parseTarFile as default } export { parseTarFile as default }