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 && }