feat(xo-web/export,import VDI): explicit import/export raw VDI (#6925)
See zammad#15254
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
- [Import/Disk] Enhance clarity for importing ISO files [Forum#7243](https://xcp-ng.org/forum/topic/7243/can-t-import-iso-through-ova-not-a-supported-filetype?_=1685710667937) (PR [#6874](https://github.com/vatesfr/xen-orchestra/pull/6874))
|
||||
- [Import/Disk] Ability to import ISO from a URL (PR [#6924](https://github.com/vatesfr/xen-orchestra/pull/6924))
|
||||
- [Import/export VDI] Ability to export/import disks in RAW format (PR [#6925](https://github.com/vatesfr/xen-orchestra/pull/6925))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
||||
@@ -1241,6 +1241,7 @@ const messages = {
|
||||
removeVdiFromVm: 'Remove VDI from this VM',
|
||||
vhd: 'VHD',
|
||||
vmdk: 'VMDK',
|
||||
raw: 'RAW',
|
||||
|
||||
// ----- VM network tab -----
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ const OPTIONS = [
|
||||
label: _('vmdk'),
|
||||
value: 'vmdk',
|
||||
},
|
||||
{
|
||||
label: _('raw'),
|
||||
value: 'raw',
|
||||
},
|
||||
]
|
||||
export default class ExportVdiModalBody extends BaseComponent {
|
||||
state = {
|
||||
|
||||
@@ -1900,6 +1900,11 @@ export const exportVdi = async vdi => {
|
||||
})
|
||||
|
||||
info(_('startVdiExport'), vdi.id)
|
||||
|
||||
if (format === 'raw') {
|
||||
return window.open(`./rest/v0/vdis/${resolveId(vdi)}.raw`)
|
||||
}
|
||||
|
||||
return _call('disk.exportContent', { id: resolveId(vdi), format }).then(({ $getFrom: url }) => {
|
||||
window.open(`.${url}`)
|
||||
})
|
||||
|
||||
@@ -43,6 +43,12 @@ const getInitialState = () => ({
|
||||
loadingDisks: false,
|
||||
})
|
||||
|
||||
const FILE_GROUP_TYPE = {
|
||||
// .raw is supported for all types of SRs
|
||||
raw: ['.iso', '.raw'],
|
||||
other: ['.vmdk', '.vhd', '.raw'],
|
||||
}
|
||||
|
||||
const DiskImport = decorate([
|
||||
provideState({
|
||||
initialState: getInitialState,
|
||||
@@ -53,14 +59,12 @@ const DiskImport = decorate([
|
||||
map(files, async file => {
|
||||
const { name } = file
|
||||
const extIndex = name.lastIndexOf('.')
|
||||
let type
|
||||
if (
|
||||
extIndex >= 0 &&
|
||||
(type = name.slice(extIndex + 1).toLowerCase()) &&
|
||||
(type === 'vmdk' || type === 'vhd' || type === 'iso')
|
||||
) {
|
||||
const fileExtension = extIndex >= 0 ? name.slice(extIndex).toLowerCase() : undefined
|
||||
const isRaw = FILE_GROUP_TYPE.raw.includes(fileExtension)
|
||||
|
||||
if (isRaw || FILE_GROUP_TYPE.other.includes(fileExtension)) {
|
||||
let vmdkData
|
||||
if (type === 'vmdk') {
|
||||
if (fileExtension === '.vmdk') {
|
||||
const parsed = await readCapacityAndGrainTable(async (start, end) => {
|
||||
/* global FileReader */
|
||||
const reader = new FileReader()
|
||||
@@ -80,7 +84,7 @@ const DiskImport = decorate([
|
||||
file,
|
||||
name,
|
||||
sr: this.state.sr,
|
||||
type,
|
||||
type: isRaw ? 'iso' : fileExtension.slice(1),
|
||||
vmdkData,
|
||||
}
|
||||
}
|
||||
@@ -230,8 +234,8 @@ const DiskImport = decorate([
|
||||
) : (
|
||||
<Dropzone
|
||||
onDrop={effects.handleDrop}
|
||||
message={_('dropDisksFiles', { types: isSrIso ? 'ISO' : ['VHD', 'VMDK'] })}
|
||||
accept={isSrIso ? '.iso' : ['.vhd', '.vmdk']}
|
||||
message={_('dropDisksFiles', { types: isSrIso ? ['ISO', 'RAW'] : ['VHD', 'VMDK', 'RAW'] })}
|
||||
accept={isSrIso ? FILE_GROUP_TYPE.raw : FILE_GROUP_TYPE.other}
|
||||
/>
|
||||
)}
|
||||
{loadingDisks && <Icon icon='loading' />}
|
||||
|
||||
Reference in New Issue
Block a user