Skip to content

Commit

Permalink
feat: auto_compose, generate docker_compose file via mdeprc
Browse files Browse the repository at this point in the history
  • Loading branch information
AVVS committed Oct 19, 2018
1 parent 96e5891 commit 816fc6d
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 41 deletions.
18 changes: 17 additions & 1 deletion .mdeprc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,21 @@
"nycCoverage": false,
"test_framework": "jest --coverage --coverageDirectory <coverageDirectory> --detectOpenHandles",
"tests": "__tests__/*.js",
"docker_compose": "__tests__/docker-compose.yml"
"auto_compose": true,
"node": "10.12.0",
"tester_flavour": "chrome-tester",
"services": [
"redisSentinel",
"redisCluster",
"rabbitmq",
"postgres"
],
"extras": {
"tester": {
"shm_size": "128m",
"environment": {
"CHROME_PATH": "/usr/bin/chromium-browser"
}
}
}
}
33 changes: 24 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,38 @@ Options:
## Test

```bash
bin/cli.js test <command>
cli.js test <command>

performs tests in docker

Commands:
compose installs compose on the system
init adds basic files for testing
run performs testing
cli.js test compose prepares docker-compose file based on config
cli.js test compose installs compose on the system
cli.js test init adds basic files for testing
cli.js test run performs testing

Options:
--node, -n node version to use when building
[default: "7.8.0"]
[default: "9.3.0"]
--env, -E node environment to build for
[default: "production"]
--project, -p project name where this is used
[default: "makeomatic-deploy"]
[default: "deploy"]
--repository, --repo docker repository to use
[default: "makeomatic"]
--version, -v version of the project to build
[default: "1.5.0"]
[default: "0.0.0-development"]
--pkg package json path
[default: "/Users/vitaly/projects/makeomatic-deploy/package.json"]
--help Show help [boolean]
[default: "/Users/vitaly/projects/@makeomatic/deploy/package.json"]
--docker_compose docker-compose file for testing
[string] [default: "./test/docker-compose.yml"]
--auto_compose [boolean] [default: false]
--tester_flavour [string] [default: "tester"]
--extras any extras for tester docker container, will
be merged [string] [default: {}]
--services enable listed services
[array] [choices: "redis", "redisCluster", "redisSentinel", "postgres",
"rabbitmq"]
--docker_compose_version, --dcv docker-compose version to use
[default: "1.11.2"]
--docker_compose_force, --dcf forces to install local copy of
Expand All @@ -131,4 +142,8 @@ Options:
[boolean] [default: false]
--arbitrary_exec arbitrary commands to exec in docker tester
[array] [default: []]
--pre pre commands to run [array] [default: []]
--nycCoverage set to --no-nycCoverage to disable it
[boolean] [default: true]
--help Show help [boolean]
```
14 changes: 0 additions & 14 deletions __tests__/docker-compose.yml

This file was deleted.

24 changes: 11 additions & 13 deletions bin/cli.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
#!/usr/bin/env node

/* eslint-disable import/no-dynamic-require, no-nested-ternary */
const path = require('path');
const fs = require('fs');
const findUp = require('find-up');
const readPkg = require('read-pkg');
const assert = require('assert');

let parentProject;
try {
// eslint-disable-next-line import/no-dynamic-require
parentProject = require(`${process.cwd()}/package.json`);
if (!parentProject.version) {
throw new Error('package.json missing version');
}
} catch (e) {
throw new Error(`Must contain package.json in the current dir: ${e.message}`);
}
const parentProject = readPkg.sync();
assert(parentProject && parentProject.version, 'Must contain package.json in the current dir');

// get configPath if it's there
const configPath = findUp.sync(['.mdeprc', '.mdeprc.js', '.mdeprc.json']);
// eslint-disable-next-line import/no-dynamic-require
const config = configPath ? JSON.parse(fs.readFileSync(configPath)) : {};
const config = configPath
? configPath.endsWith('.js')
? require(configPath)
: JSON.parse(fs.readFileSync(configPath))
: {};

require('yargs')
.version(false)
Expand All @@ -27,7 +25,7 @@ require('yargs')
.option('node', {
alias: 'n',
describe: 'node version to use when building',
default: '9.3.0',
default: '10.12.0',
})
.option('env', {
alias: 'E',
Expand Down
21 changes: 21 additions & 0 deletions bin/cmds/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,27 @@ exports.builder = yargs => (
default: './test/docker-compose.yml',
normalize: true,
})
.option('auto_compose', {
type: 'boolean',
default: false,
})
.option('tester_flavour', {
type: 'string',
default: 'tester',
})
.option('extras', {
description: 'any extras for tester docker container, will be merged',
type: 'string',
default: {},
coerce(argv) {
return typeof argv === 'string' ? JSON.parse(argv) : argv;
},
})
.option('services', {
type: 'array',
description: 'enable listed services',
choices: Object.keys(require('./test_cmds/auto_compose').SERVICE_MAP),
})
.option('docker_compose_version', {
alias: 'dcv',
describe: 'docker-compose version to use',
Expand Down
113 changes: 113 additions & 0 deletions bin/cmds/test_cmds/auto_compose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/* eslint-disable no-use-before-define, no-template-curly-in-string */
const jsYaml = require('js-yaml');
const os = require('os');
const fs = require('fs');
const hyperid = require('hyperid');
const merge = require('lodash.merge');
const path = require('path');

const SERVICE_MAP = {
redis,
redisCluster,
redisSentinel,
postgres,
rabbitmq,
};

exports.SERVICE_MAP = SERVICE_MAP;
exports.command = 'compose';
exports.desc = 'prepares docker-compose file based on config';
exports.handler = (argv) => {
const getId = hyperid({ fixedLength: true, urlSafe: true });

// Header of the file
const compose = {};
compose.version = '3';
compose.networks = {};
compose.services = {};

// Identification
if (Array.isArray(argv.services) && argv.services.length) {
for (const service of argv.services) {
const ctor = SERVICE_MAP[service];
if (ctor === undefined) {
throw new Error(`no support for ${service}, please add it to @makeomatic/deploy`);
}

ctor(compose, argv);
}
}

// add default tester service
tester(compose, argv);

// finalize and push out to tmp
const dir = os.tmpdir();
const filename = `docker-compose.${getId()}.yml`;
const location = `${dir}/${filename}`;

// write out the file
fs.writeFileSync(location, jsYaml.safeDump(compose));

// rewrite location of docker-compose
argv.docker_compose = location;
};

/**
* Prepares tester declaration
*/
function tester(compose, argv) {
compose.services.tester = merge({
image: argv.tester_image || `makeomatic/node:${argv.node}-${argv.tester_flavour}`,
hostname: 'tester',
working_dir: '/src',
volumes: ['${PWD}:/src'],
environment: {
NODE_ENV: 'test',
},
command: 'tail -f /dev/null',
}, argv.extras.tester);
}

function redisCluster(compose, argv) {
compose.services.redisCluster = merge({
image: 'makeomatic/redis-cluster:3.2.9',
hostname: 'redis-cluster',
}, argv.extras.redisCluster);
}

function redis(compose, argv) {
compose.services.redis = merge({
image: 'redis:4.0.11-alpine',
hostname: 'redis',
expose: ['6379'],
}, argv.extras.redis);
}

function redisSentinel(compose, argv) {
redis(compose, argv);

const entrypoint = path.resolve(__dirname, '../../../templates/redis-sentinel.sh');
compose.services.redisSentinel = merge({
image: 'redis:4.0.11-alpine',
hostname: 'redis-sentinel',
expose: ['26379'],
depends_on: ['redis'],
volumes: [`${entrypoint}:/entrypoint.sh:ro`],
command: '/bin/sh /entrypoint.sh redis',
}, argv.extras.redisSentinel);
}

function postgres(compose, argv) {
compose.services.postgres = merge({
image: 'postgres:10.4-alpine',
hostname: 'postgres',
}, argv.extras.postgres);
}

function rabbitmq(compose, argv) {
compose.services.rabbitmq = merge({
image: 'rabbitmq:3.7.8-management-alpine',
hostname: 'rabbitmq',
}, argv.extras.rabbitmq);
}
16 changes: 14 additions & 2 deletions bin/cmds/test_cmds/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ exports.handler = (argv) => {
chmod('+x', compose);
}

/**
* Generates dynamic docker-compose file based on the presets
*/
if (argv.auto_compose) {
require('./auto_compose').handler(argv);
}

// add link to compose file
argv.compose = ShellString(`${compose} -f ${argv.docker_compose}`);

Expand All @@ -57,12 +64,17 @@ exports.handler = (argv) => {

if (argv.no_cleanup !== true) {
echo(`\nAutomatically cleaning up after ${signal}\n`);
exec(`${dockerCompose} stop; true`);
exec(`${dockerCompose} down; true`);

if (argv.auto_compose) {
echo(`rm ${argv.docker_compose}`);
exec(`rm ${argv.docker_compose}`);
}

// force exit now
if (signal === 'exit') process.exit(code || 0);
} else {
echo(`\nLocal environment detected.\nTo stop containers write:\n\n${dockerCompose} stop;\n${dockerCompose} rm -f -v;\n`);
echo(`\nLocal environment detected.\nTo stop containers write:\n\n${dockerCompose} down;\n`);
}
}

Expand Down
2 changes: 1 addition & 1 deletion bin/cmds/test_cmds/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ exports.handler = async (argv) => {
const { compose } = argv;

// start containers
echo('bringing up containers');
echo(`bringing up containers via ${compose}`);
if (exec(`${compose} up -d`).code !== 0) {
echo('failed to start docker containers. Exit 128');
exit(128);
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,16 @@
"find-up": "^3.0.0",
"glob": "^7.1.3",
"husky": "^1.1.2",
"hyperid": "^1.4.1",
"is": "^3.2.1",
"js-yaml": "^3.12.0",
"lodash.get": "^4.4.2",
"lodash.merge": "^4.6.1",
"lodash.set": "^4.3.2",
"ms-conf": "^3.3.1",
"npm-path": "^2.0.4",
"pino": "^5.8.0",
"read-pkg": "^4.0.1",
"rimraf": "^2.6.2",
"semantic-release": "15.9.x",
"shelljs": "^0.8.2",
Expand Down
26 changes: 26 additions & 0 deletions templates/redis-sentinel.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh

# some settings
dir="/etc/redis-sentinel"
configuration="${dir}/redis-sentinel.conf"
hostname=$1

if [ ! -f "$configuration" ]
then
mkdir -p $dir
apk --no-cache --quiet add bind-tools
ip=$(dig ${hostname} +short)
echo "sentinel myid 6050271ee52c6a1f3302b44fe6793f2e3e0de356" > $configuration
echo "sentinel monitor mservice $ip 6379 1" >> $configuration
echo "sentinel down-after-milliseconds mservice 60000" >> $configuration
echo "sentinel config-epoch mservice 0" >> $configuration
echo "# Generated by CONFIG REWRITE" >> $configuration
echo "port 26379" >> $configuration
echo "dir \"/data\"" >> $configuration
echo "protected-mode no" >> $configuration
echo "sentinel leader-epoch mservice 4" >> $configuration
echo "sentinel current-epoch 4" >> $configuration
chown -R $(id -u redis):$(id -g redis) $dir
fi

exec redis-server /etc/redis-sentinel/redis-sentinel.conf --sentinel
15 changes: 14 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3286,6 +3286,14 @@ husky@^1.1.2:
run-node "^1.0.0"
slash "^2.0.0"

hyperid@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/hyperid/-/hyperid-1.4.1.tgz#5df41b25a86171661b37534c3404655ae7657d29"
integrity sha512-rtuRoJyEPZZEGN25T1PC2/IYxdApJEYbBB+8e7vZMFnfhZV7HobkpUr7z1gZvcxqleg4OVg0YrMEtfmIoV85gQ==
dependencies:
uuid "^3.2.1"
uuid-parse "^1.0.0"

[email protected], iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
Expand Down Expand Up @@ -7666,7 +7674,12 @@ util.promisify@^1.0.0:
define-properties "^1.1.2"
object.getownpropertydescriptors "^2.0.3"

uuid@^3.3.2:
uuid-parse@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/uuid-parse/-/uuid-parse-1.0.0.tgz#f4657717624b0e4b88af36f98d89589a5bbee569"
integrity sha1-9GV3F2JLDkuIrzb5jYlYmlu+5Wk=

uuid@^3.2.1, uuid@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
Expand Down

0 comments on commit 816fc6d

Please sign in to comment.