myt/lib/docker.js

134 lines
3.8 KiB
JavaScript
Raw Permalink Normal View History

2020-12-02 07:35:26 +00:00
const spawn = require('child_process').spawn;
2020-11-16 13:23:28 +00:00
const execFile = require('child_process').execFile;
const camelToSnake = require('./util').camelToSnake;
2020-11-14 01:38:56 +00:00
2020-12-02 07:35:26 +00:00
const docker = {
async run(image, commandArgs, options, execOptions) {
const args = commandArgs
? [image].concat(commandArgs)
: image;
const execMode = options.detach ? 'exec' : 'spawn';
const child = await this.command('run',
2020-12-02 07:35:26 +00:00
args,
options,
execMode,
execOptions
);
return options.detach
? new Container(child.stdout.trim())
: child;
},
async build(url, options, execOptions) {
return await this.command('build',
2020-12-02 07:35:26 +00:00
url,
options,
'spawn',
execOptions
);
},
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 command(command, args, options, execMode, execOptions) {
2020-12-02 07:35:26 +00:00
const execArgs = [command];
if (options)
for (const option in options) {
execArgs.push(`--${camelToSnake(option)}`);
if (typeof options[option] !== 'boolean')
execArgs.push(options[option]);
2020-11-14 01:38:56 +00:00
}
2020-12-02 07:35:26 +00:00
if (Array.isArray(args))
Array.prototype.push.apply(execArgs, args);
else if (args)
execArgs.push(args);
return await new Promise((resolve, reject) => {
if (execMode == 'spawn') {
if (execOptions === true)
execOptions = {
stdio: [
process.stdin,
process.stdout,
process.stderr
]
};
const child = spawn('docker', execArgs, execOptions || undefined);
child.on('exit', code => {
if (code !== 0) {
2022-06-09 18:41:18 +00:00
const quotedArgs = execArgs
.map(x => /\s/g.test(x) ? `"${x}"` : x)
.join(' ');
reject(new Error(`Docker exit code ${code}: 'docker ${quotedArgs}'`));
2020-12-02 07:35:26 +00:00
} else
resolve(code);
});
} else {
execFile('docker', execArgs, (err, stdout, stderr) => {
if (err)
reject(err);
else
resolve({stdout, stderr});
});
}
});
2020-11-14 01:38:56 +00:00
}
2020-12-02 07:35:26 +00:00
};
2020-11-14 01:38:56 +00:00
2020-12-02 07:35:26 +00:00
class Container {
2020-12-04 09:15:29 +00:00
constructor(id) {
if (!id)
throw new Error('Container id argument is required');
2020-12-02 07:35:26 +00:00
this.id = id;
2020-11-14 01:38:56 +00:00
}
2020-12-02 07:35:26 +00:00
async start(options) {
await docker.command('start', this.id, options);
2020-11-14 01:38:56 +00:00
}
2020-12-02 07:35:26 +00:00
async stop(options) {
await docker.command('stop', this.id, options);
2020-11-14 01:38:56 +00:00
}
2020-12-02 07:35:26 +00:00
async rm(options) {
await docker.command('rm', this.id, options);
2020-11-14 01:38:56 +00:00
}
2020-12-02 07:35:26 +00:00
async inspect(options) {
const child = await docker.command('inspect', this.id, options);
2020-12-02 07:35:26 +00:00
return JSON.parse(child.stdout);
2020-11-14 01:38:56 +00:00
}
async exec(options, command, commandArgs, execMode, execOptions) {
let args = [this.id, command];
if (commandArgs) args = args.concat(commandArgs);
await docker.command('exec', args, options, execMode, execOptions);
}
2020-12-02 07:35:26 +00:00
}
2020-11-16 13:23:28 +00:00
2020-12-04 09:15:29 +00:00
module.exports = docker;
module.exports.Container = Container;