implement up, down, stop, kill, rm

This commit is contained in:
Unknown 2017-06-10 23:58:22 +02:00
parent 4edf5c01df
commit 4fae99d8e4
8 changed files with 1626 additions and 0 deletions

6
.eslintrc.json Normal file
View file

@ -0,0 +1,6 @@
{
"extends": "es/2015/server",
"rules": {
"no-console" :"off"
}
}

134
.gitignore vendored Normal file
View file

@ -0,0 +1,134 @@
# Created by https://www.gitignore.io/api/node,jetbrains,visualstudiocode
### JetBrains ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# CMake
cmake-build-debug/
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### JetBrains Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/sonarlint
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# End of https://www.gitignore.io/api/node,jetbrains,visualstudiocode

141
index.js Normal file
View file

@ -0,0 +1,141 @@
'use strict';
const { promisify } = require('util');
const exec = promisify(require('child_process').exec);
const logger = require('./lib/log');
const logStandards = function (standards) {
if (standards.stdout.length > 0) {
logger.info(standards.stdout);
}
if (standards.stderr) {
logger.warn(standards.stderr);
}
};
/**
* @param {object} options
* @param {boolean} options.log
* @param {cwd} options.cwd
*/
const up = function (options) {
return new Promise((resolve, reject) => {
const cwd = options.cwd;
exec('docker-compose up -d', { cwd }).then(
standards => {
if (options.log) {
logStandards(standards);
}
return resolve();
},
err => {
logger.error(err.message);
return reject(err);
}
);
});
};
/**
* @param {object} options
* @param {boolean} options.log
* @param {cwd} options.cwd
*/
const down = function (options) {
return new Promise((resolve, reject) => {
const cwd = options.cwd;
exec('docker-compose down', { cwd }).then(
standards => {
if (options.log) {
logStandards(standards);
}
return resolve();
},
err => {
logger.error(err.message);
return reject(err);
}
);
});
};
/**
* @param {object} options
* @param {boolean} options.log
* @param {cwd} options.cwd
*/
const stop = function (options) {
return new Promise((resolve, reject) => {
const cwd = options.cwd;
exec('docker-compose stop', { cwd }).then(
standards => {
if (options.log) {
logStandards(standards);
}
return resolve();
},
err => {
logger.error(err.message);
return reject(err);
}
);
});
};
/**
* @param {object} options
* @param {boolean} options.log
* @param {cwd} options.cwd
*/
const kill = function (options) {
return new Promise((resolve, reject) => {
const cwd = options.cwd;
exec('docker-compose kill', { cwd }).then(
standards => {
if (options.log) {
logStandards(standards);
}
return resolve();
},
err => {
logger.error(err.message);
return reject(err);
}
);
});
};
/**
* @param {object} options
* @param {boolean} options.log
* @param {cwd} options.cwd
*/
const rm = function (options) {
const cwd = options.cwd;
exec('docker-compose rm', { cwd }).then(
standards => {
if (options.log) {
logStandards(standards);
}
},
err => {
logger.error(err.message);
}
);
};
module.exports = { up, kill, down, stop, rm };

25
lib/log.js Normal file
View file

@ -0,0 +1,25 @@
'use strict';
const winston = require('winston');
const LEVELS = {
fatal: 0,
error: 1,
info: 2,
warn: 3,
debug: 4
};
const logger = new winston.Logger({
transports: [
new winston.transports.Console({
level: 'debug',
colorize: true,
json: false,
stringify: true
})
],
levels: LEVELS
});
module.exports = logger;

1204
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

28
package.json Normal file
View file

@ -0,0 +1,28 @@
{
"name": "docker-compose",
"version": "0.2.0",
"main": "index.js",
"scripts": {
"test": "./node_modules/tape/bin/tape test",
"lint": "./node_modules/eslint/bin/eslint.js ."
},
"repository": {
"url": "git@github.com:PDMLab/docker-compose.git"
},
"keywords": [],
"author": "Alexander Zeitler <alexander.zeitler@pdmlab.com>",
"license": "MIT",
"description": "Manage docker-compose from Node.js",
"dependencies": {
"winston": "^2.3.1"
},
"devDependencies": {
"composefile": "^0.3.0",
"dockerode": "^2.4.3",
"eslint": "^3.19.0",
"eslint-config-es": "^0.8.11",
"eslint-plugin-extended": "^0.2.0",
"tape": "^4.6.3",
"tape-promise": "^2.0.1"
}
}

6
test/docker-compose.yml Normal file
View file

@ -0,0 +1,6 @@
version: '2'
services:
db:
image: mongo:3.4
container_name: compose_test_mongodb

82
test/index.js Normal file
View file

@ -0,0 +1,82 @@
'use strict';
const compose = require('../index');
const path = require('path');
const tape = require('tape');
const _test = require('tape-promise').default;
const test = _test(tape);
const Docker = require('dockerode');
const docker = new Docker();
test('ensure container gets started', async assert => {
await compose.up({ cwd: path.join(__dirname), log: true });
docker.listContainers((err, containers) => {
const containerIsRunning = containers.find(container =>
container.Names.includes('/compose_test_mongodb')
);
assert.true(containerIsRunning);
assert.end();
});
});
test('ensure container gets down', async assert => {
await compose.up({ cwd: path.join(__dirname), log: true });
await compose.down({ cwd: path.join(__dirname), log: true });
docker.listContainers((err, containers) => {
// eslint-disable-line
const containerIsRunning = containers.find(container =>
container.Names.includes('/compose_test_mongodb')
);
assert.false(containerIsRunning);
assert.end();
});
});
test('ensure container gets stopped', async assert => {
await compose.up({ cwd: path.join(__dirname), log: true });
await compose.stop({ cwd: path.join(__dirname), log: true });
docker.listContainers((err, containers) => {
// eslint-disable-line
const containerIsRunning = containers.find(container =>
container.Names.includes('/compose_test_mongodb')
);
assert.false(containerIsRunning);
assert.end();
});
});
test('ensure container gets killed', async assert => {
await compose.up({ cwd: path.join(__dirname), log: true });
await compose.kill({ cwd: path.join(__dirname), log: true });
docker.listContainers((err, containers) => {
// eslint-disable-line
const containerIsRunning = containers.find(container =>
container.Names.includes('/compose_test_mongodb')
);
assert.false(containerIsRunning);
assert.end();
});
});
test('teardown', assert => {
docker.listContainers((err, containers) => {
containers.forEach(container => {
container.Names.forEach(name => {
if (name.startsWith('/compose_test_')) {
console.log(`stopping ${container.Id} ${container.Names}`);
docker.getContainer(container.Id).stop();
}
});
});
});
assert.end();
});