1
0
mirror of https://github.com/yldio/copilot.git synced 2024-12-01 07:30:07 +02:00

Initial implementation

This commit is contained in:
geek 2017-05-15 13:18:18 -05:00 committed by Sérgio Ramos
parent 6ea3da5a9e
commit 98f2329fa0
5 changed files with 72 additions and 21 deletions

View File

@ -1 +1,7 @@
# command-tower # command-tower
## Usage
```bash
$ CMON_CERT_PATH=us-sw-1_api_joyent_com/cert.pem CMON_KEY_PATH=us-sw-1_api_joyent_com/key.pem control-tower
```

View File

@ -2,9 +2,15 @@
'use strict'; 'use strict';
const Fs = require('fs');
const ControlTower = require('../'); const ControlTower = require('../');
const tower = new ControlTower();
const cert = process.env.CMON_CERT_PATH ? Fs.readFileSync(process.env.CMON_CERT_PATH) : process.env.CMON_CERT;
const key = process.env.CMON_KEY_PATH ? Fs.readFileSync(process.env.CMON_KEY_PATH) : process.env.CMON_KEY;
const datacenter = 'cmon.us-sw-1.triton.zone:9163';
const tower = new ControlTower({ cmon: { cert, key, datacenter } });
tower.start((err) => { tower.start((err) => {
if (err) { if (err) {
console.error(err); console.error(err);

View File

@ -5,12 +5,10 @@ const PortalData = require('portal-data');
const VAsync = require('vasync'); const VAsync = require('vasync');
const internals = {};
module.exports = class { module.exports = class {
constructor (options) { constructor (options) {
options = options || {}; options = options || {};
this._settings = options;
this._data = new PortalData(options.data); this._data = new PortalData(options.data);
this._cmon = new CMonClient(options.cmon); this._cmon = new CMonClient(options.cmon);
this._deployments = {}; this._deployments = {};
@ -25,6 +23,10 @@ module.exports = class {
this._poll(); this._poll();
this._data.deploymentChanges((err, changes) => { this._data.deploymentChanges((err, changes) => {
if (err) {
console.error(err);
}
if (changes) { if (changes) {
this._refreshContainers(changes.id); this._refreshContainers(changes.id);
} }
@ -34,14 +36,13 @@ module.exports = class {
_refreshContainers (deploymentId) { _refreshContainers (deploymentId) {
this._data.getServices(deploymentId).then((services) => { this._data.getServices(deploymentId).then((services) => {
this._deployments[deploymentId] = services.containers; this._deployments[deploymentId] = services[0].containers;
}); });
} }
_listContainers () { _listContainers () {
let containers = []; let containers = [];
const deploymentIds = Object.keys(this._deployments); const deploymentIds = Object.keys(this._deployments);
deploymentIds.forEach((deploymentId) => { deploymentIds.forEach((deploymentId) => {
containers = containers.concat(this._deployments[deploymentId]); containers = containers.concat(this._deployments[deploymentId]);
}); });
@ -56,24 +57,68 @@ module.exports = class {
const finish = () => { const finish = () => {
this._isPolling = false; this._isPolling = false;
setTimeout(() => this._poll(), 1000); setTimeout(() => { this._poll(); }, this._settings.frequency || 5000);
}; };
const containers = this._listContainers();
if (!containers || !containers.length) {
return finish();
}
this._isPolling = true; this._isPolling = true;
VAsync.forEachParallel({ VAsync.forEachParallel({
func: this._cmon.metrics, func: (containerId, next) => {
inputs: this._listContainers() this._cmon.metrics(containerId, (err, metrics) => {
if (err) {
return next(err);
}
next(null, { containerId, metrics });
});
},
inputs: containers
}, (err, results) => { }, (err, results) => {
if (err) { if (err) {
console.error(err); console.error(err);
return finish(); return finish();
} }
this._saveMetrics(results, finish); if (!results.successes || !results.successes.length) {
return finish();
}
this._saveMetrics(results.successes, finish);
}); });
} }
_saveMetrics (metrics, cb) { _saveMetrics (successes, cb) {
const metricOperations = successes.map((success) => {
const metrics = this._formatMetrics(success);
return this._data.insertMetrics(success.containerId, metrics);
});
Promise.all(metricOperations).then(() => {
cb(); cb();
}).catch((err) => {
cb(err);
});
} }
}
_formatMetrics (success) {
const time = success.metrics.find((metric) => {
if (metric.name === 'time_of_day') {
return metric;
}
});
const formatted = success.metrics.map((metric) => {
return {
name: metric.name,
value: metric.metrics[0].value,
time: time.metrics[0].value
};
});
return formatted;
}
};

View File

@ -10,7 +10,7 @@
"lint": "belly-button", "lint": "belly-button",
"rethinkdb-up": "docker run -d -p 8080:8080 -p 28015:28015 -p 29015:29015 --name rethinkdb rethinkdb", "rethinkdb-up": "docker run -d -p 8080:8080 -p 28015:28015 -p 29015:29015 --name rethinkdb rethinkdb",
"rethinkdb-down": "docker rm -f rethinkdb", "rethinkdb-down": "docker rm -f rethinkdb",
"test": "npm run lint && lab -t 40" "test": "npm run lint && lab"
}, },
"keywords": [], "keywords": [],
"author": "wyatt", "author": "wyatt",

View File

@ -2,7 +2,6 @@
const Code = require('code'); const Code = require('code');
const Lab = require('lab'); const Lab = require('lab');
const ControlTower = require('../');
// Test shortcuts // Test shortcuts
@ -13,14 +12,9 @@ const it = lab.it;
const expect = Code.expect; const expect = Code.expect;
const internals = {
options: { data: { test: true, name: 'test' } }
};
describe('start()', () => { describe('start()', () => {
it.skip('starts to listen for service changes and monitors metrics', (done) => { it.skip('starts to listen for service changes and monitors metrics', (done) => {
const controlTower = new ControlTower(internals.options); expect(done).to.exist();
done(); done();
}); });
}); });