Skip to content

Commit

Permalink
Merge pull request #16 from nicomt/fix-13
Browse files Browse the repository at this point in the history
Fix #13 Task output buffer unconstrained
  • Loading branch information
nicomt authored Oct 25, 2020
2 parents 5ddf0a8 + 0d30b96 commit 52dd608
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 4 deletions.
2 changes: 1 addition & 1 deletion lib/tasks/exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ExecTask {
};

const exec = await container.exec(opt);
const bufferStream = util.buildBufferStream();
const bufferStream = util.buildOutputBufferStream();
const outputStream = await exec.start();

await new Promise((res, rej) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/tasks/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class RunTask {
log.info('Started task');
try {

const bufferStream = util.buildBufferStream();
await this.checkOrPull(this.image, log);
const opt = {
User: this.user,
Expand All @@ -59,6 +58,7 @@ class RunTask {
if (this.environment) opt.Env = this.environment;
if (this.volumes) opt.HostConfig.Binds = this.volumes;

const bufferStream = util.buildOutputBufferStream();
const [res, container] = await this.docker.run(this.image, this.command, bufferStream.stream, opt);

const { Error: error, StatusCode: exitCode } = res;
Expand Down
10 changes: 9 additions & 1 deletion lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const dockerUtil = require('dockerode/lib/util');
const { Writable } = require('stream');
const { StringDecoder } = require('string_decoder');

const MAX_OUTPUT_BUFFER_SIZE = 200000; // 200KB

class Util {

static parseRepositoryTag(image) {
Expand All @@ -21,12 +23,16 @@ class Util {
return Object.entries(env).map(([k, v]) => `${k}${v ? `=${v}` : ''}`);
}

static buildBufferStream() {
static buildOutputBufferStream() {
const decoder = new StringDecoder('utf8');
const res = { buffer: '' };
res.stream = new Writable({
write(chunk, encoding, callback) {
res.buffer += decoder.write(chunk);
if (res.buffer.length > Util.MAX_OUTPUT_BUFFER_SIZE) {
const start = res.buffer.length - Util.MAX_OUTPUT_BUFFER_SIZE;
res.buffer = res.buffer.substring(start);
}
callback();
}
});
Expand All @@ -47,4 +53,6 @@ class Util {

}

Util.MAX_OUTPUT_BUFFER_SIZE = MAX_OUTPUT_BUFFER_SIZE;

module.exports = Util;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
"scripts": {
"start": "node ./bin/cli.js",
"test": "ava",
"test": "ava -T 1m --verbose",
"lint": "eslint ."
},
"author": "Nicolas Martinez",
Expand Down
13 changes: 13 additions & 0 deletions test/tasks/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const path = require('path');
const test = require('ava');
const dockerUtil = require('../util/docker');
const MockLog = require('../mock/log');
const util = require('../../lib/util');
const RunTask = require('../../lib/tasks/run');

const log = new MockLog();
Expand Down Expand Up @@ -202,3 +203,15 @@ test('run: custom workingdir', async (t) => {
t.is(exitCode, 0);
t.is(output, '/tmp');
});

test('run: very long output', async (t) => {
const task = new RunTask('test', {
image: 'busybox',
command: 'sh -c "yes 0123456789 | head -1000000"'
});

const { exitCode, output } = await task.execute(log);
t.is(task.name, 'test');
t.is(exitCode, 0);
t.true(output.length <= util.MAX_OUTPUT_BUFFER_SIZE);
});

0 comments on commit 52dd608

Please # to comment.