Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix #13 Task output buffer unconstrained #16

Merged
merged 1 commit into from
Oct 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
});