diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index d76f48c92..3025e9aa0 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -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 diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index b37a0c9ca..4e982652d 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -1241,6 +1241,7 @@ const messages = { removeVdiFromVm: 'Remove VDI from this VM', vhd: 'VHD', vmdk: 'VMDK', + raw: 'RAW', // ----- VM network tab ----- diff --git a/packages/xo-web/src/common/xo/export-vdi-modal/index.js b/packages/xo-web/src/common/xo/export-vdi-modal/index.js index 581c3dc23..f0e2dba2e 100644 --- a/packages/xo-web/src/common/xo/export-vdi-modal/index.js +++ b/packages/xo-web/src/common/xo/export-vdi-modal/index.js @@ -14,6 +14,10 @@ const OPTIONS = [ label: _('vmdk'), value: 'vmdk', }, + { + label: _('raw'), + value: 'raw', + }, ] export default class ExportVdiModalBody extends BaseComponent { state = { diff --git a/packages/xo-web/src/common/xo/index.js b/packages/xo-web/src/common/xo/index.js index bdc72d4e1..92ad20e18 100644 --- a/packages/xo-web/src/common/xo/index.js +++ b/packages/xo-web/src/common/xo/index.js @@ -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}`) }) diff --git a/packages/xo-web/src/xo-app/disk-import/index.js b/packages/xo-web/src/xo-app/disk-import/index.js index 6ad4c4420..ae53755f6 100644 --- a/packages/xo-web/src/xo-app/disk-import/index.js +++ b/packages/xo-web/src/xo-app/disk-import/index.js @@ -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([ ) : ( )} {loadingDisks && }