mirror of
https://github.com/danbulant/docker-compose
synced 2026-05-24 12:35:32 +00:00
Merge pull request #2 from modjke/master
Custom and multiple YML files support
This commit is contained in:
commit
15164e7912
6 changed files with 397 additions and 423 deletions
154
index.js
154
index.js
|
|
@ -19,133 +19,97 @@ const logStandards = function (standards) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Converts supplied yml files to cli arguments
|
||||||
|
* https://docs.docker.com/compose/reference/overview/#use--f-to-specify-name-and-path-of-one-or-more-compose-files
|
||||||
|
* @param {?(string|string[])} config
|
||||||
|
*/
|
||||||
|
const configToArgs = config => {
|
||||||
|
if (typeof config === 'undefined') {
|
||||||
|
return '';
|
||||||
|
} else if (typeof config === 'string') {
|
||||||
|
return `-f ${config}`;
|
||||||
|
} else if (config instanceof Array) {
|
||||||
|
return config.map(configToArgs).join(' ');
|
||||||
|
}
|
||||||
|
throw new Error(`Invalid argument supplied: ${config}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes docker-compose command with common options
|
||||||
|
* @param {string} command
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
* @param {boolean} [options.log]
|
|
||||||
* @param {string} options.cwd
|
* @param {string} options.cwd
|
||||||
|
* @param {boolean} [options.log]
|
||||||
|
* @param {?(string|string[])} [options.config]
|
||||||
|
*/
|
||||||
|
const execCompose = (command, options) => new Promise((resolve, reject) => {
|
||||||
|
const cmd = `docker-compose ${configToArgs(options.config)} ${command}`;
|
||||||
|
const cwd = options.cwd;
|
||||||
|
|
||||||
|
exec(cmd, { cwd }).then(
|
||||||
|
standards => {
|
||||||
|
if (options.log) {
|
||||||
|
logStandards(standards);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
logger.error(error.message);
|
||||||
|
|
||||||
|
return reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} options
|
||||||
|
* @param {string} options.cwd
|
||||||
|
* @param {boolean} [options.log]
|
||||||
|
* @param {?(string|string[])} [options.config]
|
||||||
*/
|
*/
|
||||||
const up = function (options) {
|
const up = function (options) {
|
||||||
return new Promise((resolve, reject) => {
|
return execCompose('up -d', options);
|
||||||
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 {object} options
|
||||||
* @param {boolean} [options.log]
|
|
||||||
* @param {string} options.cwd
|
* @param {string} options.cwd
|
||||||
|
* @param {boolean} [options.log]
|
||||||
|
* @param {?(string|string[])} [options.config]
|
||||||
*/
|
*/
|
||||||
const down = function (options) {
|
const down = function (options) {
|
||||||
return new Promise((resolve, reject) => {
|
return execCompose('down', options);
|
||||||
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 {object} options
|
||||||
|
* @param {string} options.cwd
|
||||||
* @param {boolean} [options.log]
|
* @param {boolean} [options.log]
|
||||||
* @param {cwd} options.cwd
|
* @param {?(string|string[])} [options.config]
|
||||||
*/
|
*/
|
||||||
const stop = function (options) {
|
const stop = function (options) {
|
||||||
return new Promise((resolve, reject) => {
|
return execCompose('stop', options);
|
||||||
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 {object} options
|
||||||
* @param {boolean} [options.log]
|
|
||||||
* @param {string} options.cwd
|
* @param {string} options.cwd
|
||||||
|
* @param {boolean} [options.log]
|
||||||
|
* @param {?(string|string[])} [options.config]
|
||||||
*/
|
*/
|
||||||
const kill = function (options) {
|
const kill = function (options) {
|
||||||
return new Promise((resolve, reject) => {
|
return execCompose('kill', options);
|
||||||
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 {object} options
|
||||||
* @param {boolean} [options.log]
|
|
||||||
* @param {string} options.cwd
|
* @param {string} options.cwd
|
||||||
|
* @param {boolean} [options.log]
|
||||||
|
* @param {?(string|string[])} [options.config]
|
||||||
*/
|
*/
|
||||||
const rm = function (options) {
|
const rm = function (options) {
|
||||||
return new Promise((resolve, reject) => {
|
return execCompose('rm -f', options);
|
||||||
const cwd = options.cwd;
|
|
||||||
|
|
||||||
exec('docker-compose rm -f', { cwd }).then(
|
|
||||||
standards => {
|
|
||||||
if (options.log) {
|
|
||||||
logStandards(standards);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve();
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
logger.error(err.message);
|
|
||||||
|
|
||||||
return reject(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = { up, kill, down, stop, rm };
|
module.exports = { up, kill, down, stop, rm };
|
||||||
|
|
|
||||||
578
package-lock.json
generated
578
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -3,8 +3,8 @@
|
||||||
"version": "0.4.3",
|
"version": "0.4.3",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "./node_modules/tape/bin/tape test",
|
"test": "./node_modules/.bin/tape test",
|
||||||
"eslint": "./node_modules/eslint/bin/eslint.js ."
|
"eslint": "./node_modules/.bin/eslint ."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "git@github.com:PDMLab/docker-compose.git"
|
"url": "git@github.com:PDMLab/docker-compose.git"
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ compose.up({ cwd: path.join(__dirname), log: true })
|
||||||
|
|
||||||
`docker-compose` accepts these params:
|
`docker-compose` accepts these params:
|
||||||
|
|
||||||
* `cwd {string}`: mandatory folder path to the `docker-compose.yml` (you don't need to specify the name of the `docker-compose.yml` - and custom file names are not supported yet ([PR ahead](https://github.com/PDMLab/docker-compose/issues/1)? 😉))
|
* `cwd {string}`: mandatory folder path to the `docker-compose.yml`
|
||||||
|
* `config {(string|string[])}`: custom and/or multiple yml files can be specified (relative to `cwd`)
|
||||||
* `[log] {boolean}`: optional setting to enable console logging (output of `docker-compose` `stdout`/`stderr` output)
|
* `[log] {boolean}`: optional setting to enable console logging (output of `docker-compose` `stdout`/`stderr` output)
|
||||||
|
|
||||||
## Running the tests
|
## Running the tests
|
||||||
|
|
|
||||||
6
test/docker-compose-2.yml
Normal file
6
test/docker-compose-2.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: alpine:3.7
|
||||||
|
container_name: compose_test_alpine
|
||||||
|
|
@ -3,71 +3,74 @@
|
||||||
const compose = require('../index');
|
const compose = require('../index');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const tape = require('tape');
|
const tape = require('tape');
|
||||||
const _test = require('tape-promise').default;
|
const defaultTest = require('tape-promise').default;
|
||||||
const test = _test(tape);
|
const test = defaultTest(tape);
|
||||||
const Docker = require('dockerode');
|
const Docker = require('dockerode');
|
||||||
const docker = new Docker();
|
const docker = new Docker();
|
||||||
|
|
||||||
|
const isContainerRunning = async name => new Promise((resolve, reject) => {
|
||||||
|
docker.listContainers((err, containers) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const running = containers.find(container => container.Names.includes(name));
|
||||||
|
|
||||||
|
resolve(running);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('ensure container gets started', async assert => {
|
test('ensure container gets started', async assert => {
|
||||||
await compose.up({ cwd: path.join(__dirname), log: true });
|
await compose.up({ cwd: path.join(__dirname), log: true });
|
||||||
|
|
||||||
docker.listContainers((err, containers) => {
|
assert.true(await isContainerRunning('/compose_test_mongodb'));
|
||||||
const containerIsRunning = containers.find(container =>
|
assert.end();
|
||||||
container.Names.includes('/compose_test_mongodb')
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.true(containerIsRunning);
|
|
||||||
assert.end();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ensure container gets down', async assert => {
|
test('ensure container gets down', async assert => {
|
||||||
await compose.up({ cwd: path.join(__dirname), log: true });
|
await compose.up({ cwd: path.join(__dirname), log: true });
|
||||||
await compose.down({ cwd: path.join(__dirname), log: true });
|
await compose.down({ cwd: path.join(__dirname), log: true });
|
||||||
|
|
||||||
docker.listContainers((err, containers) => {
|
assert.false(await isContainerRunning('/compose_test_mongodb'));
|
||||||
// eslint-disable-line
|
assert.end();
|
||||||
const containerIsRunning = containers.find(container =>
|
|
||||||
container.Names.includes('/compose_test_mongodb')
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.false(containerIsRunning);
|
|
||||||
assert.end();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ensure container gets stopped', async assert => {
|
test('ensure container gets stopped', async assert => {
|
||||||
await compose.up({ cwd: path.join(__dirname), log: true });
|
await compose.up({ cwd: path.join(__dirname), log: true });
|
||||||
await compose.stop({ cwd: path.join(__dirname), log: true });
|
await compose.stop({ cwd: path.join(__dirname), log: true });
|
||||||
|
|
||||||
docker.listContainers((err, containers) => {
|
assert.false(await isContainerRunning('/compose_test_mongodb'));
|
||||||
// eslint-disable-line
|
assert.end();
|
||||||
const containerIsRunning = containers.find(container =>
|
|
||||||
container.Names.includes('/compose_test_mongodb')
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.false(containerIsRunning);
|
|
||||||
assert.end();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ensure container gets killed', async assert => {
|
test('ensure container gets killed', async assert => {
|
||||||
await compose.up({ cwd: path.join(__dirname), log: true });
|
await compose.up({ cwd: path.join(__dirname), log: true });
|
||||||
await compose.kill({ cwd: path.join(__dirname), log: true });
|
await compose.kill({ cwd: path.join(__dirname), log: true });
|
||||||
|
|
||||||
docker.listContainers((err, containers) => {
|
assert.false(await isContainerRunning('/compose_test_mongodb'));
|
||||||
// eslint-disable-line
|
assert.end();
|
||||||
const containerIsRunning = containers.find(container =>
|
});
|
||||||
container.Names.includes('/compose_test_mongodb')
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.false(containerIsRunning);
|
test('ensure custom ymls are working', async assert => {
|
||||||
assert.end();
|
const config = './docker-compose-2.yml';
|
||||||
});
|
const cwd = path.join(__dirname);
|
||||||
|
const log = true;
|
||||||
|
|
||||||
|
await compose.up({ cwd, log, config });
|
||||||
|
assert.true(await isContainerRunning('/compose_test_alpine'));
|
||||||
|
|
||||||
|
// config & [config] is the same thing, ensures that multiple configs are handled properly
|
||||||
|
await compose.kill({ cwd, log, config: [ config ]});
|
||||||
|
assert.false(await isContainerRunning('/compose_test_alpine'));
|
||||||
|
assert.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('teardown', assert => {
|
test('teardown', assert => {
|
||||||
docker.listContainers((err, containers) => {
|
docker.listContainers((err, containers) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
containers.forEach(container => {
|
containers.forEach(container => {
|
||||||
container.Names.forEach(name => {
|
container.Names.forEach(name => {
|
||||||
if (name.startsWith('/compose_test_')) {
|
if (name.startsWith('/compose_test_')) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue