in src/docker/DockerodeApiClient/DockerodeApiClient.ts [71:144]
public async execInContainer(context: IActionContext, ref: string, command: string[] | DockerExecCommandProvider, options?: DockerExecOptions, token?: CancellationToken): Promise<{ stdout: string, stderr: string }> {
// NOTE: Dockerode's exec() doesn't seem to work with Windows against the socket endpoint.
// https://github.com/apocas/dockerode/issues/534
const commandProvider = Array.isArray(command) ? () => command : command;
if (isWindows()) {
let dockerCommand = `${dockerExePath(context)} exec `;
if (options?.user) {
dockerCommand += `--user "${options.user}" `;
}
dockerCommand += `"${ref}" ${commandProvider('windows').join(' ')}`;
// Copy the Docker environment settings in
const newEnv: NodeJS.ProcessEnv = cloneObject(process.env);
addDockerSettingsToEnv(newEnv, process.env);
const { stdout, stderr } = await execStreamAsync(dockerCommand, { env: newEnv }, token);
return { stdout, stderr };
} else {
const container = this.dockerodeClient.getContainer(ref);
const exec = await container.exec({
AttachStderr: true,
AttachStdout: true,
Cmd: commandProvider('linux'),
User: options?.user
});
const execStream = await exec.start({
});
return new Promise<{ stdout: string, stderr: string }>(
(resolve, reject) => {
const stdoutChunks: Buffer[] = [];
const stderrChunks: Buffer[] = [];
const stdout = new stream.PassThrough();
const stderr = new stream.PassThrough();
// TODO: Get demuxStream() included in type definition.
container.modem.demuxStream(execStream, stdout, stderr);
stdout.on('data', chunk => {
stdoutChunks.push(chunk);
});
stderr.on('data', chunk => {
stderrChunks.push(chunk);
});
execStream.on('end', async () => {
try {
const inspectInfo = await exec.inspect();
const stdoutOutput = bufferToString(Buffer.concat(stdoutChunks));
const stderrOutput = bufferToString(Buffer.concat(stderrChunks));
if (inspectInfo.ExitCode) {
reject(new Error(stderrOutput || stdoutOutput));
} else {
resolve({ stdout: stdoutOutput, stderr: stderrOutput });
}
} catch (err) {
reject(err);
}
});
});
}
}