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