feat(portal-api): replace dockerode with node-triton (#532)

This commit is contained in:
Sérgio Ramos 2017-06-29 15:28:56 +01:00 committed by Wyatt Preul
parent 9f3782558f
commit 548c7f5f7e
5 changed files with 123 additions and 52 deletions

View File

@ -1,7 +1,48 @@
'use strict';
const Triton = require('triton');
const Url = require('url');
const Path = require('path');
const Fs = require('fs');
const Data = require('./lib/data');
const {
DOCKER_HOST,
DOCKER_CERT_PATH,
SDC_URL,
SDC_ACCOUNT,
SDC_KEY_ID
} = process.env;
const DOCKER_HOST_URL = DOCKER_HOST ?
Url.parse(DOCKER_HOST) :
{};
const settings = {
db: {
host: process.env.RETHINK_HOST || 'localhost'
},
docker: {
protocol: 'https',
host: DOCKER_HOST_URL.hostname,
port: DOCKER_HOST_URL.port,
ca: DOCKER_CERT_PATH ?
Fs.readFileSync(Path.join(DOCKER_CERT_PATH, 'ca.pem')) :
undefined,
cert: DOCKER_CERT_PATH ?
Fs.readFileSync(Path.join(DOCKER_CERT_PATH, 'cert.pem')) :
undefined,
key: DOCKER_CERT_PATH ?
Fs.readFileSync(Path.join(DOCKER_CERT_PATH, 'key.pem')) :
undefined
},
triton: {
url: SDC_URL,
account: SDC_ACCOUNT,
keyId: SDC_KEY_ID
}
};
const ifError = function (err) {
if (err) {
@ -11,20 +52,24 @@ const ifError = function (err) {
};
const bootstrap = function () {
const data = new Data({
db: {
host: process.env.RETHINK_HOST || 'localhost'
}
});
const data = new Data(settings);
const region = process.env.TRITON_DC || 'us-sw-1';
const login = process.env.TRITON_USER || 'nikola';
data.connect(() => {
data.connect((err) => {
ifError(err);
data.createDatacenter({ region, name: region }, (err, datacenter) => {
ifError(err);
data.createUser({ firstName: 'Nikola', lastName: 'Tesla', email: 'nikola@tesla.com', login }, (err, user) => {
Triton.createClient({
profile: settings.triton
}, (err, { cloudapi }) => {
ifError(err);
cloudapi.getAccount((err, { firstName, lastName, email, login }) => {
ifError(err);
data.createUser({ firstName, lastName, email, login }, (err, user) => {
ifError(err);
data.createPortal({
@ -38,20 +83,8 @@ const bootstrap = function () {
});
});
});
};
/*
const main = function () {
const dropData = new Data({
db: {
host: process.env.RETHINK_HOST || 'localhost'
}
});
});
};
dropData.connect(() => {
dropData._db.r.dbDrop('portal').run(dropData._db._connection, () => {
bootstrap();
});
});
};
*/
bootstrap();

View File

@ -10,6 +10,7 @@ const Util = require('util');
const DockerClient = require('docker-compose-client');
const Dockerode = require('dockerode');
const Hoek = require('hoek');
const Triton = require('triton');
const ParamCase = require('param-case');
const Penseur = require('penseur');
const { DEPLOYMENT_GROUP, SERVICE, HASH } = require('../watch');
@ -70,10 +71,18 @@ module.exports = class Data extends EventEmitter {
this._dockerCompose = new DockerClient(settings.dockerComposeHost);
this._docker = new Dockerode(settings.docker);
this._watcher = null;
this._triton = null;
// if (settings.consul && settings.consul.address) {
// CPClient.config(settings.consul);
// }
Triton.createClient({
profile: settings.triton
}, (err, client) => {
if (err) {
this.emit('error', err);
return;
}
this._triton = client.cloudapi;
});
this._dockerCompose.on('error', (err) => {
this.emit('error', err);
@ -1002,8 +1011,11 @@ module.exports = class Data extends EventEmitter {
return next(err);
}
const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]);
container.stop(next);
if (!this._triton) {
return next();
}
this._triton.stopMachine(instance.machine_id, next);
});
},
inputs: instanceIds
@ -1038,8 +1050,11 @@ module.exports = class Data extends EventEmitter {
return next(err);
}
const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]);
container.start(next);
if (!this._triton) {
return next();
}
this._triton.startMachine(instance.machine_id, next);
});
},
inputs: instanceIds
@ -1074,8 +1089,11 @@ module.exports = class Data extends EventEmitter {
return next(err);
}
const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]);
container.restart(next);
if (!this._triton) {
return next();
}
this._triton.rebootMachine(instance.machine_id, next);
});
},
inputs: instanceIds
@ -1127,9 +1145,11 @@ module.exports = class Data extends EventEmitter {
return next(err);
}
const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]);
// Use force in case the container is running. TODO: should we keep force?
container.remove({ force: true }, next);
if (!this._triton) {
return next();
}
this._triton.deleteMachine(instance.machine_id, next);
});
},
inputs: instanceIds
@ -1220,8 +1240,11 @@ module.exports = class Data extends EventEmitter {
VAsync.forEachParallel({
func: (instance, next) => {
const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]);
container.stop(next);
if (!this._triton) {
return next();
}
this._triton.stopMachine(instance.machine_id, next);
},
inputs: instances
}, (err, results) => {
@ -1246,19 +1269,26 @@ module.exports = class Data extends EventEmitter {
VAsync.forEachParallel({
func: (instance, next) => {
const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]);
container.start((err) => {
if (!this._triton) {
return next();
}
this._triton.startMachine(instance.machine_id, (err) => {
if (err) {
return next(err);
}
const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]);
// Update the IPAddress for the instance
container.inspect((err, details) => {
if (err) {
return next(err);
}
this._db.instances.update(instance.id, { ip_address: details.NetworkSettings.IPAddress }, next);
this._db.instances.update(instance.id, {
ip_address: details.NetworkSettings.IPAddress
}, next);
});
});
},
@ -1285,10 +1315,11 @@ module.exports = class Data extends EventEmitter {
VAsync.forEachParallel({
func: (instance, next) => {
this.updateInstance({ id: instance.id, status: 'RESTARTING' }, () => {
const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]);
container.restart(next);
});
if (!this._triton) {
return next();
}
this._triton.rebootMachine(instance.machine_id, next);
},
inputs: instances
}, (err, results) => {

View File

@ -31,7 +31,9 @@ module.exports = class Watcher {
this._queues = {};
this._tritonWatch.on('change', (container) => { return this.onChange(container); });
this._tritonWatch.on('change', (container) => {
return this.onChange(container);
});
this._tritonWatch.on('all', (containers) => {
containers.forEach((container) => {

View File

@ -40,9 +40,9 @@
"param-case": "^2.1.1",
"penseur": "^7.12.3",
"piloted": "^3.1.1",
"portal-watch": "^1.0.0",
"throat": "^4.0.0",
"toppsy": "^1.1.0",
"triton": "^5.2.0",
"triton-watch": "^1.1.0",
"uuid": "^3.1.0",
"vasync": "^1.6.4",

View File

@ -51,6 +51,11 @@ const portalOptions = {
key: DOCKER_CERT_PATH ?
Fs.readFileSync(Path.join(DOCKER_CERT_PATH, 'key.pem')) :
undefined
},
triton: {
url: SDC_URL,
account: SDC_ACCOUNT,
keyId: SDC_KEY_ID
}
},
watch: {