@verdnatura/myt
Version:
MySQL version control
164 lines (139 loc) • 4.73 kB
JavaScript
const spawn = require('child_process').spawn;
const execFile = require('child_process').execFile;
const camelToSnake = require('./util').camelToSnake;
const docker = {
async run(image, commandArgs, options, execOptions, debug) {
const args = commandArgs
? [image].concat(commandArgs)
: image;
const execMode = options.detach ? 'exec' : 'spawn';
const child = await this.command('run',
args,
options,
execMode,
execOptions,
debug
);
return options.detach
? new Container(child.stdout.trim())
: child;
},
async build(url, options, debug) {
if (debug === true && options.progress == null)
options = Object.assign({progress: 'plain'}, options);
return await this.command('build',
url,
options,
'spawn',
undefined,
debug
);
},
async start(id, options) {
const ct = new Container(id);
await ct.start(options);
return ct;
},
async stop(id, options) {
const ct = new Container(id);
return await ct.stop(options);
},
async rm(id, options) {
const ct = new Container(id);
return await ct.rm(options);
},
async inspect(id, options) {
const ct = new Container(id);
return await ct.inspect(options);
},
async images(tag, options) {
options = Object.assign({format: 'json'}, options);
const child = await docker.command('images', tag, options);
return JSON.parse(child.stdout || null);
},
async tag(source, target) {
await docker.command('tag', [source, target]);
},
async command(command, args, options, execMode, execOptions, debug) {
const execArgs = [command];
if (options)
for (const option in options) {
const value = options[option];
const param = `--${camelToSnake(option)}`;
if (typeof value == 'boolean') {
execArgs.push (param)
} else if (Array.isArray(value)) {
for (const val of value)
execArgs.push(param, val)
} else {
execArgs.push(param, value);
}
}
if (Array.isArray(args))
Array.prototype.push.apply(execArgs, args);
else if (args)
execArgs.push(args);
const dockerBin = 'docker';
if (debug === true) {
const quotedArgs = execArgs
.map(x => /\s/g.test(x) ? `"${x}"` : x)
.join(' ');
console.debug('Command:', `${dockerBin} ${quotedArgs}`.yellow);
}
if (execMode == 'spawn') {
if (debug === true && !execOptions)
execOptions = {
stdio: [
process.stdin,
process.stdout,
process.stderr
]
};
const child = spawn(dockerBin, execArgs, execOptions);
return await new Promise((resolve, reject) => {
child.on('exit', code => {
if (code !== 0)
reject(new Error(`${dockerBin} exit code ${code}`));
else
resolve(code);
});
});
} else {
return await new Promise((resolve, reject) => {
execFile(dockerBin, execArgs, (err, stdout, stderr) => {
if (err)
reject(err);
else
resolve({stdout, stderr});
});
});
}
}
};
class Container {
constructor(id) {
if (!id)
throw new Error('Container id argument is required');
this.id = id;
}
async start(options) {
await docker.command('start', this.id, options);
}
async stop(options) {
await docker.command('stop', this.id, options);
}
async rm(options) {
await docker.command('rm', this.id, options);
}
async inspect(options) {
const child = await docker.command('inspect', this.id, options);
return JSON.parse(child.stdout || null);
}
async exec(options, command, commandArgs, execMode, execOptions, debug) {
let args = [this.id, command];
if (commandArgs) args = args.concat(commandArgs);
await docker.command('exec', args, options, execMode, execOptions, debug);
}
}
module.exports = docker;
module.exports.Container = Container;