Skip to content

Commit

Permalink
feat(xo-server): import multiple from ESXi (#6708)
Browse files Browse the repository at this point in the history
  • Loading branch information
fbeauchamp committed Mar 28, 2023
1 parent 34f6be8 commit 53e0f17
Showing 1 changed file with 103 additions and 0 deletions.
103 changes: 103 additions & 0 deletions packages/xo-server/src/api/vm.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as multiparty from 'multiparty'
import assignWith from 'lodash/assignWith.js'
import { asyncEach } from '@vates/async-each'
import asyncMapSettled from '@xen-orchestra/async-map/legacy.js'
import { Task } from '@xen-orchestra/mixins/Tasks.mjs'
import concat from 'lodash/concat.js'
import getStream from 'get-stream'
import hrp from 'http-request-plus'
Expand Down Expand Up @@ -1327,6 +1329,107 @@ importFromEsxi.params = {
vm: { type: 'string' },
}

/**
* on success: returns an object, the keys are the esxi id, and the values are the created vm uuid
* On error: throw an error. If stopOnError is false, continue when an error occurs, throws an error at the end with a 'succeeded'
* property listing the VM properly imported and a 'errors' property with all the errors collected
*/
export async function importMultipleFromEsxi({
concurrency,
host,
network,
password,
sr,
sslVerify,
stopSource,
stopOnError,
thin,
user,
vms,
}) {
const task = await this.tasks.create({ name: `importing vms ${vms.join(',')}` })
let done = 0
return task.run(async () => {
Task.set('total', vms.length)
Task.set('done', 0)
Task.set('progress', 0)
const result = {}
try {
await asyncEach(
vms,
async vm => {
await new Task({ name: `importing vm ${vm}` }).run(async () => {
try {
const vmUuid = await this.migrationfromEsxi({
host,
user,
password,
sslVerify,
thin,
vm,
sr,
network,
stopSource,
})
result[vm] = vmUuid
} finally {
done++
Task.set('done', done)
Task.set('progress', Math.round((done * 100) / vms.length))
}
})
},
{
concurrency,
stopOnError,
}
)
return result
} catch (error) {
// if stopOnError is true :
// error is the original error , `suceeded` property {[esxi vm id]: xen vm id} contains only the VMs migrated before the error.
// VMs started before the error and finished migration after won't be in
// else
// error is an AggregatedError with an `errors` property containing all the errors
// and a `succeeded` property {[esxi vm id]: xen vm id} containing all the migrated VMs
error.succeeded = result
throw error
}
})
}

importMultipleFromEsxi.params = {
concurrency: {
type: 'number',
optional: true,
default: 2,
description: 'number of VM imports in parallel (the disks are imported in parallel in each VM import)',
},
host: { type: 'string' },
network: { type: 'string' },
password: { type: 'string' },
sr: { type: 'string' },
sslVerify: { type: 'boolean', optional: true, default: true },
stopSource: { type: 'boolean', optional: true, default: false },
stopOnError: {
type: 'boolean',
optional: true,
default: false,
description: 'should the import stop on the first error , default true . Warning, change the response format',
},
thin: { type: 'boolean', optional: true, default: false },
user: { type: 'string' },
vms: {
items: {
type: 'string',
description: 'VM id to be imported, if used from cli use this syntax : vms=json:\'["2","9","18"]\'',
},
minItems: 1,
type: 'array',
uniqueItems: true,
},
}

// -------------------------------------------------------------------

// FIXME: if position is used, all other disks after this position
Expand Down

0 comments on commit 53e0f17

Please sign in to comment.