Various updates.
This commit is contained in:
parent
e68f1d64a3
commit
426dbf4fff
|
@ -26,11 +26,15 @@ Xapi.prototype.call = function (method) {
|
|||
params.unshift(this.sessionId);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
return Q.ninvoke(this.xmlrpc, 'methodCall', method, params)
|
||||
.then(function (value) {
|
||||
if ('Success' !== value.Status)
|
||||
{
|
||||
if ('Failure' === value.Status)
|
||||
{
|
||||
throw value.ErrorDescription;
|
||||
}
|
||||
|
||||
throw value;
|
||||
}
|
||||
|
||||
|
@ -43,6 +47,7 @@ Xapi.prototype.connect = function (username, password) {
|
|||
|
||||
return this.call('session.login_with_password', username, password)
|
||||
.then(function (session_id) {
|
||||
console.log(self.xmlrpc.options, session_id);
|
||||
self.sessionId = session_id;
|
||||
});
|
||||
};
|
||||
|
|
435
src/xo.js
435
src/xo.js
|
@ -157,352 +157,6 @@ var Users = RedisCollection.extend({
|
|||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
var Pool = Model.extend({});
|
||||
|
||||
var Pools = MemoryCollection.extend({
|
||||
'model': Pool,
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
var Host = Model.extend({});
|
||||
|
||||
var Hosts = MemoryCollection.extend({
|
||||
'model': Host,
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
var VM = Model.extend({});
|
||||
|
||||
var VMs = MemoryCollection.extend({
|
||||
'model': VM,
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
var Network = Model.extend({});
|
||||
|
||||
var Networks = MemoryCollection.extend({
|
||||
'model': Network,
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
var SR = Model.extend({});
|
||||
|
||||
var SRs = MemoryCollection.extend({
|
||||
'model': SR,
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
var VDI = Model.extend({});
|
||||
|
||||
var VDIs = MemoryCollection.extend({
|
||||
'model': VDI,
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
var PIF = Model.extend({});
|
||||
|
||||
var PIFs = MemoryCollection.extend({
|
||||
'model': PIF,
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
var VIF = Model.extend({});
|
||||
|
||||
var VIFs = MemoryCollection.extend({
|
||||
'model': VIF,
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Collections
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
var VDIs = MemoryCollection.extend({
|
||||
'model': VDI,
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// @todo Really ugly.
|
||||
function refresh(xo, xapi)
|
||||
{
|
||||
var get_records = function (classes) {
|
||||
var promises = [];
|
||||
for (var i = 0, n = classes.length; i < n; i++)
|
||||
{
|
||||
!function (klass) {
|
||||
promises.push(
|
||||
xapi.call(klass +'.get_all_records')
|
||||
.fail(function (error) {
|
||||
console.error(klass, error);
|
||||
return {};
|
||||
})
|
||||
);
|
||||
}(classes[i]);
|
||||
}
|
||||
return Q.all(promises);
|
||||
};
|
||||
|
||||
return get_records([
|
||||
// Main classes.
|
||||
'pool',
|
||||
'host',
|
||||
'VM',
|
||||
|
||||
'network',
|
||||
'SR',
|
||||
'VDI',
|
||||
|
||||
'PIF',
|
||||
'VIF',
|
||||
|
||||
// Associated classes (e.g. metrics).
|
||||
'console',
|
||||
'crashdump',
|
||||
'DR_task',
|
||||
'host_cpu',
|
||||
'host_crashdump',
|
||||
'host_metrics',
|
||||
'host_patch',
|
||||
'message',
|
||||
'PBD',
|
||||
'PCI',
|
||||
'PGPU',
|
||||
'PIF_metrics',
|
||||
'VBD',
|
||||
'VGPU',
|
||||
'VIF_metrics',
|
||||
'VM_appliance',
|
||||
'VM_metrics',
|
||||
'VM_guest_metrics',
|
||||
//'VMPP',
|
||||
//'VTPM',
|
||||
]).spread(function (
|
||||
pools,
|
||||
hosts,
|
||||
vms,
|
||||
|
||||
networks,
|
||||
srs,
|
||||
vdis,
|
||||
|
||||
pifs,
|
||||
vifs,
|
||||
|
||||
consoles,
|
||||
crashdumps,
|
||||
dr_tasks,
|
||||
host_cpus,
|
||||
host_crashdumps,
|
||||
host_metrics,
|
||||
host_patches,
|
||||
messages,
|
||||
pbds,
|
||||
pcis,
|
||||
pgpus,
|
||||
pif_metrics,
|
||||
vbds,
|
||||
vgpus,
|
||||
vif_metrics,
|
||||
vm_appliances,
|
||||
vm_metrics,
|
||||
vm_guest_metrics
|
||||
//vmpps
|
||||
//vtpms
|
||||
) {
|
||||
// Special case for pools.
|
||||
pools = _.values(pools);
|
||||
var pool_uuid = pools[0].id = pools[0].uuid;
|
||||
|
||||
xo.connections[pool_uuid] = xapi;
|
||||
|
||||
// @todo Remove: security concerns.
|
||||
pools[0].sessionId = xapi.sessionId;
|
||||
|
||||
var resolve = function (model, collection, props, include) {
|
||||
/* jshint laxbreak: true */
|
||||
|
||||
if (!_.isArray(props))
|
||||
{
|
||||
props = [props];
|
||||
}
|
||||
|
||||
var helper;
|
||||
if (include)
|
||||
{
|
||||
helper = function (ref) {
|
||||
return collection[ref] || null;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
helper = function (ref) {
|
||||
var model = collection[ref];
|
||||
return model && model.uuid || null;
|
||||
};
|
||||
}
|
||||
|
||||
var map = function (list, iterator) {
|
||||
var result = _.isArray(list) ? [] : {};
|
||||
_.each(list, function (value, key) {
|
||||
result[key] = iterator(value);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
for (var i = 0, n = props.length; i < n; ++i)
|
||||
{
|
||||
var prop = props[i];
|
||||
var ref = model[prop];
|
||||
|
||||
model[prop] = _.isArray(ref)
|
||||
? map(ref, helper)
|
||||
: helper(ref);
|
||||
}
|
||||
};
|
||||
|
||||
// @todo Messages are linked differently.
|
||||
messages = _.groupBy(messages, 'obj_uuid');
|
||||
|
||||
// @todo Cast numerical/boolean properties to correct types.
|
||||
|
||||
// Resolves dependencies.
|
||||
//
|
||||
// 1. Associated objects are included.
|
||||
// 2. Linked objects are relinked using their uuid instead of
|
||||
// their reference.
|
||||
_.each(pools, function (pool) {
|
||||
// @todo Blobs?
|
||||
|
||||
resolve(pool, srs, [
|
||||
'crash_dump_SR',
|
||||
'default_SR',
|
||||
'suspend_image_SR',
|
||||
]);
|
||||
resolve(pool, hosts, 'master');
|
||||
resolve(pool, vdis, [
|
||||
'metadata_VDIs',
|
||||
'redo_log_vdi',
|
||||
]);
|
||||
});
|
||||
_.each(hosts, function (host) {
|
||||
// @todo Blobs?
|
||||
|
||||
resolve(host, srs, [
|
||||
'crash_dump_sr',
|
||||
'local_cache_sr',
|
||||
'suspend_image_SR',
|
||||
]);
|
||||
resolve(host, host_crashdumps, 'host_crashdumps', true);
|
||||
resolve(host, host_cpus, 'host_CPUs', true);
|
||||
resolve(host, host_metrics, 'metrics', true);
|
||||
resolve(host, host_patches, 'patches', true);
|
||||
resolve(host, pbds, 'PBDs', true);
|
||||
resolve(host, pcis, 'PCIs', true);
|
||||
resolve(host, pgpus, 'PGPUs', true);
|
||||
resolve(host, pifs, 'PIFs');
|
||||
resolve(host, vms, 'resident_VMs');
|
||||
});
|
||||
_.each(vms, function (vm) {
|
||||
// @todo Blobs?
|
||||
|
||||
resolve(vm, hosts, [
|
||||
'affinity',
|
||||
'resident_on',
|
||||
]);
|
||||
resolve(vm, vm_appliances, 'appliance', true);
|
||||
resolve(vm, pcis, 'attached_PCIs', true);
|
||||
resolve(vm, vms, [
|
||||
'children', // Snapshots?
|
||||
'parent',
|
||||
'snapshot_of',
|
||||
]);
|
||||
resolve(vm, consoles, 'consoles', true);
|
||||
resolve(vm, crashdumps, 'crash_dumps', true);
|
||||
resolve(vm, vm_guest_metrics, 'guest_metrics', true);
|
||||
vm.messages = messages[vm.uuid] || []; // @todo
|
||||
resolve(vm, vm_metrics, 'metrics', true);
|
||||
//resolve(vm, vmpps, 'protection_policy', true);
|
||||
resolve(vm, srs, 'suspend_SR');
|
||||
resolve(vm, vdis, 'suspend_VDI');
|
||||
resolve(vm, vbds, 'VBDs');
|
||||
resolve(vm, vgpus, 'VGPUs');
|
||||
resolve(vm, vifs, 'VIFs', true); // @todo
|
||||
//resolve(vm, vtpms, 'VTPMs');
|
||||
});
|
||||
_.each(networks, function (network) {
|
||||
// @todo Blobs?
|
||||
|
||||
resolve(network, pifs, 'PIFs');
|
||||
resolve(network, vifs, 'VIFs');
|
||||
});
|
||||
_.each(srs, function (sr) {
|
||||
// @todo Blobs?
|
||||
|
||||
resolve(sr, dr_tasks, 'introduced_by'); // @todo.
|
||||
resolve(sr, pbds, 'PBDs');
|
||||
resolve(sr, vdis, 'VDIs');
|
||||
});
|
||||
_.each(vdis, function (vdi) {
|
||||
resolve(vdi, crashdumps, 'crash_dumps', true);
|
||||
resolve(vdi, pools, 'metadata_of_pool');
|
||||
resolve(vdi, vdis, [
|
||||
'parent',
|
||||
'snapshot_of',
|
||||
'snapshots',
|
||||
]);
|
||||
resolve(vdi, srs, 'SR');
|
||||
resolve(vdi, vbds, 'VBDs');
|
||||
});
|
||||
_.each(pifs, function (pif) {
|
||||
// @todo Bonds, tunnels & VLANs.
|
||||
|
||||
resolve(pif, hosts, 'host');
|
||||
resolve(pif, pif_metrics, 'metrics');
|
||||
resolve(pif, networks, 'network');
|
||||
});
|
||||
_.each(vifs, function (vif) {
|
||||
resolve(vif, vif_metrics, 'metrics');
|
||||
resolve(vif, networks, 'network');
|
||||
resolve(vif, vms, 'VM');
|
||||
});
|
||||
|
||||
// Normalizes the collections.
|
||||
//
|
||||
// 1. The collection is converted to an array.
|
||||
// 2. For each object, an identifier based on its uuid is
|
||||
// created.
|
||||
var normalize = function (items) {
|
||||
return _.map(items, function (item, ref) {
|
||||
item.id = item.uuid;
|
||||
item.pool_uuid = pool_uuid;
|
||||
item.ref = ref;
|
||||
return item;
|
||||
});
|
||||
};
|
||||
|
||||
var opts = {
|
||||
'replace': true,
|
||||
};
|
||||
|
||||
return Q.all([
|
||||
xo.pools.add(pools, opts), // Special case.
|
||||
xo.hosts.add(normalize(hosts), opts),
|
||||
xo.vms.add(normalize(vms), opts),
|
||||
|
||||
xo.networks.add(normalize(networks), opts),
|
||||
xo.srs.add(normalize(srs), opts),
|
||||
xo.vdis.add(normalize(vdis), opts),
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
function Xo()
|
||||
{
|
||||
if ( !(this instanceof Xo) )
|
||||
|
@ -510,27 +164,8 @@ function Xo()
|
|||
return new Xo();
|
||||
}
|
||||
|
||||
var xo = this;
|
||||
|
||||
|
||||
|
||||
// Connections to Xen pools/servers.
|
||||
xo.connections = {};
|
||||
|
||||
//--------------------------------------
|
||||
// Xen objects.
|
||||
|
||||
xo.pools = new Pools();
|
||||
xo.hosts = new Hosts();
|
||||
xo.vms = new VMs();
|
||||
|
||||
xo.networks = new Networks();
|
||||
xo.srs = new SRs();
|
||||
xo.vdis = new VDIs();
|
||||
|
||||
// Connecting classes. (@todo VBD & SR).
|
||||
xo.vifs = new VIFs();
|
||||
xo.pifs = new PIFs();
|
||||
this.connections = {};
|
||||
}
|
||||
require('util').inherits(Xo, require('events').EventEmitter);
|
||||
|
||||
|
@ -557,20 +192,74 @@ Xo.prototype.start = function (cfg) {
|
|||
'indexes': ['email'],
|
||||
});
|
||||
|
||||
xo.xclasses = [
|
||||
'console',
|
||||
'crashdump',
|
||||
'DR_task',
|
||||
'host',
|
||||
'host_cpu',
|
||||
'host_crashdump',
|
||||
'host_metrics',
|
||||
'host_patch',
|
||||
'message',
|
||||
'network',
|
||||
'PBD',
|
||||
'PCI',
|
||||
'PGPU',
|
||||
'PIF',
|
||||
'PIF_metrics',
|
||||
'pool',
|
||||
'SR',
|
||||
'VBD',
|
||||
'VDI',
|
||||
'VGPU',
|
||||
'VIF',
|
||||
'VIF_metrics',
|
||||
'VM',
|
||||
'VM_appliance',
|
||||
'VM_guest_metrics',
|
||||
'VM_metrics',
|
||||
// 'VMPP',
|
||||
// 'VTPM',
|
||||
];
|
||||
xo.xobjs = {};
|
||||
_.each(xo.xclasses, function (xclass) {
|
||||
xo.xobjs[xclass] = new MemoryCollection();
|
||||
});
|
||||
|
||||
// When a server is added we should connect to it and fetch data.
|
||||
var connect = function (server) {
|
||||
var pool_id = server.id;
|
||||
var xapi = new Xapi(server.host);
|
||||
|
||||
xapi.connect(server.username, server.password).then(function () {
|
||||
// @todo Use events.
|
||||
!function helper() {
|
||||
refresh(xo, xapi).then(function () {
|
||||
setTimeout(helper, 5000);
|
||||
}).done();
|
||||
}();
|
||||
var xclasses = xo.xclasses;
|
||||
var xobjs = xo.xobjs;
|
||||
|
||||
return _.map(xclasses, function (xclass) {
|
||||
var collection = xo.xobjs[xclass];
|
||||
var helper = function () {
|
||||
return xapi.call(xclass +'.get_all_records').then(function (records) {
|
||||
_.each(records, function (record) {
|
||||
record.pool = pool_id;
|
||||
});
|
||||
|
||||
return collection.add(records, {
|
||||
'update': true,
|
||||
});
|
||||
}).fail(function (error) {
|
||||
if ('HOST_IS_SLAVE' === error[0])
|
||||
{
|
||||
server.host = error[1];
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
});
|
||||
}).fail(function (error) {
|
||||
console.log(error);
|
||||
}).done();
|
||||
});
|
||||
};
|
||||
// Connect existing servers.
|
||||
xo.servers.get().then(function (servers) {
|
||||
|
|
Loading…
Reference in New Issue