UNPKG

navy

Version:

Quick and powerful development environments using Docker and Docker Compose

196 lines (151 loc) 5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = createDockerComposeDriver; var _jsYaml = _interopRequireDefault(require("js-yaml")); var _fs = _interopRequireDefault(require("../../util/fs")); var _dockerClient = _interopRequireDefault(require("../../util/docker-client")); var _client = require("./client"); var _service = require("../../service"); const debug = require('debug')('navy:docker-compose'); function getArgsFromOptions(opts, argMap) { return Object.keys(opts).map(key => argMap[key]).filter(arg => arg); } const launchArgMap = { noDeps: '--no-deps', forceRecreate: '--force-recreate' }; function createDockerComposeDriver(navy) { const { exec, getCompiledDockerComposePath } = (0, _client.createComposeClient)(navy); const driver = { async launch(services, opts = {}) { const additionalArgs = []; debug('Got launch', services, opts); if (opts) { additionalArgs.push(...getArgsFromOptions(opts, launchArgMap)); debug('Resolve opts to args', additionalArgs); } if (!services) { services = []; } await exec('up', ['-d', ...additionalArgs, ...services]); }, async destroy() { await exec('kill'); await exec('down', ['-v']); }, async ps(service) { const projectName = navy.normalisedName; const psOptions = { all: true, filters: { label: [`com.docker.compose.project=${projectName}`] } }; if (service) { psOptions.filters.label.push(`com.docker.compose.service=${service}`); } const ps = await _dockerClient.default.listContainers(psOptions); const inspect = await Promise.all(ps.map(container => _dockerClient.default.getContainer(container.Id).inspect())); return inspect.map(service => ({ id: service.Id, name: service.Config.Labels['com.docker.compose.service'], image: service.Config.Image, status: service.State.Running === true ? _service.Status.RUNNING : _service.Status.EXITED, raw: service })); }, async start(services) { await exec('start', services); }, async stop(services) { await exec('stop', services); }, async restart(services) { await exec('restart', services); }, async kill(services) { await exec('kill', services); }, async rm(services) { if (!services) { services = []; } await exec('rm', ['-f', '-v', ...services]); }, async update(services) { if (!services) { services = []; } await exec('pull', services); // only relaunch services which are already running const launchedServiceNames = toLookupTable(await this.getLaunchedServiceNames()); const servicesToRelaunch = services.filter(name => launchedServiceNames[name]); if (servicesToRelaunch.length) { await exec('up', ['-d', '--no-deps', ...servicesToRelaunch]); } }, async spawnLogStream(services) { if (!services) { services = []; } await exec('logs', ['-f', '--tail=250', ...services], { pipeLog: true, maxBuffer: Infinity }); }, async port(service, privatePort, index) { if (index == null) index = 1; const container = (await this.ps(service)).pop(); if (!container) { return null; } const portConfig = container.raw.NetworkSettings.Ports[`${privatePort}/tcp`]; if (!Array.isArray(portConfig) || portConfig.length === 0) { return null; } return Number(portConfig[0].HostPort); }, async writeConfig(config) { const yamlOut = _jsYaml.default.safeDump(config, { skipInvalid: true }); await _fs.default.writeFileAsync(getCompiledDockerComposePath(), yamlOut); debug('Wrote docker-compose.tmp.yml', yamlOut); }, async getConfig() { const output = await exec('config', [], { useOriginalDockerComposeFiles: true, noLog: true }); const config = _jsYaml.default.safeLoad(output); return config; }, async getLaunchedServiceNames() { const projectName = navy.normalisedName; const ps = await _dockerClient.default.listContainers({ all: true, filters: { label: [`com.docker.compose.project=${projectName}`] } }); const names = ps.map(container => container.Labels['com.docker.compose.service']); return names; }, async getAvailableServiceNames() { const config = await driver.getConfig(); return Object.keys(config.services); } }; return driver; } function toLookupTable(keys) { const lookupTable = {}; keys.forEach(key => lookupTable[key] = true); return lookupTable; } module.exports = exports.default;