bug: boostrap/start when rethink/docker are ready

This commit is contained in:
geek 2017-08-21 12:03:17 -05:00 committed by Sérgio Ramos
parent 7cce1e6f8e
commit 5f97704c78
11 changed files with 222 additions and 161 deletions

View File

@ -95,11 +95,20 @@ compose-api:
restart: always restart: always
rethinkdb: rethinkdb:
image: rethinkdb image: autopilotpattern/rethinkdb:2.3.5r1
restart: always restart: always
mem_limit: 1g mem_limit: 1g
links:
- consul:consul
env_file:
- _env
environment:
- CONSUL=consul
- CONSUL_AGENT=1
ports: ports:
- 8080:8080 - 8080:8080
expose: expose:
- 28015 - 28015
- 29015 - 29015
dns:
- 127.0.0.1

View File

@ -16,13 +16,15 @@ RUN curl --retry 7 --fail -vo /tmp/consul.zip "https://releases.hashicorp.com/co
&& rm /tmp/consul.zip \ && rm /tmp/consul.zip \
&& mkdir /config && mkdir /config
# Install ContainerPilot # Install Containerpilot
ENV CP_SHA1 056d45f728e9b9c61793d6f994da291d5eebeabd ENV CONTAINERPILOT_VERSION 3.4.1
ENV CONTAINERPILOT_VERSION 3.3.2 RUN export CONTAINERPILOT_CHECKSUM=4d13cfb345de86135ab2271b77516c6b6a7bed3a \
RUN curl -Lo /tmp/containerpilot.tar.gz "https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VERSION}/containerpilot-${CONTAINERPILOT_VERSION}.tar.gz" \ && export archive=containerpilot-${CONTAINERPILOT_VERSION}.tar.gz \
&& echo "${CP_SHA1} /tmp/containerpilot.tar.gz" | sha1sum -c \ && curl -Lso /tmp/${archive} \
&& tar zxf /tmp/containerpilot.tar.gz -C /bin \ "https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VERSION}/${archive}" \
&& rm /tmp/containerpilot.tar.gz && echo "${CONTAINERPILOT_CHECKSUM} /tmp/${archive}" | sha1sum -c \
&& tar zxf /tmp/${archive} -C /bin \
&& rm /tmp/${archive}
# Copy required files # Copy required files
RUN mkdir -p /opt/app/ RUN mkdir -p /opt/app/
@ -41,4 +43,4 @@ ENV BUILD=production
ENV NODE_ENV=production ENV NODE_ENV=production
RUN npm install RUN npm install
CMD ["/bin/containerpilot"] CMD ["containerpilot"]

View File

@ -1,78 +1,85 @@
'use strict'; 'use strict';
const Data = require('portal-api/lib/data');
const Fs = require('fs');
const Path = require('path');
const Piloted = require('piloted');
const Triton = require('triton'); const Triton = require('triton');
const Url = require('url'); const Url = require('url');
const Path = require('path');
const Fs = require('fs');
const Data = require('portal-api/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) : {}; let bootstrapped = false;
let timeoutId;
const loadConfig = function () {
const docker = Piloted.service('docker-compose-api');
const rethink = Piloted.service('rethinkdb');
const settings = { if (docker && rethink && !bootstrapped) {
db: { bootstrapped = true;
host: process.env.RETHINK_HOST || 'localhost' bootstrap({ docker, rethink });
}, } else if (!bootstrapped && !timeoutId) {
docker: { timeoutId = setTimeout(() => {
protocol: 'https', timeoutId = null;
host: DOCKER_HOST_URL.hostname, Piloted.refresh();
port: DOCKER_HOST_URL.port, }, 1000);
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) { Piloted.on('refresh', () => {
if (err) { loadConfig();
console.error(err); });
process.exit(1);
}
}; const bootstrap = function ({ docker, rethink }) {
const settings = {
db: {
host: rethink.address
},
docker: {
protocol: 'https',
host: docker.address,
port: docker.port,
ca: process.env.DOCKER_CERT_PATH
? Fs.readFileSync(Path.join(process.env.DOCKER_CERT_PATH, 'ca.pem'))
: undefined,
cert: process.env.DOCKER_CERT_PATH
? Fs.readFileSync(Path.join(process.env.DOCKER_CERT_PATH, 'cert.pem'))
: undefined,
key: process.env.DOCKER_CERT_PATH
? Fs.readFileSync(Path.join(process.env.DOCKER_CERT_PATH, 'key.pem'))
: undefined
},
triton: {
url: process.env.SDC_URL,
account: process.env.SDC_ACCOUNT,
keyId: process.env.SDC_KEY_ID
}
};
const bootstrap = function() {
const data = new Data(settings); const data = new Data(settings);
const region = process.env.TRITON_DC || 'us-sw-1'; const region = process.env.TRITON_DC || 'us-sw-1';
data.connect(err => { data.connect(err => {
ifError(err); handlerError(err);
data.createDatacenter({ region, name: region }, (err, datacenter) => { data.createDatacenter({ region, name: region }, (err, datacenter) => {
ifError(err); handlerError(err);
Triton.createClient( Triton.createClient(
{ {
profile: settings.triton profile: settings.triton
}, },
(err, { cloudapi }) => { (err, { cloudapi }) => {
ifError(err); handlerError(err);
cloudapi.getAccount((err, { firstName, lastName, email, login }) => { cloudapi.getAccount((err, { firstName, lastName, email, login }) => {
ifError(err); handlerError(err);
data.createUser( data.createUser(
{ firstName, lastName, email, login }, { firstName, lastName, email, login },
(err, user) => { (err, user) => {
ifError(err); handlerError(err);
data.createPortal( data.createPortal(
{ {
@ -80,7 +87,7 @@ const bootstrap = function() {
datacenter datacenter
}, },
(err, portal) => { (err, portal) => {
ifError(err); handlerError(err);
console.log('data bootstrapped'); console.log('data bootstrapped');
process.exit(0); process.exit(0);
} }
@ -94,4 +101,11 @@ const bootstrap = function() {
}); });
}; };
bootstrap(); const handlerError = function (err) {
if (err) {
console.error(err);
process.exit(1);
}
};
loadConfig();

View File

@ -19,9 +19,9 @@
"hapi": "^16.1.0", "hapi": "^16.1.0",
"hoek": "^4.1.1", "hoek": "^4.1.1",
"joi": "^10.6.0", "joi": "^10.6.0",
"joyent-cp-gql-schema": "^1.2.0", "joyent-cp-gql-schema": "^1.5.0",
"piloted": "^3.1.1", "piloted": "^3.1.1",
"portal-api": "^1.3.3", "portal-api": "^1.4.0",
"toppsy": "^1.1.0", "toppsy": "^1.1.0",
"triton": "^5.2.0" "triton": "^5.2.0"
} }

View File

@ -1,106 +1,126 @@
'use strict'; 'use strict';
const Brule = require('brule'); const Brule = require('brule');
const Fs = require('fs');
const Good = require('good'); const Good = require('good');
const Hapi = require('hapi'); const Hapi = require('hapi');
const Toppsy = require('toppsy');
const Portal = require('portal-api');
const Path = require('path'); const Path = require('path');
const Fs = require('fs'); const Piloted = require('piloted');
const Portal = require('portal-api');
const Toppsy = require('toppsy');
const Url = require('url'); const Url = require('url');
const server = new Hapi.Server();
server.connection({ port: 3000 });
const { let started = false;
DOCKER_HOST, let timeoutId;
DOCKER_CERT_PATH, const loadConfig = function () {
SDC_URL, const docker = Piloted.service('docker-compose-api');
SDC_ACCOUNT, const rethink = Piloted.service('rethinkdb');
SDC_KEY_ID
} = process.env;
const DOCKER_HOST_URL = DOCKER_HOST ? Url.parse(DOCKER_HOST) : {}; if (docker && rethink && !started) {
started = true;
const portalOptions = { startServer({ docker, rethink });
data: { } else if (!started && !timeoutId) {
db: { timeoutId = setTimeout(() => {
host: process.env.RETHINK_HOST || 'localhost' timeoutId = null;
}, Piloted.refresh();
docker: { }, 1000);
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
}
},
watch: {
url: SDC_URL,
account: SDC_ACCOUNT,
keyId: SDC_KEY_ID
} }
}; };
const goodOptions = { Piloted.on('refresh', () => {
ops: { loadConfig();
interval: 1000 });
},
reporters: {
consoleReporter: [
{
module: 'good-squeeze',
name: 'Squeeze',
args: [{ response: '*', error: '*' }]
},
{
module: 'good-console'
},
'stdout'
]
}
};
server.register(
[ const startServer = function ({ docker, rethink }) {
Brule, const port = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : 3000;
{
register: Good, const server = new Hapi.Server();
options: goodOptions server.connection({ port });
const portalOptions = {
data: {
db: {
host: rethink.address
},
docker: {
protocol: 'https',
host: docker.address,
port: docker.port,
ca: process.env.DOCKER_CERT_PATH
? Fs.readFileSync(Path.join(process.env.DOCKER_CERT_PATH, 'ca.pem'))
: undefined,
cert: process.env.DOCKER_CERT_PATH
? Fs.readFileSync(Path.join(process.env.DOCKER_CERT_PATH, 'cert.pem'))
: undefined,
key: process.env.DOCKER_CERT_PATH
? Fs.readFileSync(Path.join(process.env.DOCKER_CERT_PATH, 'key.pem'))
: undefined
},
triton: {
url: process.env.SDC_URL,
account: process.env.SDC_ACCOUNT,
keyId: process.env.SDC_KEY_ID
}
}, },
{ watch: {
register: Portal, url: process.env.SDC_URL,
options: portalOptions account: process.env.SDC_ACCOUNT,
}, keyId: process.env.SDC_KEY_ID
{
register: Toppsy,
options: { namespace: 'portal', subsystem: 'api' }
} }
], };
err => {
handlerError(err); const goodOptions = {
server.start(err => { ops: {
interval: 1000
},
reporters: {
consoleReporter: [
{
module: 'good-squeeze',
name: 'Squeeze',
args: [{ response: '*', error: '*' }]
},
{
module: 'good-console'
},
'stdout'
]
}
};
server.register(
[
Brule,
{
register: Good,
options: goodOptions
},
{
register: Portal,
options: portalOptions
},
{
register: Toppsy,
options: { namespace: 'portal', subsystem: 'api' }
}
],
(err) => {
handlerError(err); handlerError(err);
console.log(`server started at http://localhost:${server.info.port}`); server.start((err) => {
}); handlerError(err);
} console.log(`server started at http://localhost:${server.info.port}`);
); });
}
);
};
function handlerError(error) { const handlerError = function (err) {
if (error) { if (err) {
console.error(error); console.error(err);
process.exit(1); process.exit(1);
} }
} };
loadConfig();

View File

@ -10,16 +10,14 @@ RUN export CONSUL_VERSION=0.7.0 \
&& rm /tmp/consul.zip \ && rm /tmp/consul.zip \
&& mkdir /config && mkdir /config
# Add Containerpilot and set its configuration # Install Containerpilot
ENV CONTAINERPILOT_VERSION 3.3.1 ENV CONTAINERPILOT_VERSION 3.4.1
ENV CONTAINERPILOT /etc/containerpilot.json RUN export CONTAINERPILOT_CHECKSUM=4d13cfb345de86135ab2271b77516c6b6a7bed3a \
RUN export CONTAINERPILOT_CHECKSUM=e27c1b9cd1023e622f77bb19914606dee3c9b22c \
&& export archive=containerpilot-${CONTAINERPILOT_VERSION}.tar.gz \ && export archive=containerpilot-${CONTAINERPILOT_VERSION}.tar.gz \
&& curl -Lso /tmp/${archive} \ && curl -Lso /tmp/${archive} \
"https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VERSION}/${archive}" \ "https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VERSION}/${archive}" \
&& echo "${CONTAINERPILOT_CHECKSUM} /tmp/${archive}" | sha1sum -c \ && echo "${CONTAINERPILOT_CHECKSUM} /tmp/${archive}" | sha1sum -c \
&& tar zxf /tmp/${archive} -C /usr/local/bin \ && tar zxf /tmp/${archive} -C /bin \
&& rm /tmp/${archive} && rm /tmp/${archive}
# Add Containerpilot configuration # Add Containerpilot configuration
@ -28,4 +26,4 @@ ENV CONTAINERPILOT /etc/containerpilot.json
COPY bin /bin COPY bin /bin
ENTRYPOINT [] ENTRYPOINT []
CMD ["/usr/local/bin/containerpilot"] CMD ["containerpilot"]

View File

@ -26,13 +26,15 @@ RUN curl --retry 7 --fail -vo /tmp/consul.zip "https://releases.hashicorp.com/co
&& rm /tmp/consul.zip \ && rm /tmp/consul.zip \
&& mkdir /config && mkdir /config
# Install ContainerPilot # Install Containerpilot
ENV CP_SHA1 e27c1b9cd1023e622f77bb19914606dee3c9b22c ENV CONTAINERPILOT_VERSION 3.4.1
ENV CONTAINERPILOT_VERSION 3.3.1 RUN export CONTAINERPILOT_CHECKSUM=4d13cfb345de86135ab2271b77516c6b6a7bed3a \
RUN curl -Lo /tmp/containerpilot.tar.gz "https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VERSION}/containerpilot-${CONTAINERPILOT_VERSION}.tar.gz" \ && export archive=containerpilot-${CONTAINERPILOT_VERSION}.tar.gz \
&& echo "${CP_SHA1} /tmp/containerpilot.tar.gz" | sha1sum -c \ && curl -Lso /tmp/${archive} \
&& tar zxf /tmp/containerpilot.tar.gz -C /bin \ "https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VERSION}/${archive}" \
&& rm /tmp/containerpilot.tar.gz && echo "${CONTAINERPILOT_CHECKSUM} /tmp/${archive}" | sha1sum -c \
&& tar zxf /tmp/${archive} -C /bin \
&& rm /tmp/${archive}
ENV NODE_ENV=production ENV NODE_ENV=production
@ -47,4 +49,4 @@ WORKDIR /opt/app/
RUN npm pack joyent-cp-frontend RUN npm pack joyent-cp-frontend
RUN tar -xzf joyent-cp-frontend*.tgz RUN tar -xzf joyent-cp-frontend*.tgz
CMD ["/bin/containerpilot"] CMD ["containerpilot"]

View File

@ -96,6 +96,10 @@ rethinkdb:
image: autopilotpattern/rethinkdb:2.3.5r1 image: autopilotpattern/rethinkdb:2.3.5r1
restart: always restart: always
mem_limit: 1g mem_limit: 1g
links:
- consul:consul
env_file:
- _env
environment: environment:
- CONSUL=consul - CONSUL=consul
- CONSUL_AGENT=1 - CONSUL_AGENT=1

View File

@ -1,6 +1,6 @@
{ {
"name": "joyent-cp-gql-schema", "name": "joyent-cp-gql-schema",
"version": "1.5.0", "version": "1.5.1",
"license": "MPL-2.0", "license": "MPL-2.0",
"repository": "github:yldio/joyent-portal", "repository": "github:yldio/joyent-portal",
"main": "index.js", "main": "index.js",

View File

@ -1,6 +1,6 @@
{ {
"name": "portal-api", "name": "portal-api",
"version": "1.3.3", "version": "1.4.0",
"description": "", "description": "",
"main": "./lib/index.js", "main": "./lib/index.js",
"scripts": { "scripts": {

View File

@ -45,6 +45,18 @@ prometheus:
env_file: env_file:
- _env - _env
rethinkdb:
image: autopilotpattern/rethinkdb:2.3.5r1
restart: always
mem_limit: 1g
env_file:
- _env
environment:
- CONSUL_AGENT=1
expose:
- 28015
- 29015
############################################################################# #############################################################################
# FRONTEND # FRONTEND