More code in Xapi.

This commit is contained in:
Julien Fontanet 2015-05-25 15:20:59 +02:00
parent 510897f672
commit b55764db56
2 changed files with 72 additions and 62 deletions

View File

@ -637,7 +637,8 @@ exports.convert = convert
#---------------------------------------------------------------------
snapshot = $coroutine ({vm, name}) ->
return $wait @getXAPI(vm).call 'VM.snapshot', vm.ref, name
snapshot = $wait @getXAPI(vm).snapshotVm(vm.ref, name)
return snapshot.$id
snapshot.params = {
id: { type: 'string' }
@ -768,68 +769,24 @@ exports.revert = revert
#---------------------------------------------------------------------
handleExport = (req, res, {stream, response: upstream}) ->
res.writeHead(
upstream.statusCode,
upstream.statusMessage ? '',
upstream.headers
)
stream.pipe(res)
return
# TODO: integrate in xapi.js
export_ = $coroutine ({vm, compress}) ->
compress ?= true
xapi = @getXAPI vm
# if the VM is running, we can't export it directly
# that's why we export the snapshot
exportRef = if vm.power_state is 'Running'
$debug 'VM is running, creating temp snapshot...'
snapshotRef = $wait xapi.call 'VM.snapshot', vm.ref, vm.name_label
# convert the template to a VM
$wait xapi.call 'VM.set_is_a_template', snapshotRef, false
snapshotRef
else
vm.ref
host = @getObject vm.$container
do (type = host.type) =>
if type is 'pool'
host = @getObject host.master, 'host'
else unless type is 'host'
throw new Error "unexpected type: got #{type} instead of host"
task = $wait xapi._createTask(
'VM export via Xen Orchestra',
'Export VM ' + vm.name_label
)
pFinally(
xapi._watchTask(task)
.then((result) ->
$debug 'export succeeded'
return
)
.catch((error) ->
$debug 'export failed: %j', error
return
)
,
->
if snapshotRef?
$debug 'deleting temp snapshot...'
xapi.deleteVm(snapshotRef, true)
return
)
url = $wait @registerProxyRequest {
method: 'get'
hostname: host.address
pathname: '/export/'
query: {
session_id: xapi.sessionId
ref: exportRef
task_id: task.$ref
use_compression: if compress then 'true' else false
}
}
stream = $wait @getXAPI(vm).exportVm(vm.id, compress ? true)
return {
$getFrom: url
$getFrom: $wait @registerHttpRequest(handleExport, {
stream,
$wait stream.response
})
}
export_.params = {

View File

@ -211,8 +211,8 @@ export default class Xapi extends XapiBase {
// Create a task.
//
// Returns the task object from the Xapi.
async _createTask (name, description = '') {
const ref = await this.call('task.create', name, description)
async _createTask (name = 'untitled task', description = '') {
const ref = await this.call('task.create', `[XO] ${name}`, description)
debug('task created: %s', name)
pFinally(this._watchTask(ref), () => {
@ -393,7 +393,7 @@ export default class Xapi extends XapiBase {
// -----------------------------------------------------------------
async uploadPoolPatch (stream, length) {
const task = await this._createTask('Patch upload from XO')
const task = await this._createTask('Patch upload')
// TODO: Update when xen-api >= 0.5
const poolMaster = this.objects.all[this._refsToUuids[this.pool.master]]
@ -472,6 +472,15 @@ export default class Xapi extends XapiBase {
await this.call('VDI.destroy', vdi.$ref)
}
async _snapshotVm (vm, nameLabel = vm.name_label) {
const ref = await this.call('VM.snapshot', vm.$ref, nameLabel)
// Convert the template to a VM.
await this.call('VM.set_is_a_template', ref, false)
return ref
}
async deleteVm (vmId, deleteDisks = false) {
const vm = this.getObject(vmId)
@ -491,6 +500,50 @@ export default class Xapi extends XapiBase {
await this.call('VM.destroy', vm.$ref)
}
// Returns a stream to the exported VM.
async exportVm (vmId, {compress = true} = {}) {
const vm = this.getObject(vmId)
let host
let snapshotRef
if (isVmRunning(vm)) {
host = this.getObject(vm.resident_on)
snapshotRef = await this._snapshotVm(vm)
} else {
host = this.getObject(this.pool.master)
}
const task = await this._createTask('VM Snapshot', vm.name_label)
pFinally(this._watchTask(task), () => {
if (snapshotRef) {
this.deleteVm(snapshotRef, true)
}
})
const stream = got({
hostname: host.address,
path: '/export/'
}, {
query: {
ref: snapshotRef || vm.$ref,
session_id: this.sessionId,
task_id: task.$ref,
use_compression: compress ? 'true' : 'false'
}
})
stream.response = eventToPromise(stream, 'response')
return stream
}
async snapshotVm (vmId) {
return await this._getOrWaitObject(
await this._snapshotVm(
this.getObject(vmId)
)
)
}
// =================================================================
async _doDockerAction (vmId, action, containerId) {