diff --git a/packages/portal-api/bootstrap-data.js b/packages/portal-api/bootstrap-data.js index 3a94a61d..b6fe5adb 100644 --- a/packages/portal-api/bootstrap-data.js +++ b/packages/portal-api/bootstrap-data.js @@ -14,7 +14,7 @@ const bootstrap = function () { const data = new Data(); data.connect(() => { - data.createDatacenter({ region: 'us-sw', name: 'us-sw' }, (err, datacenter) => { + data.createDatacenter({ region: 'us-sw-1', name: 'us-sw-1' }, (err, datacenter) => { ifError(err); data.createUser({ firstName: 'Nikola', lastName: 'Tesla', email: 'nikola@tesla.com', login: 'nikola' }, (err, user) => { diff --git a/packages/portal-api/test/example-compose.yml b/packages/portal-api/test/example-compose.yml new file mode 100644 index 00000000..d694b249 --- /dev/null +++ b/packages/portal-api/test/example-compose.yml @@ -0,0 +1,24 @@ +consul: + image: autopilotpattern/consul:0.7.2-r0.8 + restart: always + dns: + - 127.0.0.1 + labels: + - triton.cns.services=consul + ports: + - "8500:8500" + environment: + - CONSUL=consul.svc.30f62ec2-24a2-6f8e-8fad-d46b04c8a0b9.us-sw-1.cns.joyent.com + command: > + /usr/local/bin/containerpilot + /bin/consul agent -server + -config-dir=/etc/consul + -log-level=err + -ui-dir /ui +nats: + image: autopilotpattern/nats:0.9.6-r1.0.0 + restart: always + environment: + - CONSUL=consul.svc.30f62ec2-24a2-6f8e-8fad-d46b04c8a0b9.us-sw-1.cns.joyent.com + - NATS_USER=ruser + - NATS_PASSWORD=H4HelAN diff --git a/packages/portal-data/lib/index.js b/packages/portal-data/lib/index.js index f10e2a3c..07796859 100644 --- a/packages/portal-data/lib/index.js +++ b/packages/portal-data/lib/index.js @@ -768,34 +768,16 @@ module.exports = class Data extends EventEmitter { } _instancesFilter (instanceIds) { - return ({ name, machineId, status }) => { + return (query) => { return new Promise((resolve, reject) => { - const query = { - id: this._db.or(instanceIds) - }; + query.ids = instanceIds; - if (name) { - query.name = name; - } - - if (machineId) { - query.machine_id = machineId; - } - - if (status) { - query.status = status; - } - - this._db.instances.query(query, (err, instances) => { + this.getInstances(query, (err, instances) => { if (err) { return reject(err); } - if (!instances || !instances.length) { - return resolve([]); - } - - resolve(instances.map(Transform.fromInstance)); + resolve(instances); }); }); }; @@ -1004,6 +986,38 @@ module.exports = class Data extends EventEmitter { }); } + getInstances ({ ids, name, machineId, status }, cb) { + const query = {}; + + if (ids) { + query.id = this._db.or(ids); + } + + if (name) { + query.name = name; + } + + if (machineId) { + query.machine_id = machineId; + } + + if (status) { + query.status = status; + } + + this._db.instances.query(query, (err, instances) => { + if (err) { + return cb(err); + } + + if (!instances || !instances.length) { + return cb(null, []); + } + + cb(null, instances.map(Transform.fromInstance)); + }); + } + updateInstance ({ id, status }, cb) { this._db.instances.update(id, { status }, (err, instance) => { if (err) { @@ -1014,6 +1028,107 @@ module.exports = class Data extends EventEmitter { }); } + stopInstances ({ ids }, cb) { + this._db.instances.get(ids, (err, instances) => { + if (err) { + return cb(err); + } + + if (!instances || !instances.length) { + return cb(); + } + + VAsync.forEachParallel({ + func: (instance, next) => { + const container = this._docker.getContainer(instance.machine_id); + + container.stop((err) => { + if (err) { + return next(err); + } + + this.updateInstance({ id: instance.id, status: 'STOPPED' }, next); + }); + }, + inputs: instances + }, (err, results) => { + if (err) { + return cb(err); + } + + this.getInstances({ ids }, cb); + }); + }); + } + + startInstances ({ ids }, cb) { + this._db.instances.get(ids, (err, instances) => { + if (err) { + return cb(err); + } + + if (!instances || !instances.length) { + return cb(); + } + + VAsync.forEachParallel({ + func: (instance, next) => { + const container = this._docker.getContainer(instance.machine_id); + + container.start((err) => { + if (err) { + return next(err); + } + + this.updateInstance({ id: instance.id, status: 'RUNNING' }, next); + }); + }, + inputs: instances + }, (err, results) => { + if (err) { + return cb(err); + } + + this.getInstances({ ids }, cb); + }); + }); + } + + restartInstances ({ ids }, cb) { + this._db.instances.get(ids, (err, instances) => { + if (err) { + return cb(err); + } + + if (!instances || !instances.length) { + return cb(); + } + + VAsync.forEachParallel({ + func: (instance, next) => { + this.updateInstance({ id: instance.id, status: 'RESTARTING' }, () => { + const container = this._docker.getContainer(instance.machine_id); + + container.restart((err) => { + if (err) { + return next(err); + } + + this.updateInstance({ id: instance.id, status: 'RUNNING' }, next); + }); + }); + }, + inputs: instances + }, (err, results) => { + if (err) { + return cb(err); + } + + this.getInstances({ ids }, cb); + }); + }); + } + // packages