Various cleanings & minor fix (xapi.js).
This commit is contained in:
parent
7eb0c36a8e
commit
49fcefbf2d
@ -1,27 +1,28 @@
|
||||
# Low level tools.
|
||||
$_ = require 'underscore'
|
||||
|
||||
######################################################################
|
||||
#=====================================================================
|
||||
|
||||
class DynamicProperty
|
||||
class $DynamicProperty
|
||||
|
||||
constructor: (@value, @hooks) ->
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
#=====================================================================
|
||||
|
||||
noop = ->
|
||||
$noop = ->
|
||||
|
||||
copyDeep = (value) ->
|
||||
$copyDeep = (value) ->
|
||||
if value instanceof Array
|
||||
return (copyDeep item for item in value)
|
||||
return ($copyDeep item for item in value)
|
||||
|
||||
if value instanceof Object
|
||||
result = {}
|
||||
result[key] = copyDeep item for key, item of value
|
||||
result[key] = $copyDeep item for key, item of value
|
||||
return result
|
||||
|
||||
return value
|
||||
|
||||
getDeep = (obj, path) ->
|
||||
$getDeep = (obj, path) ->
|
||||
return obj if path.length is 0
|
||||
|
||||
current = obj
|
||||
@ -34,7 +35,7 @@ getDeep = (obj, path) ->
|
||||
|
||||
current[path[i]]
|
||||
|
||||
setDeep = (obj, path, value) ->
|
||||
$setDeep = (obj, path, value) ->
|
||||
throw new Error 'invalid path' if path.length is 0
|
||||
|
||||
current = obj
|
||||
@ -50,7 +51,7 @@ setDeep = (obj, path, value) ->
|
||||
# @param rule Rule of the current item.
|
||||
# @param item Current item.
|
||||
# @param value Value of the generator item.
|
||||
computeValue = (rule, item, value) ->
|
||||
$computeValue = (rule, item, value) ->
|
||||
|
||||
# @param parent The parent object of this entry (necessary for
|
||||
# assignment).
|
||||
@ -61,8 +62,8 @@ computeValue = (rule, item, value) ->
|
||||
helper = (parent, name, spec) ->
|
||||
if not $_.isObject spec
|
||||
parent[name] = spec
|
||||
else if spec instanceof DynamicProperty
|
||||
# If there was no previous value use DynamicProperty.value,
|
||||
else if spec instanceof $DynamicProperty
|
||||
# If there was no previous value use $DynamicProperty.value,
|
||||
# otherwise, just keep the previous value.
|
||||
if parent[name] is undefined
|
||||
# Helper is re-called for the initial value.
|
||||
@ -85,7 +86,7 @@ computeValue = (rule, item, value) ->
|
||||
|
||||
######################################################################
|
||||
|
||||
class MappedCollection
|
||||
class $MappedCollection
|
||||
|
||||
constructor: (spec) ->
|
||||
|
||||
@ -94,8 +95,8 @@ class MappedCollection
|
||||
if $_.isFunction spec
|
||||
ctx =
|
||||
dynamic: (initialValue, hooks) ->
|
||||
new DynamicProperty initialValue, hooks
|
||||
noop: noop
|
||||
new $DynamicProperty initialValue, hooks
|
||||
noop: $noop
|
||||
|
||||
spec = spec.call ctx
|
||||
|
||||
@ -114,7 +115,7 @@ class MappedCollection
|
||||
|
||||
spec.rules or= {}
|
||||
|
||||
# Rules are the core of MappedCollection, they allow to categorize
|
||||
# Rules are the core of $MappedCollection, they allow to categorize
|
||||
# objects and to treat them differently.
|
||||
@_rules = {}
|
||||
|
||||
@ -198,7 +199,7 @@ class MappedCollection
|
||||
|
||||
# If the value is a dynamic property, grabs the initial value
|
||||
# and registers its hooks.
|
||||
if value instanceof DynamicProperty
|
||||
if value instanceof $DynamicProperty
|
||||
hooks = value.hooks
|
||||
|
||||
# Browse hooks for each rules.
|
||||
@ -220,7 +221,7 @@ class MappedCollection
|
||||
# current rule.
|
||||
for key, item of items
|
||||
# Value of the current field.
|
||||
field = getDeep item.value, path
|
||||
field = $getDeep item.value, path
|
||||
|
||||
ctx = {rule, field}
|
||||
ctx.__proto__ = item # Links to the current item.
|
||||
@ -228,7 +229,7 @@ class MappedCollection
|
||||
hook.call ctx, value, key
|
||||
|
||||
# Updates the value if it changed.
|
||||
setDeep item.value, path if ctx.field isnt field
|
||||
$setDeep item.value, path if ctx.field isnt field
|
||||
|
||||
# Checks each hook is correctly defined.
|
||||
{enter, update, exit} = hooks_
|
||||
@ -273,7 +274,7 @@ class MappedCollection
|
||||
value: undefined
|
||||
|
||||
# Computes the value.
|
||||
computeValue rule, item
|
||||
$computeValue rule, item
|
||||
|
||||
# No events for static items.
|
||||
|
||||
@ -306,11 +307,10 @@ class MappedCollection
|
||||
# Adds, updates or removes items from the collections. Items not
|
||||
# present are added, present are updated, and present in the
|
||||
# generated collection but not in the generator are removed.
|
||||
set: (items, options = {}) ->
|
||||
{add, update, remove} = options
|
||||
set: (items, {add, update, remove} = {}) ->
|
||||
add = true if add is undefined
|
||||
update = true if update is undefined
|
||||
remove = true if remove is undefined
|
||||
remove = false if remove is undefined
|
||||
|
||||
itemsToRemove = {}
|
||||
if remove
|
||||
@ -329,7 +329,7 @@ class MappedCollection
|
||||
rule = @_rules[item._ruleName]
|
||||
|
||||
# Compute the new value.
|
||||
computeValue rule, item, value
|
||||
$computeValue rule, item, value
|
||||
|
||||
# Runs related hooks.
|
||||
for hook in @_hooks[rule.name]?.update or []
|
||||
@ -351,7 +351,7 @@ class MappedCollection
|
||||
value: undefined
|
||||
|
||||
# Computes the value.
|
||||
computeValue rule, item, value
|
||||
$computeValue rule, item, value
|
||||
|
||||
# Runs related hooks.
|
||||
for hook in @_hooks[rule.name]?.enter or []
|
||||
@ -369,6 +369,6 @@ class MappedCollection
|
||||
# Removes effectively the item.
|
||||
delete @_byKey[key] @_byRule[ruleName][key]
|
||||
|
||||
######################################################################
|
||||
#=====================================================================
|
||||
|
||||
module.exports = MappedCollection
|
||||
module.exports = $MappedCollection
|
||||
|
@ -1,3 +1,6 @@
|
||||
# Low level tools.
|
||||
$_ = require 'underscore'
|
||||
|
||||
# Async code is easier with fibers (light threads)!
|
||||
$fiber = require 'fibers'
|
||||
|
||||
@ -8,15 +11,26 @@ $fiberize = (fn) ->
|
||||
(args...) ->
|
||||
$fiber(-> fn args...).run()
|
||||
|
||||
# Makes the fiber waits for a number of miliseconds.
|
||||
$sleep = (ms) ->
|
||||
fiber = $fiber.current
|
||||
setTimeout (-> fiber.run()), ms
|
||||
$fiber.yield()
|
||||
|
||||
# Makes an asynchrouneous function synchrouneous (in a fiber).
|
||||
$synchronize = (fn) ->
|
||||
$synchronize = (fn, ctx) ->
|
||||
fn = ctx[fn] if $_.isString fn
|
||||
|
||||
(args...) ->
|
||||
fiber = $fiber.current
|
||||
fn args..., (error, result) ->
|
||||
|
||||
args.push (error, result) ->
|
||||
if error?
|
||||
fiber.throwInto error
|
||||
else
|
||||
fiber.run result
|
||||
fn.apply ctx, args
|
||||
|
||||
$fiber.yield()
|
||||
|
||||
# TODO: remove promises ASAP.
|
||||
@ -32,6 +46,7 @@ $waitForPromise = (promise) ->
|
||||
|
||||
module.exports = {
|
||||
$fiberize
|
||||
$sleep
|
||||
$synchronize
|
||||
$waitForPromise
|
||||
}
|
||||
|
@ -13,9 +13,6 @@ $_ = require 'underscore'
|
||||
# HTTP(s) middleware framework.
|
||||
$connect = require 'connect'
|
||||
|
||||
# Async code is easier with fibers (light threads)!
|
||||
$fiber = require 'fibers'
|
||||
|
||||
# Configuration handling.
|
||||
$nconf = require 'nconf'
|
||||
|
||||
|
@ -199,7 +199,10 @@ module.exports = (refsToUUIDs) ->
|
||||
|
||||
iSCSI_name: (value) -> value.other_config?.iscsi_iqn
|
||||
|
||||
memory: {} # TODO
|
||||
memory: { # TODO
|
||||
usage: 0
|
||||
size: 0
|
||||
}
|
||||
|
||||
power_state: 'Running' # TODO
|
||||
|
||||
|
@ -1,20 +1,13 @@
|
||||
# Async code is easier with fibers (light threads) and futures!
|
||||
Fiber = require 'fibers'
|
||||
Future = require 'fibers/future'
|
||||
$xmlrpc = require 'xmlrpc'
|
||||
|
||||
xmlrpc = require 'xmlrpc'
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Helpers for dealing with fibers.
|
||||
{$sleep, $synchronize} = require './fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
sleep = (ms) ->
|
||||
fiber = Fiber.current;
|
||||
setTimeout (-> fiber.run()), ms
|
||||
Fiber.yield()
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# Note: All methods are synchroneous (using fibers), `.future()` may
|
||||
# be used to make them asynchroneous.
|
||||
# Note: All methods are synchroneous (using fibers).
|
||||
class XAPI
|
||||
|
||||
constructor: ({@host, @username, @password}) ->
|
||||
@ -28,12 +21,16 @@ class XAPI
|
||||
# Makes sure there is not session id left.
|
||||
delete @sessionId
|
||||
|
||||
@xmlrpc = xmlrpc.createSecureClient {
|
||||
@xmlrpc = $xmlrpc.createSecureClient {
|
||||
hostname: @host
|
||||
port: '443'
|
||||
rejectUnauthorized: false
|
||||
}
|
||||
|
||||
# Make `methodCall()` synchroneous.
|
||||
@xmlrpc.methodCall = $synchronize 'methodCall', @xmlrpc
|
||||
|
||||
# Logs in.
|
||||
@logIn()
|
||||
|
||||
call: (method, args...) ->
|
||||
@ -42,11 +39,8 @@ class XAPI
|
||||
args.unshift @sessionId if @sessionId
|
||||
|
||||
do helper = =>
|
||||
future = new Future()
|
||||
@xmlrpc.methodCall method, args, future.resolver()
|
||||
|
||||
try
|
||||
result = future.wait()
|
||||
result = @xmlrpc.methodCall method, args
|
||||
|
||||
# Returns the plain result if it does not have a valid XAPI format.
|
||||
return result unless result.Status?
|
||||
@ -80,7 +74,7 @@ class XAPI
|
||||
# I would like to be able to use a shorter delay but for some
|
||||
# reason, when we connect to XAPI at a give moment, the
|
||||
# connection hangs.
|
||||
Fiber.sleep(500)
|
||||
$sleep 500
|
||||
helper()
|
||||
|
||||
# XAPI is sometimes reinitialized and sessions are lost.
|
||||
|
@ -9,9 +9,6 @@ $_ = require 'underscore'
|
||||
# Password hasing.
|
||||
$hashy = require 'hashy'
|
||||
|
||||
# Async code is easier with fibers (light threads)!
|
||||
$fiber = require 'fibers'
|
||||
|
||||
# Redis.
|
||||
$createRedisClient = (require 'then-redis').createClient
|
||||
|
||||
@ -21,9 +18,6 @@ $createRedisClient = (require 'then-redis').createClient
|
||||
# specification.
|
||||
$MappedCollection = require './MappedCollection'
|
||||
|
||||
# Collection where models are stored in memory.
|
||||
$MemoryCollection = require './collection/memory'
|
||||
|
||||
# Collection where models are stored in a Redis DB.
|
||||
$RedisCollection = require './collection/redis'
|
||||
|
||||
@ -38,34 +32,34 @@ $XAPI = require './xapi'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
$randomBytes = $synchronize $crypto.randomBytes
|
||||
$randomBytes = $synchronize 'randomBytes', $crypto
|
||||
|
||||
#=====================================================================
|
||||
# Models and collections.
|
||||
|
||||
class Server extends $Model
|
||||
class $Server extends $Model
|
||||
validate: -> # TODO
|
||||
|
||||
class Servers extends $RedisCollection
|
||||
model: Server
|
||||
class $Servers extends $RedisCollection
|
||||
model: $Server
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
class Token extends $Model
|
||||
class $Token extends $Model
|
||||
@generate: (userId) ->
|
||||
new Token {
|
||||
new $Token {
|
||||
id: ($randomBytes 32).toString 'base64'
|
||||
user_id: userId
|
||||
}
|
||||
|
||||
validate: -> # TODO
|
||||
|
||||
class Tokens extends $RedisCollection
|
||||
model: Token
|
||||
class $Tokens extends $RedisCollection
|
||||
model: $Token
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
class User extends $Model
|
||||
class $User extends $Model
|
||||
default: {
|
||||
permission: 'none'
|
||||
}
|
||||
@ -97,11 +91,11 @@ class User extends $Model
|
||||
|
||||
perms[@get 'permission'] => perms[permission]
|
||||
|
||||
class Users extends $RedisCollection
|
||||
model: User
|
||||
class $Users extends $RedisCollection
|
||||
model: $User
|
||||
|
||||
create: (email, password, permission) ->
|
||||
user = new User {
|
||||
user = new $User {
|
||||
email: email
|
||||
}
|
||||
user.setPassword password
|
||||
@ -111,24 +105,24 @@ class Users extends $RedisCollection
|
||||
|
||||
#=====================================================================
|
||||
|
||||
class XO
|
||||
class $XO
|
||||
|
||||
start: (config) ->
|
||||
# Connects to Redis.
|
||||
redis = $createRedisClient config.redis.uri
|
||||
|
||||
# Creates persistent collections.
|
||||
@servers = new Servers {
|
||||
@servers = new $Servers {
|
||||
connection: redis
|
||||
prefix: 'xo:server'
|
||||
indexes: ['host']
|
||||
}
|
||||
@tokens = new Tokens {
|
||||
@tokens = new $Tokens {
|
||||
connection: redis
|
||||
prefix: 'xo:token'
|
||||
indexes: ['host']
|
||||
}
|
||||
@users = new Users {
|
||||
@users = new $Users {
|
||||
connection: redis
|
||||
prefix: 'xo:user'
|
||||
indexes: ['host']
|
||||
@ -277,4 +271,4 @@ class XO
|
||||
|
||||
#=====================================================================
|
||||
|
||||
module.exports = XO
|
||||
module.exports = $XO
|
||||
|
Loading…
Reference in New Issue
Block a user