const path = require('path'); const isRoot = require('is-root'); const hostile = require('hostile'); const colors = require('colors'); const docker = require('docker-compose'); const log = require('../inc/log'); const shell = require('shelljs'); const ProjectEnvironment = require('../classes/ProjectEnvironment'); const installHosts = (hosts) => { if (!isRoot()) { log.warn('Unable to set hosts because you need root privileges'); } else { for (var ip in hosts) { const hostsString = hosts[ip].join(' '); log.log('Installing hosts for %s: %s', ip, hostsString); hostile.set(ip, hostsString); } } }; const runServiceHook = (hook, service, projectEnv) => { const env = projectEnv.getEnv(); const scripts = [ `${hook}.before`, `${hook}.before.${env}`, `${hook}`, `${hook}.${env}`, `${hook}.after`, `${hook}.after.${env}`, ]; let scriptArgument = { service: service, log: (message) => { log.log('%s - %s', colors.bold(service), message); }, env: projectEnv.getEnv(), shell: (cmd) => { shell.cd(path.join(projectEnv.getCwd(), service)); const ret = shell.exec(cmd, { fatal: true }); if (ret.code !== 0) { throw ret.code; } } }; switch (hook) { case "start": scriptArgument.exec = (command, options) => { const opts = { ...projectEnv.getDockerOptions(), ...options }; return docker.exec(service, command, opts); }; break; default: break; } let chain = Promise.resolve(); scripts.forEach(script => { chain = chain.then(() => { return new Promise((resolve, reject) => { try { const scriptFunction = require(path.join(projectEnv.getCwd(), service, script)); log.log(`\nExecuting %s script for %s...`, colors.bold(script), colors.bold(service)); try { Promise .all([scriptFunction({ ...scriptArgument })]) .then(() => { resolve(); }) .catch((e) => { reject(e); }); } catch (ex) { reject(ex); } } catch (ex) { resolve(); } }); }); }); return chain.then(() => { }); }; const runServices = async (projectEnv) => { const services = await projectEnv.getServices(); let preparePromises = []; services.forEach(service => { preparePromises.push(runServiceHook("prepare", service, projectEnv)); }); try { await Promise.all(preparePromises); } catch (e) { log.error(e); return; } await docker.buildAll(projectEnv.getDockerOptions()); await docker.upAll(projectEnv.getDockerOptions()); let startPromises = []; services.forEach(service => { startPromises.push(runServiceHook("start", service, projectEnv)); }); await Promise.all(startPromises); }; module.exports = (env) => { try { const projectEnv = new ProjectEnvironment(process.cwd(), env); log.log("Starting project (%s environment)...", colors.bold(env)); // Install hosts installHosts(projectEnv.getHosts()); // Docker up services runServices(projectEnv); } catch (ex) { log.error(...ex); } };