feat(xo-web,xo-server): implement ISO import (#6180)
This commit is contained in:
parent
af85df611c
commit
0706e6f4ff
@ -11,6 +11,7 @@
|
||||
- [Backup] Add _Restore Health Check_: ensure a backup is viable by doing an automatic test restore (requires guest tools in the VM) [#6148](https://github.com/vatesfr/xen-orchestra/pull/6148)
|
||||
- [VM migrate] Allow to choose a private network for VIFs network (PR [#6200](https://github.com/vatesfr/xen-orchestra/pull/6200))
|
||||
- [Proxy] Disable "Deploy proxy" button for source users (PR [#6199](https://github.com/vatesfr/xen-orchestra/pull/6199))
|
||||
- [Import] Feat import `iso` disks (PR [#6180](https://github.com/vatesfr/xen-orchestra/pull/6180))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { pipeline } from 'stream'
|
||||
import { checkFooter, peekFooterFromVhdStream } from 'vhd-lib'
|
||||
import { vmdkToVhd } from 'xo-vmdk-to-vhd'
|
||||
|
||||
import { VDI_FORMAT_VHD } from '../xapi/index.mjs'
|
||||
import { VDI_FORMAT_VHD, VDI_FORMAT_RAW } from '../xapi/index.mjs'
|
||||
|
||||
const log = createLogger('xo:disk')
|
||||
|
||||
@ -182,13 +182,16 @@ async function handleImport(req, res, { type, name, description, vmdkData, srId,
|
||||
})()
|
||||
)
|
||||
} else {
|
||||
let diskFormat = VDI_FORMAT_VHD
|
||||
await Promise.all(promises)
|
||||
part.length = part.byteCount
|
||||
if (type === 'vmdk') {
|
||||
switch (type) {
|
||||
case 'vmdk':
|
||||
vhdStream = await vmdkToVhd(part, vmdkData.grainLogicalAddressList, vmdkData.grainFileOffsetList)
|
||||
size = vmdkData.capacity
|
||||
} else if (type === 'vhd') {
|
||||
vhdStream = part
|
||||
break
|
||||
case 'vhd':
|
||||
{
|
||||
const footer = await peekFooterFromVhdStream(vhdStream)
|
||||
try {
|
||||
checkFooter(footer)
|
||||
@ -197,10 +200,19 @@ async function handleImport(req, res, { type, name, description, vmdkData, srId,
|
||||
throw new JsonRpcError(`Vhd file had an invalid header ${e}`)
|
||||
}
|
||||
}
|
||||
vhdStream = part
|
||||
size = footer.currentSize
|
||||
} else {
|
||||
throw new JsonRpcError(`Unknown disk type, expected "vhd" or "vmdk", got ${type}`)
|
||||
}
|
||||
break
|
||||
case 'iso':
|
||||
diskFormat = VDI_FORMAT_RAW
|
||||
vhdStream = part
|
||||
size = part.byteCount
|
||||
break
|
||||
default:
|
||||
throw new JsonRpcError(`Unknown disk type, expected "iso", "vhd" or "vmdk", got ${type}`)
|
||||
}
|
||||
|
||||
const vdi = await xapi.createVdi({
|
||||
name_description: description,
|
||||
name_label: name,
|
||||
@ -208,7 +220,7 @@ async function handleImport(req, res, { type, name, description, vmdkData, srId,
|
||||
sr: srId,
|
||||
})
|
||||
try {
|
||||
await xapi.importVdiContent(vdi, vhdStream, VDI_FORMAT_VHD)
|
||||
await xapi.importVdiContent(vdi, vhdStream, { format: diskFormat })
|
||||
res.end(format.response(0, vdi.$id))
|
||||
} catch (e) {
|
||||
await vdi.$destroy()
|
||||
|
@ -10,13 +10,15 @@ export default class Dropzone extends Component {
|
||||
onDrop: PropTypes.func,
|
||||
message: PropTypes.node,
|
||||
multiple: PropTypes.bool,
|
||||
accept: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
|
||||
}
|
||||
|
||||
render() {
|
||||
const { onDrop, message, multiple } = this.props
|
||||
const { onDrop, message, multiple, accept } = this.props
|
||||
|
||||
return (
|
||||
<ReactDropzone
|
||||
accept={accept}
|
||||
activeClassName={styles.activeDropzone}
|
||||
className={styles.dropzone}
|
||||
multiple={multiple}
|
||||
|
@ -3819,7 +3819,7 @@ export default {
|
||||
diskImportSuccess: 'Importazione del disco riuscita',
|
||||
|
||||
// Original text: 'Drop VMDK or VHD files here to import disks.'
|
||||
dropDisksFiles: 'Rilascia qui i file VMDK o VHD per importare i dischi.',
|
||||
dropDisksFiles: 'Rilascia qui i file ISO, VMDK o VHD per importare i dischi.',
|
||||
|
||||
// Original text: 'To SR'
|
||||
importToSr: 'A SR',
|
||||
|
@ -1584,7 +1584,7 @@ const messages = {
|
||||
// ---- Disk import ---
|
||||
diskImportFailed: 'Disk import failed',
|
||||
diskImportSuccess: 'Disk import success',
|
||||
dropDisksFiles: 'Drop VMDK or VHD files here to import disks.',
|
||||
dropDisksFiles: 'Drop ISO, VMDK or VHD files here to import disks.',
|
||||
importToSr: 'To SR',
|
||||
|
||||
// ---- Tasks ---
|
||||
|
@ -54,6 +54,7 @@ export const XEN_VIDEORAM_VALUES = [1, 2, 4, 8, 16]
|
||||
// ===================================================================
|
||||
|
||||
export const isSrWritable = sr => sr && sr.content_type !== 'iso' && sr.size > 0
|
||||
export const isSrWritableOrIso = sr => sr && sr.size > 0
|
||||
export const isSrShared = sr => sr && sr.shared
|
||||
export const isVmRunning = vm => vm && vm.power_state === 'Running'
|
||||
|
||||
|
@ -17,6 +17,7 @@ import { InputCol, LabelCol, Row } from 'form-grid'
|
||||
import { map } from 'lodash'
|
||||
import { readCapacityAndGrainTable } from 'xo-vmdk-to-vhd'
|
||||
import { SelectSr } from 'select-objects'
|
||||
import { isSrWritableOrIso } from '../../common/xo'
|
||||
|
||||
const getInitialState = () => ({
|
||||
disks: [],
|
||||
@ -40,7 +41,7 @@ const DiskImport = decorate([
|
||||
if (
|
||||
extIndex >= 0 &&
|
||||
(type = name.slice(extIndex + 1).toLowerCase()) &&
|
||||
(type === 'vmdk' || type === 'vhd')
|
||||
(type === 'vmdk' || type === 'vhd' || type === 'iso')
|
||||
) {
|
||||
let vmdkData
|
||||
if (type === 'vmdk') {
|
||||
@ -108,12 +109,16 @@ const DiskImport = decorate([
|
||||
<Row>
|
||||
<LabelCol>{_('importToSr')}</LabelCol>
|
||||
<InputCol>
|
||||
<SelectSr onChange={effects.onChangeSr} required value={sr} />
|
||||
<SelectSr onChange={effects.onChangeSr} required value={sr} predicate={isSrWritableOrIso} />
|
||||
</InputCol>
|
||||
</Row>
|
||||
{sr !== undefined && (
|
||||
<div>
|
||||
<Dropzone onDrop={effects.handleDrop} message={_('dropDisksFiles')} />
|
||||
<Dropzone
|
||||
onDrop={effects.handleDrop}
|
||||
message={_('dropDisksFiles')}
|
||||
accept={sr.content_type === 'iso' ? '.iso' : ['.vhd', '.vmdk']}
|
||||
/>
|
||||
{loadingDisks && <Icon icon='loading' />}
|
||||
{disks.length > 0 && (
|
||||
<div>
|
||||
|
Loading…
Reference in New Issue
Block a user