No longer use fibers.
This commit is contained in:
parent
934949c514
commit
5cd22b41d6
@ -42,6 +42,10 @@ gulp.task(function buildCoffee () {
|
||||
.pipe(coffee({
|
||||
bare: true
|
||||
}))
|
||||
|
||||
// Necessary to correctly compile generators.
|
||||
.pipe(babel())
|
||||
|
||||
.pipe(sourceMaps.write('.'))
|
||||
.pipe(gulp.dest(DIST_DIR))
|
||||
})
|
||||
|
@ -37,7 +37,6 @@
|
||||
"debug": "^2.1.3",
|
||||
"event-to-promise": "^0.3.2",
|
||||
"exec-promise": "^0.5.1",
|
||||
"fibers": "~1.0.5",
|
||||
"fs-promise": "^0.3.1",
|
||||
"got": "^3.2.0",
|
||||
"graceful-fs": "^3.0.6",
|
||||
|
@ -1,12 +1,11 @@
|
||||
import {coroutine, wait} from '../fibers-utils'
|
||||
import {parseSize} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const create = coroutine(function ({name, size, sr}) {
|
||||
export async function create ({name, size, sr}) {
|
||||
const xapi = this.getXAPI(sr)
|
||||
|
||||
const ref = wait(xapi.call('VDI.create', {
|
||||
const ref = await xapi.call('VDI.create', {
|
||||
name_label: name,
|
||||
other_config: {},
|
||||
read_only: false,
|
||||
@ -14,11 +13,11 @@ export const create = coroutine(function ({name, size, sr}) {
|
||||
SR: sr.ref,
|
||||
type: 'user',
|
||||
virtual_size: String(parseSize(size))
|
||||
}))
|
||||
|
||||
return wait(xapi.call('VDI.get_record', ref)).uuid
|
||||
})
|
||||
|
||||
return (await xapi.call('VDI.get_record', ref)).uuid
|
||||
}
|
||||
|
||||
create.description = 'create a new disk on a SR'
|
||||
|
||||
create.params = {
|
||||
|
@ -1,12 +1,12 @@
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
$debug = (require 'debug') 'xo:api:vm'
|
||||
$request = require('bluebird').promisify(require('request'))
|
||||
{parseXml} = require '../utils'
|
||||
$forEach = require 'lodash.foreach'
|
||||
$find = require 'lodash.find'
|
||||
$findIndex = require 'lodash.findindex'
|
||||
startsWith = require 'lodash.startswith'
|
||||
$forEach = require 'lodash.foreach'
|
||||
$request = require('bluebird').promisify(require('request'))
|
||||
endsWith = require 'lodash.endswith'
|
||||
startsWith = require 'lodash.startswith'
|
||||
{coroutine: $coroutine} = require 'bluebird'
|
||||
{parseXml} = require '../utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
@ -21,7 +21,7 @@ set = $coroutine (params) ->
|
||||
}
|
||||
continue unless param of params
|
||||
|
||||
$wait xapi.call "host.set_#{field}", host.ref, params[param]
|
||||
yield xapi.call "host.set_#{field}", host.ref, params[param]
|
||||
|
||||
return true
|
||||
|
||||
@ -48,8 +48,8 @@ exports.set = set
|
||||
restart = $coroutine ({host}) ->
|
||||
xapi = @getXAPI host
|
||||
|
||||
$wait xapi.call 'host.disable', host.ref
|
||||
$wait xapi.call 'host.reboot', host.ref
|
||||
yield xapi.call 'host.disable', host.ref
|
||||
yield xapi.call 'host.reboot', host.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -68,7 +68,7 @@ exports.restart = restart
|
||||
restartAgent = $coroutine ({host}) ->
|
||||
xapi = @getXAPI host
|
||||
|
||||
$wait xapi.call 'host.restart_agent', host.ref
|
||||
yield xapi.call 'host.restart_agent', host.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -88,7 +88,7 @@ exports.restart_agent = restartAgent
|
||||
start = $coroutine ({host}) ->
|
||||
xapi = @getXAPI host
|
||||
|
||||
$wait xapi.call 'host.power_on', host.ref
|
||||
yield xapi.call 'host.power_on', host.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -107,8 +107,8 @@ exports.start = start
|
||||
stop = $coroutine ({host}) ->
|
||||
xapi = @getXAPI host
|
||||
|
||||
$wait xapi.call 'host.disable', host.ref
|
||||
$wait xapi.call 'host.shutdown', host.ref
|
||||
yield xapi.call 'host.disable', host.ref
|
||||
yield xapi.call 'host.shutdown', host.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -127,7 +127,7 @@ exports.stop = stop
|
||||
detach = $coroutine ({host}) ->
|
||||
xapi = @getXAPI host
|
||||
|
||||
$wait xapi.call 'pool.eject', host.ref
|
||||
yield xapi.call 'pool.eject', host.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -146,7 +146,7 @@ exports.detach = detach
|
||||
enable = $coroutine ({host}) ->
|
||||
xapi = @getXAPI host
|
||||
|
||||
$wait xapi.call 'host.enable', host.ref
|
||||
yield xapi.call 'host.enable', host.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -165,7 +165,7 @@ exports.enable = enable
|
||||
disable = $coroutine ({host}) ->
|
||||
xapi = @getXAPI host
|
||||
|
||||
$wait xapi.call 'host.disable', host.ref
|
||||
yield xapi.call 'host.disable', host.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -186,7 +186,7 @@ createNetwork = $coroutine ({host, name, description, pif, mtu, vlan}) ->
|
||||
|
||||
description = description ? 'Created with Xen Orchestra'
|
||||
|
||||
network_ref = $wait xapi.call 'network.create', {
|
||||
network_ref = yield xapi.call 'network.create', {
|
||||
name_label: name,
|
||||
name_description: description,
|
||||
MTU: mtu ? '1500'
|
||||
@ -196,7 +196,7 @@ createNetwork = $coroutine ({host, name, description, pif, mtu, vlan}) ->
|
||||
if pif?
|
||||
vlan = vlan ? '0'
|
||||
pif = @getObject pif, 'PIF'
|
||||
$wait xapi.call 'pool.create_VLAN_from_PIF', pif.ref, network_ref, vlan
|
||||
yield xapi.call 'pool.create_VLAN_from_PIF', pif.ref, network_ref, vlan
|
||||
|
||||
return true
|
||||
|
||||
@ -256,7 +256,7 @@ stats = $coroutine ({host}) ->
|
||||
|
||||
xapi = @getXAPI host
|
||||
|
||||
[response, body] = $wait $request {
|
||||
[response, body] = yield $request {
|
||||
method: 'get'
|
||||
rejectUnauthorized: false
|
||||
url: 'https://'+host.address+'/host_rrd?session_id='+xapi.sessionId
|
||||
|
@ -1,20 +0,0 @@
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
delete_ = $coroutine ({message}) ->
|
||||
xapi = @getXAPI message
|
||||
|
||||
$wait xapi.call 'message.destroy', message.ref
|
||||
|
||||
return true
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
message: ['id', 'message', 'administrate']
|
||||
}
|
||||
|
||||
exports.delete = delete_
|
12
src/api/message.js
Normal file
12
src/api/message.js
Normal file
@ -0,0 +1,12 @@
|
||||
async function delete_ ({message}) {
|
||||
await this.getXAPI(message).call('message.destroy', message.ref)
|
||||
}
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
message: ['id', 'message', 'administrate']
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
# FIXME: too low level, should be removed.
|
||||
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
# Delete
|
||||
|
||||
exports.delete = $coroutine ({PBD}) ->
|
||||
xapi = @getXAPI PBD
|
||||
|
||||
# TODO: check if PBD is attached before
|
||||
$wait xapi.call 'PBD.destroy', PBD.ref
|
||||
|
||||
return true
|
||||
exports.delete.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
exports.delete.resolve = {
|
||||
PBD: ['id', 'PBD', 'administrate']
|
||||
}
|
||||
|
||||
#=====================================================================
|
||||
# Disconnect
|
||||
|
||||
exports.disconnect = $coroutine ({PBD}) ->
|
||||
xapi = @getXAPI PBD
|
||||
|
||||
# TODO: check if PBD is attached before
|
||||
$wait xapi.call 'PBD.unplug', PBD.ref
|
||||
|
||||
return true
|
||||
exports.disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
exports.disconnect.resolve = {
|
||||
PBD: ['id', 'PBD', 'administrate']
|
||||
}
|
||||
|
||||
#=====================================================================
|
||||
# Connect
|
||||
|
||||
exports.connect = $coroutine ({PBD}) ->
|
||||
xapi = @getXAPI PBD
|
||||
|
||||
# TODO: check if PBD is attached before
|
||||
$wait xapi.call 'PBD.plug', PBD.ref
|
||||
|
||||
return true
|
||||
exports.connect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
exports.connect.resolve = {
|
||||
PBD: ['id', 'PBD', 'administrate']
|
||||
}
|
50
src/api/pbd.js
Normal file
50
src/api/pbd.js
Normal file
@ -0,0 +1,50 @@
|
||||
// FIXME: too low level, should be removed.
|
||||
|
||||
// ===================================================================
|
||||
// Delete
|
||||
|
||||
async function delete_ ({PBD}) {
|
||||
// TODO: check if PBD is attached before
|
||||
await this.getXAPI(PBD).call('PBD.destroy', PBD.ref)
|
||||
}
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
PBD: ['id', 'PBD', 'administrate']
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Disconnect
|
||||
|
||||
export async function disconnect ({PBD}) {
|
||||
// TODO: check if PBD is attached before
|
||||
await this.getXAPI(PBD).call('PBD.unplug', PBD.ref)
|
||||
}
|
||||
|
||||
disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
disconnect.resolve = {
|
||||
PBD: ['id', 'PBD', 'administrate']
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Connect
|
||||
|
||||
export async function connect ({PBD}) {
|
||||
// TODO: check if PBD is attached before
|
||||
await this.getXAPI(PBD).call('PBD.plug', PBD.ref)
|
||||
}
|
||||
|
||||
connect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
connect.resolve = {
|
||||
PBD: ['id', 'PBD', 'administrate']
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
# Delete
|
||||
|
||||
exports.delete = $coroutine ({PIF}) ->
|
||||
xapi = @getXAPI PIF
|
||||
|
||||
# TODO: check if PIF is attached before
|
||||
$wait xapi.call 'PIF.destroy', PIF.ref
|
||||
|
||||
return true
|
||||
exports.delete.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
exports.delete.resolve = {
|
||||
PIF: ['id', 'PIF', 'administrate']
|
||||
}
|
||||
|
||||
#=====================================================================
|
||||
# Disconnect
|
||||
|
||||
exports.disconnect = $coroutine ({PIF}) ->
|
||||
xapi = @getXAPI PIF
|
||||
|
||||
# TODO: check if PIF is attached before
|
||||
$wait xapi.call 'PIF.unplug', PIF.ref
|
||||
|
||||
return true
|
||||
exports.disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
exports.disconnect.resolve = {
|
||||
PIF: ['id', 'PIF', 'administrate']
|
||||
}
|
||||
#=====================================================================
|
||||
# Connect
|
||||
|
||||
exports.connect = $coroutine ({PIF}) ->
|
||||
xapi = @getXAPI PIF
|
||||
|
||||
# TODO: check if PIF is attached before
|
||||
$wait xapi.call 'PIF.plug', PIF.ref
|
||||
|
||||
return true
|
||||
exports.connect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
exports.connect.resolve = {
|
||||
PIF: ['id', 'PIF', 'administrate']
|
||||
}
|
47
src/api/pif.js
Normal file
47
src/api/pif.js
Normal file
@ -0,0 +1,47 @@
|
||||
// ===================================================================
|
||||
// Delete
|
||||
|
||||
async function delete_ ({PIF}) {
|
||||
// TODO: check if PIF is attached before
|
||||
await this.getXAPI(PIF).call('PIF.destroy', PIF.ref)
|
||||
}
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
PIF: ['id', 'PIF', 'administrate']
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Disconnect
|
||||
|
||||
export async function disconnect ({PIF}) {
|
||||
// TODO: check if PIF is attached before
|
||||
await this.getXAPI(PIF).call('PIF.unplug', PIF.ref)
|
||||
}
|
||||
|
||||
disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
disconnect.resolve = {
|
||||
PIF: ['id', 'PIF', 'administrate']
|
||||
}
|
||||
// ===================================================================
|
||||
// Connect
|
||||
|
||||
export async function connect ({PIF}) {
|
||||
// TODO: check if PIF is attached before
|
||||
await this.getXAPI(PIF).call('PIF.plug', PIF.ref)
|
||||
}
|
||||
|
||||
connect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
connect.resolve = {
|
||||
PIF: ['id', 'PIF', 'administrate']
|
||||
}
|
@ -2,23 +2,21 @@ import {deprecate} from 'util'
|
||||
|
||||
import {InvalidCredential, AlreadyAuthenticated} from '../api-errors'
|
||||
|
||||
import {coroutine, wait} from '../fibers-utils'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const signIn = coroutine(function (credentials) {
|
||||
export async function signIn (credentials) {
|
||||
if (this.session.has('user_id')) {
|
||||
throw new AlreadyAuthenticated()
|
||||
}
|
||||
|
||||
const user = wait(this.authenticateUser(credentials))
|
||||
const user = await this.authenticateUser(credentials)
|
||||
if (!user) {
|
||||
throw new InvalidCredential()
|
||||
}
|
||||
this.session.set('user_id', user.get('id'))
|
||||
|
||||
return this.getUserPublicProperties(user)
|
||||
})
|
||||
}
|
||||
|
||||
signIn.description = 'sign in'
|
||||
|
||||
@ -52,12 +50,12 @@ signOut.permission = ''
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const getUser = coroutine(function () {
|
||||
export async function getUser () {
|
||||
const userId = this.session.get('user_id')
|
||||
|
||||
return userId === undefined ?
|
||||
null :
|
||||
this.getUserPublicProperties(wait(this.getUser(userId)))
|
||||
})
|
||||
this.getUserPublicProperties(await this.getUser(userId))
|
||||
}
|
||||
|
||||
getUser.description = 'return the currently connected user'
|
||||
|
127
src/api/sr.js
127
src/api/sr.js
@ -1,5 +1,4 @@
|
||||
import forEach from 'lodash.foreach'
|
||||
import {coroutine, wait} from '../fibers-utils'
|
||||
import {ensureArray, parseXml} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -25,13 +24,9 @@ set.resolve = {
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const scan = coroutine(function ({SR}) {
|
||||
const xapi = this.getXAPI(SR)
|
||||
|
||||
wait(xapi.call('SR.scan', SR.ref))
|
||||
|
||||
return true
|
||||
})
|
||||
export async function scan ({SR}) {
|
||||
await this.getXAPI(SR).call('SR.scan', SR.ref)
|
||||
}
|
||||
|
||||
scan.params = {
|
||||
id: { type: 'string' }
|
||||
@ -44,13 +39,9 @@ scan.resolve = {
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// TODO: find a way to call this "delete" and not destroy
|
||||
export const destroy = coroutine(function ({SR}) {
|
||||
const xapi = this.getXAPI(SR)
|
||||
|
||||
wait(xapi.call('SR.destroy', SR.ref))
|
||||
|
||||
return true
|
||||
})
|
||||
export async function destroy ({SR}) {
|
||||
await this.getXAPI(SR).call('SR.destroy', SR.ref)
|
||||
}
|
||||
|
||||
destroy.params = {
|
||||
id: { type: 'string' }
|
||||
@ -62,13 +53,9 @@ destroy.resolve = {
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const forget = coroutine(function ({SR}) {
|
||||
const xapi = this.getXAPI(SR)
|
||||
|
||||
wait(xapi.call('SR.forget', SR.ref))
|
||||
|
||||
return true
|
||||
})
|
||||
export async function forget ({SR}) {
|
||||
await this.getXAPI(SR).call('SR.forget', SR.ref)
|
||||
}
|
||||
|
||||
forget.params = {
|
||||
id: { type: 'string' }
|
||||
@ -80,7 +67,7 @@ forget.resolve = {
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const createIso = coroutine(function ({
|
||||
export async function createIso ({
|
||||
host,
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
@ -95,7 +82,7 @@ export const createIso = coroutine(function ({
|
||||
// TODO: legacy will be removed in XAPI soon by FileSR
|
||||
deviceConfig.legacy_mode = 'true'
|
||||
}
|
||||
const srRef = wait(xapi.call(
|
||||
const srRef = await xapi.call(
|
||||
'SR.create',
|
||||
host.ref,
|
||||
deviceConfig,
|
||||
@ -106,11 +93,11 @@ export const createIso = coroutine(function ({
|
||||
'iso', // SR content type ISO
|
||||
true,
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
const sr = wait(xapi.call('SR.get_record', srRef))
|
||||
const sr = await xapi.call('SR.get_record', srRef)
|
||||
return sr.uuid
|
||||
})
|
||||
}
|
||||
|
||||
createIso.params = {
|
||||
host: { type: 'string' },
|
||||
@ -128,7 +115,7 @@ createIso.resolve = {
|
||||
|
||||
// This functions creates a NFS SR
|
||||
|
||||
export const createNfs = coroutine(function ({
|
||||
export async function createNfs ({
|
||||
host,
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
@ -148,7 +135,7 @@ export const createNfs = coroutine(function ({
|
||||
deviceConfig.nfsversion = nfsVersion
|
||||
}
|
||||
|
||||
const srRef = wait(xapi.call(
|
||||
const srRef = await xapi.call(
|
||||
'SR.create',
|
||||
host.ref,
|
||||
deviceConfig,
|
||||
@ -159,11 +146,11 @@ export const createNfs = coroutine(function ({
|
||||
'user', // recommended by Citrix
|
||||
true,
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
const sr = wait(xapi.call('SR.get_record', srRef))
|
||||
const sr = await xapi.call('SR.get_record', srRef)
|
||||
return sr.uuid
|
||||
})
|
||||
}
|
||||
|
||||
createNfs.params = {
|
||||
host: { type: 'string' },
|
||||
@ -183,7 +170,7 @@ createNfs.resolve = {
|
||||
|
||||
// This functions creates a local LVM SR
|
||||
|
||||
export const createLvm = coroutine(function ({
|
||||
export async function createLvm ({
|
||||
host,
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
@ -195,7 +182,7 @@ export const createLvm = coroutine(function ({
|
||||
device
|
||||
}
|
||||
|
||||
const srRef = wait(xapi.call(
|
||||
const srRef = await xapi.call(
|
||||
'SR.create',
|
||||
host.ref,
|
||||
deviceConfig,
|
||||
@ -206,11 +193,11 @@ export const createLvm = coroutine(function ({
|
||||
'user', // recommended by Citrix
|
||||
false,
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
const sr = wait(xapi.call('SR.get_record', srRef))
|
||||
const sr = await xapi.call('SR.get_record', srRef)
|
||||
return sr.uuid
|
||||
})
|
||||
}
|
||||
|
||||
createLvm.params = {
|
||||
host: { type: 'string' },
|
||||
@ -227,7 +214,7 @@ createLvm.resolve = {
|
||||
// This function helps to detect all NFS shares (exports) on a NFS server
|
||||
// Return a table of exports with their paths and ACLs
|
||||
|
||||
export const probeNfs = coroutine(function ({
|
||||
export async function probeNfs ({
|
||||
host,
|
||||
server
|
||||
}) {
|
||||
@ -240,13 +227,13 @@ export const probeNfs = coroutine(function ({
|
||||
let xml
|
||||
|
||||
try {
|
||||
wait(xapi.call(
|
||||
await xapi.call(
|
||||
'SR.probe',
|
||||
host.ref,
|
||||
deviceConfig,
|
||||
'nfs',
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
throw new Error('the call above should have thrown an error')
|
||||
} catch (error) {
|
||||
@ -266,7 +253,7 @@ export const probeNfs = coroutine(function ({
|
||||
})
|
||||
|
||||
return nfsExports
|
||||
})
|
||||
}
|
||||
|
||||
probeNfs.params = {
|
||||
host: { type: 'string' },
|
||||
@ -282,7 +269,7 @@ probeNfs.resolve = {
|
||||
|
||||
// This functions creates a iSCSI SR
|
||||
|
||||
export const createIscsi = coroutine(function ({
|
||||
export async function createIscsi ({
|
||||
host,
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
@ -313,7 +300,7 @@ export const createIscsi = coroutine(function ({
|
||||
deviceConfig.port = port
|
||||
}
|
||||
|
||||
const srRef = wait(xapi.call(
|
||||
const srRef = await xapi.call(
|
||||
'SR.create',
|
||||
host.ref,
|
||||
deviceConfig,
|
||||
@ -324,11 +311,11 @@ export const createIscsi = coroutine(function ({
|
||||
'user', // recommended by Citrix
|
||||
true,
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
const sr = wait(xapi.call('SR.get_record', srRef))
|
||||
const sr = await xapi.call('SR.get_record', srRef)
|
||||
return sr.uuid
|
||||
})
|
||||
}
|
||||
|
||||
createIscsi.params = {
|
||||
host: { type: 'string' },
|
||||
@ -350,7 +337,7 @@ createIscsi.resolve = {
|
||||
// This function helps to detect all iSCSI IQN on a Target (iSCSI "server")
|
||||
// Return a table of IQN or empty table if no iSCSI connection to the target
|
||||
|
||||
export const probeIscsiIqns = coroutine(function ({
|
||||
export async function probeIscsiIqns ({
|
||||
host,
|
||||
target: targetIp,
|
||||
port,
|
||||
@ -377,13 +364,13 @@ export const probeIscsiIqns = coroutine(function ({
|
||||
let xml
|
||||
|
||||
try {
|
||||
wait(xapi.call(
|
||||
await xapi.call(
|
||||
'SR.probe',
|
||||
host.ref,
|
||||
deviceConfig,
|
||||
'lvmoiscsi',
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
throw new Error('the call above should have thrown an error')
|
||||
} catch (error) {
|
||||
@ -409,7 +396,7 @@ export const probeIscsiIqns = coroutine(function ({
|
||||
})
|
||||
|
||||
return targets
|
||||
})
|
||||
}
|
||||
|
||||
probeIscsiIqns.params = {
|
||||
host: { type: 'string' },
|
||||
@ -426,7 +413,7 @@ probeIscsiIqns.resolve = {
|
||||
// This function helps to detect all iSCSI ID and LUNs on a Target
|
||||
// It will return a LUN table
|
||||
|
||||
export const probeIscsiLuns = coroutine(function ({
|
||||
export async function probeIscsiLuns ({
|
||||
host,
|
||||
target: targetIp,
|
||||
port,
|
||||
@ -455,13 +442,13 @@ export const probeIscsiLuns = coroutine(function ({
|
||||
let xml
|
||||
|
||||
try {
|
||||
wait(xapi.call(
|
||||
await xapi.call(
|
||||
'SR.probe',
|
||||
host.ref,
|
||||
deviceConfig,
|
||||
'lvmoiscsi',
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
throw new Error('the call above should have thrown an error')
|
||||
} catch (error) {
|
||||
@ -484,7 +471,7 @@ export const probeIscsiLuns = coroutine(function ({
|
||||
})
|
||||
|
||||
return luns
|
||||
})
|
||||
}
|
||||
|
||||
probeIscsiLuns.params = {
|
||||
host: { type: 'string' },
|
||||
@ -503,7 +490,7 @@ probeIscsiLuns.resolve = {
|
||||
// This function helps to detect if this target already exists in XAPI
|
||||
// It returns a table of SR UUID, empty if no existing connections
|
||||
|
||||
export const probeIscsiExists = coroutine(function ({
|
||||
export async function probeIscsiExists ({
|
||||
host,
|
||||
target: targetIp,
|
||||
port,
|
||||
@ -531,7 +518,7 @@ export const probeIscsiExists = coroutine(function ({
|
||||
deviceConfig.port = port
|
||||
}
|
||||
|
||||
const xml = parseXml(wait(xapi.call('SR.probe', host.ref, deviceConfig, 'lvmoiscsi', {})))
|
||||
const xml = parseXml(await xapi.call('SR.probe', host.ref, deviceConfig, 'lvmoiscsi', {}))
|
||||
|
||||
const srs = []
|
||||
forEach(ensureArray(xml['SRlist'].SR), sr => {
|
||||
@ -540,7 +527,7 @@ export const probeIscsiExists = coroutine(function ({
|
||||
})
|
||||
|
||||
return srs
|
||||
})
|
||||
}
|
||||
|
||||
probeIscsiExists.params = {
|
||||
host: { type: 'string' },
|
||||
@ -560,7 +547,7 @@ probeIscsiExists.resolve = {
|
||||
// This function helps to detect if this NFS SR already exists in XAPI
|
||||
// It returns a table of SR UUID, empty if no existing connections
|
||||
|
||||
export const probeNfsExists = coroutine(function ({
|
||||
export async function probeNfsExists ({
|
||||
host,
|
||||
server,
|
||||
serverPath,
|
||||
@ -572,7 +559,7 @@ export const probeNfsExists = coroutine(function ({
|
||||
serverpath: serverPath
|
||||
}
|
||||
|
||||
const xml = parseXml(wait(xapi.call('SR.probe', host.ref, deviceConfig, 'nfs', {})))
|
||||
const xml = parseXml(await xapi.call('SR.probe', host.ref, deviceConfig, 'nfs', {}))
|
||||
|
||||
const srs = []
|
||||
|
||||
@ -582,7 +569,7 @@ export const probeNfsExists = coroutine(function ({
|
||||
})
|
||||
|
||||
return srs
|
||||
})
|
||||
}
|
||||
|
||||
probeNfsExists.params = {
|
||||
host: { type: 'string' },
|
||||
@ -597,7 +584,7 @@ probeNfsExists.resolve = {
|
||||
// -------------------------------------------------------------------
|
||||
// This function helps to reattach a forgotten NFS/iSCSI SR
|
||||
|
||||
export const reattach = coroutine(function ({
|
||||
export async function reattach ({
|
||||
host,
|
||||
uuid,
|
||||
nameLabel,
|
||||
@ -610,7 +597,7 @@ export const reattach = coroutine(function ({
|
||||
type = 'lvmoiscsi' // the internal XAPI name
|
||||
}
|
||||
|
||||
const srRef = wait(xapi.call(
|
||||
const srRef = await xapi.call(
|
||||
'SR.introduce',
|
||||
uuid,
|
||||
nameLabel,
|
||||
@ -619,11 +606,11 @@ export const reattach = coroutine(function ({
|
||||
'user',
|
||||
true,
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
const sr = wait(xapi.call('SR.get_record', srRef))
|
||||
const sr = await xapi.call('SR.get_record', srRef)
|
||||
return sr.uuid
|
||||
})
|
||||
}
|
||||
|
||||
reattach.params = {
|
||||
host: { type: 'string' },
|
||||
@ -640,7 +627,7 @@ reattach.resolve = {
|
||||
// -------------------------------------------------------------------
|
||||
// This function helps to reattach a forgotten ISO SR
|
||||
|
||||
export const reattachIso = coroutine(function ({
|
||||
export async function reattachIso ({
|
||||
host,
|
||||
uuid,
|
||||
nameLabel,
|
||||
@ -653,7 +640,7 @@ export const reattachIso = coroutine(function ({
|
||||
type = 'lvmoiscsi' // the internal XAPI name
|
||||
}
|
||||
|
||||
const srRef = wait(xapi.call(
|
||||
const srRef = await xapi.call(
|
||||
'SR.introduce',
|
||||
uuid,
|
||||
nameLabel,
|
||||
@ -662,11 +649,11 @@ export const reattachIso = coroutine(function ({
|
||||
'iso',
|
||||
true,
|
||||
{}
|
||||
))
|
||||
)
|
||||
|
||||
const sr = wait(xapi.call('SR.get_record', srRef))
|
||||
const sr = await xapi.call('SR.get_record', srRef)
|
||||
return sr.uuid
|
||||
})
|
||||
}
|
||||
|
||||
reattachIso.params = {
|
||||
host: { type: 'string' },
|
||||
|
@ -1,38 +0,0 @@
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
cancel = $coroutine ({task}) ->
|
||||
xapi = @getXAPI task
|
||||
|
||||
$wait xapi.call 'task.cancel', task.ref
|
||||
|
||||
return true
|
||||
|
||||
cancel.params = {
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
cancel.resolve = {
|
||||
task: ['id', 'task', 'administrate'],
|
||||
}
|
||||
|
||||
exports.cancel = cancel
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
destroy = $coroutine ({task}) ->
|
||||
xapi = @getXAPI task
|
||||
|
||||
$wait xapi.call 'task.destroy', task.ref
|
||||
|
||||
return true
|
||||
|
||||
destroy.params = {
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
destroy.resolve = {
|
||||
task: ['id', 'task', 'administrate'],
|
||||
}
|
||||
|
||||
exports.destroy = destroy
|
25
src/api/task.js
Normal file
25
src/api/task.js
Normal file
@ -0,0 +1,25 @@
|
||||
export async function cancel ({task}) {
|
||||
await this.getXAPI(task).call('task.cancel', task.ref)
|
||||
}
|
||||
|
||||
cancel.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
cancel.resolve = {
|
||||
task: ['id', 'task', 'administrate']
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export async function destroy ({task}) {
|
||||
await this.getXAPI(task).call('task.destroy', task.ref)
|
||||
}
|
||||
|
||||
destroy.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
destroy.resolve = {
|
||||
task: ['id', 'task', 'administrate']
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
# FIXME: too low level, should be removed.
|
||||
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
{coroutine: $coroutine} = require 'bluebird'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
@ -8,7 +8,7 @@ delete_ = $coroutine ({vbd}) ->
|
||||
xapi = @getXAPI vbd
|
||||
|
||||
# TODO: check if VBD is attached before
|
||||
$wait xapi.call 'VBD.destroy', vbd.ref
|
||||
yield xapi.call 'VBD.destroy', vbd.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -28,7 +28,7 @@ disconnect = $coroutine ({vbd}) ->
|
||||
xapi = @getXAPI vbd
|
||||
|
||||
# TODO: check if VBD is attached before
|
||||
$wait xapi.call 'VBD.unplug_force', vbd.ref
|
||||
yield xapi.call 'VBD.unplug_force', vbd.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -48,7 +48,7 @@ connect = $coroutine ({vbd}) ->
|
||||
xapi = @getXAPI vbd
|
||||
|
||||
# TODO: check if VBD is attached before
|
||||
$wait xapi.call 'VBD.plug', vbd.ref
|
||||
yield xapi.call 'VBD.plug', vbd.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -72,7 +72,7 @@ set = $coroutine (params) ->
|
||||
|
||||
# VBD position
|
||||
if 'position' of params
|
||||
$wait xapi.call 'VBD.set_userdevice', ref, params.position
|
||||
yield xapi.call 'VBD.set_userdevice', ref, params.position
|
||||
|
||||
set.params = {
|
||||
# Identifier of the VBD to update.
|
||||
|
@ -4,7 +4,7 @@ $isArray = require 'lodash.isarray'
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
{coroutine: $coroutine} = require 'bluebird'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
@ -12,7 +12,7 @@ delete_ = $coroutine ({vdi}) ->
|
||||
xapi = @getXAPI vdi
|
||||
|
||||
# TODO: check if VDI is attached before
|
||||
$wait xapi.call 'VDI.destroy', vdi.ref
|
||||
yield xapi.call 'VDI.destroy', vdi.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -45,7 +45,7 @@ set = $coroutine (params) ->
|
||||
"cannot set new size below the current size (#{vdi.size})"
|
||||
)
|
||||
|
||||
$wait xapi.call 'VDI.resize_online', ref, "#{size}"
|
||||
yield xapi.call 'VDI.resize_online', ref, "#{size}"
|
||||
|
||||
# Other fields.
|
||||
for param, fields of {
|
||||
@ -55,7 +55,7 @@ set = $coroutine (params) ->
|
||||
continue unless param of params
|
||||
|
||||
for field in (if $isArray fields then fields else [fields])
|
||||
$wait xapi.call "VDI.set_#{field}", ref, "#{params[param]}"
|
||||
yield xapi.call "VDI.set_#{field}", ref, "#{params[param]}"
|
||||
|
||||
return true
|
||||
|
||||
@ -83,7 +83,7 @@ migrate = $coroutine ({vdi, sr}) ->
|
||||
xapi = @getXAPI vdi
|
||||
|
||||
# TODO: check if VDI is attached before
|
||||
$wait xapi.call 'VDI.pool_migrate', vdi.ref, sr.ref, {}
|
||||
yield xapi.call 'VDI.pool_migrate', vdi.ref, sr.ref, {}
|
||||
|
||||
return true
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
delete_ = $coroutine ({vif}) ->
|
||||
xapi = @getXAPI vif
|
||||
|
||||
# TODO: check if VIF is attached before
|
||||
$wait xapi.call 'VIF.destroy', vif.ref
|
||||
|
||||
return true
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
vif: ['id', 'VIF', 'administrate']
|
||||
}
|
||||
|
||||
exports.delete = delete_
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
disconnect = $coroutine ({vif}) ->
|
||||
xapi = @getXAPI vif
|
||||
|
||||
# TODO: check if VIF is attached before
|
||||
$wait xapi.call 'VIF.unplug_force', vif.ref
|
||||
|
||||
return true
|
||||
|
||||
disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
disconnect.resolve = {
|
||||
vif: ['id', 'VIF', 'operate']
|
||||
}
|
||||
|
||||
exports.disconnect = disconnect
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
connect = $coroutine ({vif}) ->
|
||||
xapi = @getXAPI vif
|
||||
|
||||
# TODO: check if VIF is attached before
|
||||
$wait xapi.call 'VIF.plug', vif.ref
|
||||
|
||||
return true
|
||||
|
||||
connect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
connect.resolve = {
|
||||
vif: ['id', 'VIF', 'operate']
|
||||
}
|
||||
|
||||
exports.connect = connect
|
43
src/api/vif.js
Normal file
43
src/api/vif.js
Normal file
@ -0,0 +1,43 @@
|
||||
async function delete_ ({vif}) {
|
||||
// TODO: check if VIF is attached before
|
||||
await this.getXAPI(vif).call('VIF.destroy', vif.ref)
|
||||
}
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
vif: ['id', 'VIF', 'administrate']
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export async function disconnect ({vif}) {
|
||||
// TODO: check if VIF is attached before
|
||||
await this.getXAPI(vif).call('VIF.unplug_force', vif.ref)
|
||||
}
|
||||
|
||||
disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
disconnect.resolve = {
|
||||
vif: ['id', 'VIF', 'operate']
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export async function connect ({vif}) {
|
||||
// TODO: check if VIF is attached before
|
||||
await this.getXAPI(vif).call('VIF.plug', vif.ref)
|
||||
}
|
||||
|
||||
connect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
connect.resolve = {
|
||||
vif: ['id', 'VIF', 'operate']
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
$debug = (require 'debug') 'xo:api:vm'
|
||||
$findIndex = require 'lodash.findindex'
|
||||
$findWhere = require 'lodash.find'
|
||||
$result = require 'lodash.result'
|
||||
$forEach = require 'lodash.foreach'
|
||||
$isArray = require 'lodash.isarray'
|
||||
$findIndex = require 'lodash.findindex'
|
||||
startsWith = require 'lodash.startswith'
|
||||
endsWith = require 'lodash.endswith'
|
||||
$request = require('bluebird').promisify(require('request'))
|
||||
$result = require 'lodash.result'
|
||||
endsWith = require 'lodash.endswith'
|
||||
startsWith = require 'lodash.startswith'
|
||||
{coroutine: $coroutine} = require 'bluebird'
|
||||
|
||||
{$coroutine, $wait} = require '../fibers-utils'
|
||||
{
|
||||
formatXml: $js2xml,
|
||||
parseXml,
|
||||
@ -38,7 +38,7 @@ create = $coroutine ({
|
||||
xapi = @getXAPI template
|
||||
|
||||
# Clones the VM from the template.
|
||||
ref = $wait xapi.call 'VM.clone', template.ref, name_label
|
||||
ref = yield xapi.call 'VM.clone', template.ref, name_label
|
||||
|
||||
# TODO: if there is an error from now, removes this VM.
|
||||
|
||||
@ -51,7 +51,7 @@ create = $coroutine ({
|
||||
$forEach VIFs, (VIF) =>
|
||||
network = @getObject VIF.network, 'network'
|
||||
|
||||
$wait xapi.call 'VIF.create', {
|
||||
yield xapi.call 'VIF.create', {
|
||||
|
||||
device: String(deviceId++)
|
||||
MAC: VIF.MAC ? ''
|
||||
@ -65,11 +65,11 @@ create = $coroutine ({
|
||||
|
||||
return
|
||||
|
||||
# TODO: ? $wait xapi.call 'VM.set_PV_args', ref, 'noninteractive'
|
||||
# TODO: ? yield xapi.call 'VM.set_PV_args', ref, 'noninteractive'
|
||||
|
||||
# Updates the number of existing vCPUs.
|
||||
if CPUs?
|
||||
$wait xapi.call 'VM.set_VCPUs_at_startup', ref, CPUs
|
||||
yield xapi.call 'VM.set_VCPUs_at_startup', ref, CPUs
|
||||
|
||||
# TODO: remove existing VDIs (o make sure we have only those we
|
||||
# asked.
|
||||
@ -96,10 +96,10 @@ create = $coroutine ({
|
||||
}
|
||||
|
||||
# Replace the existing entry in the VM object.
|
||||
try $wait xapi.call 'VM.remove_from_other_config', ref, 'disks'
|
||||
$wait xapi.call 'VM.add_to_other_config', ref, 'disks', VDIs
|
||||
try yield xapi.call 'VM.remove_from_other_config', ref, 'disks'
|
||||
yield xapi.call 'VM.add_to_other_config', ref, 'disks', VDIs
|
||||
|
||||
try $wait xapi.call(
|
||||
try yield xapi.call(
|
||||
'VM.remove_from_other_config'
|
||||
ref
|
||||
'install-repository'
|
||||
@ -107,12 +107,12 @@ create = $coroutine ({
|
||||
if installation
|
||||
switch installation.method
|
||||
when 'cdrom'
|
||||
$wait xapi.call(
|
||||
yield xapi.call(
|
||||
'VM.add_to_other_config', ref
|
||||
'install-repository', 'cdrom'
|
||||
)
|
||||
when 'ftp', 'http', 'nfs'
|
||||
$wait xapi.call(
|
||||
yield xapi.call(
|
||||
'VM.add_to_other_config', ref
|
||||
'install-repository', installation.repository
|
||||
)
|
||||
@ -124,10 +124,10 @@ create = $coroutine ({
|
||||
|
||||
# Creates the VDIs and executes the initial steps of the
|
||||
# installation.
|
||||
$wait xapi.call 'VM.provision', ref
|
||||
yield xapi.call 'VM.provision', ref
|
||||
|
||||
# Gets the VM record.
|
||||
VM = $wait xapi.call 'VM.get_record', ref
|
||||
VM = yield xapi.call 'VM.get_record', ref
|
||||
|
||||
if installation.method is 'cdrom'
|
||||
# Gets the VDI containing the ISO to mount.
|
||||
@ -140,7 +140,7 @@ create = $coroutine ({
|
||||
# CD.
|
||||
CD_drive = null
|
||||
$forEach VM.VBDs, (ref) ->
|
||||
VBD = $wait xapi.call 'VBD.get_record', ref
|
||||
VBD = yield xapi.call 'VBD.get_record', ref
|
||||
# TODO: Checks it has been correctly retrieved.
|
||||
if VBD.type is 'CD'
|
||||
CD_drive = VBD.ref
|
||||
@ -150,7 +150,7 @@ create = $coroutine ({
|
||||
# No CD drives have been found, creates one.
|
||||
unless CD_drive
|
||||
# See: https://github.com/xenserver/xenadmin/blob/da00b13bb94603b369b873b0a555d44f15fa0ca5/XenModel/Actions/VM/CreateVMAction.cs#L370
|
||||
CD_drive = $wait xapi.call 'VBD.create', {
|
||||
CD_drive = yield xapi.call 'VBD.create', {
|
||||
bootable: true
|
||||
device: ''
|
||||
empty: true
|
||||
@ -160,7 +160,7 @@ create = $coroutine ({
|
||||
qos_algorithm_type: ''
|
||||
type: 'CD'
|
||||
unpluggable: true
|
||||
userdevice: ($wait xapi.call 'VM.get_allowed_VBD_devices', ref)[0]
|
||||
userdevice: (yield xapi.call 'VM.get_allowed_VBD_devices', ref)[0]
|
||||
VDI: 'OpaqueRef:NULL'
|
||||
VM: ref
|
||||
}
|
||||
@ -169,10 +169,10 @@ create = $coroutine ({
|
||||
@throw 'NO_SUCH_OBJECT' unless CD_drive
|
||||
|
||||
# Mounts the VDI into the VBD.
|
||||
$wait xapi.call 'VBD.insert', CD_drive, VDIref
|
||||
yield xapi.call 'VBD.insert', CD_drive, VDIref
|
||||
else
|
||||
$wait xapi.call 'VM.provision', ref
|
||||
VM = $wait xapi.call 'VM.get_record', ref
|
||||
yield xapi.call 'VM.provision', ref
|
||||
VM = yield xapi.call 'VM.get_record', ref
|
||||
|
||||
# The VM should be properly created.
|
||||
return VM.uuid
|
||||
@ -272,7 +272,7 @@ ejectCd = $coroutine ({vm}) ->
|
||||
return
|
||||
|
||||
if cdDriveRef
|
||||
$wait xapi.call 'VBD.eject', cdDriveRef
|
||||
yield xapi.call 'VBD.eject', cdDriveRef
|
||||
|
||||
# Silently attempts to destroy the VBD.
|
||||
xapi.call('VBD.destroy', cdDriveRef).catch(->)
|
||||
@ -306,9 +306,9 @@ insertCd = $coroutine ({vm, vdi, force}) ->
|
||||
|
||||
if cdDrive.VDI
|
||||
@throw 'INVALID_PARAMS' unless force
|
||||
$wait xapi.call 'VBD.eject', cdDriveRef
|
||||
yield xapi.call 'VBD.eject', cdDriveRef
|
||||
else
|
||||
cdDriveRef = $wait xapi.call 'VBD.create', {
|
||||
cdDriveRef = yield xapi.call 'VBD.create', {
|
||||
bootable: true
|
||||
device: ''
|
||||
empty: true
|
||||
@ -318,12 +318,12 @@ insertCd = $coroutine ({vm, vdi, force}) ->
|
||||
qos_algorithm_type: ''
|
||||
type: 'CD'
|
||||
unpluggable: true
|
||||
userdevice: ($wait xapi.call 'VM.get_allowed_VBD_devices', vm.ref)[0]
|
||||
userdevice: (yield xapi.call 'VM.get_allowed_VBD_devices', vm.ref)[0]
|
||||
VDI: 'OpaqueRef:NULL'
|
||||
VM: vm.ref
|
||||
}
|
||||
|
||||
$wait xapi.call 'VBD.insert', cdDriveRef, vdi.ref
|
||||
yield xapi.call 'VBD.insert', cdDriveRef, vdi.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -347,7 +347,7 @@ migrate = $coroutine ({vm, host}) ->
|
||||
|
||||
xapi = @getXAPI vm
|
||||
|
||||
$wait xapi.call 'VM.pool_migrate', vm.ref, host.ref, {'force': 'true'}
|
||||
yield xapi.call 'VM.pool_migrate', vm.ref, host.ref, {'force': 'true'}
|
||||
|
||||
return true
|
||||
|
||||
@ -411,14 +411,14 @@ migratePool = $coroutine ({
|
||||
VIF = @getObject vifId, 'VIF'
|
||||
vifMap[VIF.ref] = network.ref
|
||||
|
||||
token = $wait (@getXAPI host).call(
|
||||
token = yield (@getXAPI host).call(
|
||||
'host.migrate_receive'
|
||||
host.ref
|
||||
migrationNetwork.ref
|
||||
{} # Other parameters
|
||||
)
|
||||
|
||||
$wait (@getXAPI VM).call(
|
||||
yield (@getXAPI VM).call(
|
||||
'VM.migrate_send'
|
||||
VM.ref
|
||||
token
|
||||
@ -486,10 +486,10 @@ set = $coroutine (params) ->
|
||||
)
|
||||
|
||||
if memory < VM.memory.dynamic[0]
|
||||
$wait xapi.call 'VM.set_memory_dynamic_min', ref, "#{memory}"
|
||||
yield xapi.call 'VM.set_memory_dynamic_min', ref, "#{memory}"
|
||||
else if memory > VM.memory.static[1]
|
||||
$wait xapi.call 'VM.set_memory_static_max', ref, "#{memory}"
|
||||
$wait xapi.call 'VM.set_memory_dynamic_max', ref, "#{memory}"
|
||||
yield xapi.call 'VM.set_memory_static_max', ref, "#{memory}"
|
||||
yield xapi.call 'VM.set_memory_dynamic_max', ref, "#{memory}"
|
||||
|
||||
# Number of CPUs.
|
||||
if 'CPUs' of params
|
||||
@ -502,11 +502,11 @@ set = $coroutine (params) ->
|
||||
"cannot set CPUs above the static maximum (#{VM.CPUs.max}) "+
|
||||
"for a running VM"
|
||||
)
|
||||
$wait xapi.call 'VM.set_VCPUs_number_live', ref, "#{CPUs}"
|
||||
yield xapi.call 'VM.set_VCPUs_number_live', ref, "#{CPUs}"
|
||||
else
|
||||
if CPUs > VM.CPUs.max
|
||||
$wait xapi.call 'VM.set_VCPUs_max', ref, "#{CPUs}"
|
||||
$wait xapi.call 'VM.set_VCPUs_at_startup', ref, "#{CPUs}"
|
||||
yield xapi.call 'VM.set_VCPUs_max', ref, "#{CPUs}"
|
||||
yield xapi.call 'VM.set_VCPUs_at_startup', ref, "#{CPUs}"
|
||||
|
||||
# HA policy
|
||||
# TODO: also handle "best-effort" case
|
||||
@ -514,17 +514,17 @@ set = $coroutine (params) ->
|
||||
{high_availability} = params
|
||||
|
||||
if high_availability
|
||||
$wait xapi.call 'VM.set_ha_restart_priority', ref, "restart"
|
||||
yield xapi.call 'VM.set_ha_restart_priority', ref, "restart"
|
||||
else
|
||||
$wait xapi.call 'VM.set_ha_restart_priority', ref, ""
|
||||
yield xapi.call 'VM.set_ha_restart_priority', ref, ""
|
||||
|
||||
if 'auto_poweron' of params
|
||||
{auto_poweron} = params
|
||||
|
||||
if auto_poweron
|
||||
$wait xapi.call 'VM.add_to_other_config', ref, 'auto_poweron', 'true'
|
||||
yield xapi.call 'VM.add_to_other_config', ref, 'auto_poweron', 'true'
|
||||
else
|
||||
$wait xapi.call 'VM.remove_from_other_config', ref, 'auto_poweron'
|
||||
yield xapi.call 'VM.remove_from_other_config', ref, 'auto_poweron'
|
||||
|
||||
# Other fields.
|
||||
for param, fields of {
|
||||
@ -534,7 +534,7 @@ set = $coroutine (params) ->
|
||||
continue unless param of params
|
||||
|
||||
for field in (if $isArray fields then fields else [fields])
|
||||
$wait xapi.call "VM.set_#{field}", ref, "#{params[param]}"
|
||||
yield xapi.call "VM.set_#{field}", ref, "#{params[param]}"
|
||||
|
||||
return true
|
||||
|
||||
@ -573,9 +573,9 @@ restart = $coroutine ({vm, force}) ->
|
||||
xapi = @getXAPI(vm)
|
||||
|
||||
if force
|
||||
$wait xapi.call 'VM.hard_reboot', vm.ref
|
||||
yield xapi.call 'VM.hard_reboot', vm.ref
|
||||
else
|
||||
$wait xapi.call 'VM.clean_reboot', vm.ref
|
||||
yield xapi.call 'VM.clean_reboot', vm.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -595,9 +595,9 @@ exports.restart = restart
|
||||
clone = $coroutine ({vm, name, full_copy}) ->
|
||||
xapi = @getXAPI vm
|
||||
if full_copy
|
||||
$wait xapi.call 'VM.copy', vm.ref, name, ''
|
||||
yield xapi.call 'VM.copy', vm.ref, name, ''
|
||||
else
|
||||
$wait xapi.call 'VM.clone', vm.ref, name
|
||||
yield xapi.call 'VM.clone', vm.ref, name
|
||||
|
||||
return true
|
||||
|
||||
@ -621,7 +621,7 @@ exports.clone = clone
|
||||
|
||||
# TODO: rename convertToTemplate()
|
||||
convert = $coroutine ({vm}) ->
|
||||
$wait @getXAPI(vm).call 'VM.set_is_a_template', vm.ref, true
|
||||
yield @getXAPI(vm).call 'VM.set_is_a_template', vm.ref, true
|
||||
|
||||
return true
|
||||
|
||||
@ -638,7 +638,7 @@ exports.convert = convert
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
snapshot = $coroutine ({vm, name}) ->
|
||||
snapshot = $wait @getXAPI(vm).snapshotVm(vm.ref, name)
|
||||
snapshot = yield @getXAPI(vm).snapshotVm(vm.ref, name)
|
||||
return snapshot.$id
|
||||
|
||||
snapshot.params = {
|
||||
@ -655,7 +655,7 @@ exports.snapshot = snapshot
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
start = $coroutine ({vm}) ->
|
||||
$wait @getXAPI(vm).call(
|
||||
yield @getXAPI(vm).call(
|
||||
'VM.start', vm.ref
|
||||
false # Start paused?
|
||||
false # Skips the pre-boot checks?
|
||||
@ -684,12 +684,12 @@ stop = $coroutine ({vm, force}) ->
|
||||
|
||||
# Hard shutdown
|
||||
if force
|
||||
$wait xapi.call 'VM.hard_shutdown', vm.ref
|
||||
yield xapi.call 'VM.hard_shutdown', vm.ref
|
||||
return true
|
||||
|
||||
# Clean shutdown
|
||||
try
|
||||
$wait xapi.call 'VM.clean_shutdown', vm.ref
|
||||
yield xapi.call 'VM.clean_shutdown', vm.ref
|
||||
catch error
|
||||
if error.code is 'VM_MISSING_PV_DRIVERS'
|
||||
# TODO: Improve reporting: this message is unclear.
|
||||
@ -713,7 +713,7 @@ exports.stop = stop
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
suspend = $coroutine ({vm}) ->
|
||||
$wait @getXAPI(vm).call 'VM.suspend', vm.ref
|
||||
yield @getXAPI(vm).call 'VM.suspend', vm.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -733,7 +733,7 @@ resume = $coroutine ({vm, force}) ->
|
||||
if not force
|
||||
force = true
|
||||
|
||||
$wait @getXAPI(vm).call 'VM.resume', vm.ref, false, force
|
||||
yield @getXAPI(vm).call 'VM.resume', vm.ref, false, force
|
||||
|
||||
return true
|
||||
|
||||
@ -752,7 +752,7 @@ exports.resume = resume
|
||||
# revert a snapshot to its parent VM
|
||||
revert = $coroutine ({snapshot}) ->
|
||||
# Attempts a revert from this snapshot to its parent VM
|
||||
$wait @getXAPI(snapshot).call 'VM.revert', snapshot.ref
|
||||
yield @getXAPI(snapshot).call 'VM.revert', snapshot.ref
|
||||
|
||||
return true
|
||||
|
||||
@ -778,12 +778,12 @@ handleExport = (req, res, {stream, response: upstream}) ->
|
||||
|
||||
# TODO: integrate in xapi.js
|
||||
export_ = $coroutine ({vm, compress}) ->
|
||||
stream = $wait @getXAPI(vm).exportVm(vm.id, compress ? true)
|
||||
stream = yield @getXAPI(vm).exportVm(vm.id, compress ? true)
|
||||
|
||||
return {
|
||||
$getFrom: $wait @registerHttpRequest(handleExport, {
|
||||
$getFrom: yield @registerHttpRequest(handleExport, {
|
||||
stream,
|
||||
response: $wait stream.response
|
||||
response: yield stream.response
|
||||
})
|
||||
}
|
||||
|
||||
@ -805,7 +805,7 @@ import_ = $coroutine ({host}) ->
|
||||
|
||||
{sessionId} = @getXAPI(host)
|
||||
|
||||
url = $wait @registerProxyRequest {
|
||||
url = yield @registerProxyRequest {
|
||||
# Receive a POST but send a PUT.
|
||||
method: 'put'
|
||||
proxyMethod: 'post'
|
||||
@ -834,7 +834,7 @@ exports.import = import_
|
||||
# FIXME: if position is used, all other disks after this position
|
||||
# should be shifted.
|
||||
attachDisk = $coroutine ({vm, vdi, position, mode, bootable}) ->
|
||||
$wait @getXAPI(vm).attachVdiToVm(vdi.id, vm.id, {bootable, mode, position})
|
||||
yield @getXAPI(vm).attachVdiToVm(vdi.id, vm.id, {bootable, mode, position})
|
||||
return
|
||||
|
||||
attachDisk.params = {
|
||||
@ -859,7 +859,7 @@ exports.attachDisk = attachDisk
|
||||
# FIXME: position should be optional and default to last.
|
||||
|
||||
createInterface = $coroutine ({vm, network, position, mtu, mac}) ->
|
||||
vif = $wait @getXAPI(vm).createVirtualInterface(vm.id, network.id, {
|
||||
vif = yield @getXAPI(vm).createVirtualInterface(vm.id, network.id, {
|
||||
mac,
|
||||
mtu,
|
||||
position
|
||||
@ -886,7 +886,7 @@ exports.createInterface = createInterface
|
||||
attachPci = $coroutine ({vm, pciId}) ->
|
||||
xapi = @getXAPI vm
|
||||
|
||||
$wait xapi.call 'VM.add_to_other_config', vm.ref, 'pci', pciId
|
||||
yield xapi.call 'VM.add_to_other_config', vm.ref, 'pci', pciId
|
||||
|
||||
return true
|
||||
|
||||
@ -906,7 +906,7 @@ exports.attachPci = attachPci
|
||||
detachPci = $coroutine ({vm}) ->
|
||||
xapi = @getXAPI vm
|
||||
|
||||
$wait xapi.call 'VM.remove_from_other_config', vm.ref, 'pci'
|
||||
yield xapi.call 'VM.remove_from_other_config', vm.ref, 'pci'
|
||||
|
||||
return true
|
||||
|
||||
@ -933,7 +933,7 @@ stats = $coroutine ({vm}) ->
|
||||
else unless type is 'host'
|
||||
throw new Error "unexpected type: got #{type} instead of host"
|
||||
|
||||
[response, body] = $wait $request {
|
||||
[response, body] = yield $request {
|
||||
method: 'get'
|
||||
rejectUnauthorized: false
|
||||
url: 'https://'+host.address+'/vm_rrd?session_id='+xapi.sessionId+'&uuid='+vm.id
|
||||
@ -1031,7 +1031,7 @@ bootOrder = $coroutine ({vm, order}) ->
|
||||
|
||||
order = {order: order}
|
||||
|
||||
$wait xapi.call 'VM.set_HVM_boot_params', vm.ref, order
|
||||
yield xapi.call 'VM.set_HVM_boot_params', vm.ref, order
|
||||
|
||||
return true
|
||||
|
||||
|
@ -1,115 +0,0 @@
|
||||
import Bluebird from 'bluebird'
|
||||
import Fiber from 'fibers'
|
||||
import forEach from 'lodash.foreach'
|
||||
import isArray from 'lodash.isarray'
|
||||
import isFunction from 'lodash.isfunction'
|
||||
import isObject from 'lodash.isobject'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const isPromise = (obj) => obj && isFunction(obj.then)
|
||||
|
||||
// The value is guarantee to resolve asynchronously.
|
||||
const runAsync = (value, resolve, reject) => {
|
||||
if (isPromise(value)) {
|
||||
return value.then(resolve, reject)
|
||||
}
|
||||
|
||||
if (isFunction(value)) { // Continuable
|
||||
throw new Error('continuable are no longer supported')
|
||||
}
|
||||
|
||||
if (!isObject(value)) {
|
||||
return process.nextTick(() => {
|
||||
resolve(value)
|
||||
})
|
||||
}
|
||||
|
||||
let left = 0
|
||||
let results = isArray(value) ?
|
||||
new Array(value.length) :
|
||||
Object.create(null)
|
||||
|
||||
forEach(value, (value, index) => {
|
||||
++left
|
||||
runAsync(
|
||||
value,
|
||||
(result) => {
|
||||
// Returns if already rejected.
|
||||
if (!results) {
|
||||
return
|
||||
}
|
||||
|
||||
results[index] = result
|
||||
if (!--left) {
|
||||
resolve(results)
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
// Returns if already rejected.
|
||||
if (!results) {
|
||||
return
|
||||
}
|
||||
|
||||
// Frees the reference ASAP.
|
||||
results = null
|
||||
|
||||
reject(error)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
if (!left) {
|
||||
process.nextTick(() => {
|
||||
resolve(value)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
// Makes a function run in its own fiber and returns a promise.
|
||||
export function coroutine (fn) {
|
||||
return function (...args) {
|
||||
return new Bluebird((resolve, reject) => {
|
||||
new Fiber(() => {
|
||||
try {
|
||||
resolve(fn.apply(this, args))
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
}
|
||||
}).run()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Waits for a promise or a continuable to end.
|
||||
//
|
||||
// If value is composed (array or map), every asynchronous value is
|
||||
// resolved before returning (parallelization).
|
||||
export const wait = (value) => {
|
||||
const fiber = Fiber.current
|
||||
if (!fiber) {
|
||||
throw new Error('not running in a fiber')
|
||||
}
|
||||
|
||||
runAsync(
|
||||
value,
|
||||
(value) => {
|
||||
fiber.run(value)
|
||||
},
|
||||
(error) => {
|
||||
fiber.throwInto(error)
|
||||
}
|
||||
)
|
||||
|
||||
return Fiber.yield()
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
// Compatibility.
|
||||
export {
|
||||
coroutine as $coroutine,
|
||||
wait as $wait
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
/* eslint-env mocha */
|
||||
|
||||
import {expect} from 'chai'
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
import Bluebird from 'bluebird'
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
import {$coroutine, $wait} from './fibers-utils'
|
||||
|
||||
// Enable source maps support for traces.
|
||||
import sourceMapSupport from 'source-map-support'
|
||||
sourceMapSupport.install()
|
||||
|
||||
// ===================================================================
|
||||
|
||||
describe('$coroutine', function () {
|
||||
it('creates a function which returns promises', function () {
|
||||
const fn = $coroutine(function () {})
|
||||
expect(fn().then).to.be.a('function')
|
||||
})
|
||||
|
||||
it('creates a function which runs in a new fiber', function () {
|
||||
const previous = require('fibers').current
|
||||
|
||||
const fn = $coroutine(function () {
|
||||
const current = require('fibers').current
|
||||
|
||||
expect(current).to.exists
|
||||
expect(current).to.not.equal(previous)
|
||||
})
|
||||
|
||||
return fn()
|
||||
})
|
||||
|
||||
it('forwards all arguments (even this)', function () {
|
||||
const self = {}
|
||||
const arg1 = {}
|
||||
const arg2 = {}
|
||||
|
||||
return $coroutine(function (arg1_, arg2_) {
|
||||
expect(this).to.equal(self)
|
||||
expect(arg1_).to.equal(arg1)
|
||||
expect(arg2_).to.equal(arg2)
|
||||
}).call(self, arg1, arg2)
|
||||
})
|
||||
})
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
describe('$wait', function () {
|
||||
it('waits for a promise', function () {
|
||||
return $coroutine(function () {
|
||||
const value = {}
|
||||
const promise = Bluebird.resolve(value)
|
||||
|
||||
expect($wait(promise)).to.equal(value)
|
||||
})()
|
||||
})
|
||||
|
||||
it('handles promise rejection', function () {
|
||||
return $coroutine(function () {
|
||||
const promise = Bluebird.reject('an exception')
|
||||
|
||||
expect(function () {
|
||||
$wait(promise)
|
||||
}).to.throw('an exception')
|
||||
})()
|
||||
})
|
||||
|
||||
it('forwards scalar values', function () {
|
||||
return $coroutine(function () {
|
||||
let value = 'a scalar value'
|
||||
expect($wait(value)).to.equal(value)
|
||||
|
||||
value = [
|
||||
'foo',
|
||||
'bar',
|
||||
'baz'
|
||||
]
|
||||
expect($wait(value)).to.deep.equal(value)
|
||||
|
||||
value = []
|
||||
expect($wait(value)).to.deep.equal(value)
|
||||
|
||||
value = {
|
||||
foo: 'foo',
|
||||
bar: 'bar',
|
||||
baz: 'baz'
|
||||
}
|
||||
expect($wait(value)).to.deep.equal(value)
|
||||
|
||||
value = {}
|
||||
expect($wait(value)).to.deep.equal(value)
|
||||
})()
|
||||
})
|
||||
|
||||
it('handles arrays of promises', function () {
|
||||
return $coroutine(function () {
|
||||
const value1 = {}
|
||||
const value2 = {}
|
||||
|
||||
const promise1 = Bluebird.resolve(value1)
|
||||
const promise2 = Bluebird.resolve(value2)
|
||||
|
||||
const results = $wait([promise1, promise2])
|
||||
expect(results[0]).to.equal(value1)
|
||||
expect(results[1]).to.equal(value2)
|
||||
})()
|
||||
})
|
||||
|
||||
it('handles maps of promises', function () {
|
||||
return $coroutine(function () {
|
||||
const value1 = {}
|
||||
const value2 = {}
|
||||
|
||||
const promise1 = Bluebird.resolve(value1)
|
||||
const promise2 = Bluebird.resolve(value2)
|
||||
|
||||
const results = $wait({
|
||||
foo: promise1,
|
||||
bar: promise2
|
||||
})
|
||||
expect(results.foo).to.equal(value1)
|
||||
expect(results.bar).to.equal(value2)
|
||||
})()
|
||||
})
|
||||
|
||||
it('handles nested arrays/maps', function () {
|
||||
const promise1 = Bluebird.resolve('promise 1')
|
||||
const promise2 = Bluebird.resolve('promise 2')
|
||||
|
||||
return $coroutine(function () {
|
||||
expect($wait({
|
||||
foo: promise1,
|
||||
bar: [
|
||||
promise2,
|
||||
'a scalar'
|
||||
]
|
||||
})).to.deep.equal({
|
||||
foo: 'promise 1',
|
||||
bar: [
|
||||
'promise 2',
|
||||
'a scalar'
|
||||
]
|
||||
})
|
||||
})()
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user