From 8b6d28074187a6ccadb5f5aed6e37264aabebe72 Mon Sep 17 00:00:00 2001 From: Sergio Zharinov <zharinov@users.noreply.github.com> Date: Wed, 22 Jan 2020 14:45:21 +0400 Subject: [PATCH] feat(exec): Allow for extra docker commands (#5208) --- lib/util/exec/common.ts | 7 ++++++- lib/util/exec/docker/index.ts | 24 +++++++++++++++++++++--- lib/util/exec/index.ts | 6 ++---- test/util/exec.spec.ts | 26 +++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/lib/util/exec/common.ts b/lib/util/exec/common.ts index 3c8464e14d..c229cf62dd 100644 --- a/lib/util/exec/common.ts +++ b/lib/util/exec/common.ts @@ -20,7 +20,10 @@ export interface ExecConfig { } export type VolumesPair = [string, string]; -export type VolumeOption = string | VolumesPair | null | undefined; +export type VolumeOption = Opt<string | VolumesPair>; + +export type DockerExtraCommand = Opt<string>; +export type DockerExtraCommands = Opt<DockerExtraCommand[]>; export interface DockerOptions { image: string; @@ -28,6 +31,8 @@ export interface DockerOptions { volumes?: Opt<VolumeOption[]>; envVars?: Opt<Opt<string>[]>; cwd?: Opt<string>; + preCommands?: DockerExtraCommands; + postCommands?: DockerExtraCommands; } export interface RawExecOptions extends ChildProcessExecOptions { diff --git a/lib/util/exec/docker/index.ts b/lib/util/exec/docker/index.ts index 2aa4b53155..94e4d9f5e9 100644 --- a/lib/util/exec/docker/index.ts +++ b/lib/util/exec/docker/index.ts @@ -3,6 +3,7 @@ import { VolumesPair, DockerOptions, ExecConfig, + DockerExtraCommands, rawExec, } from '../common'; import { logger } from '../../../logger'; @@ -56,12 +57,24 @@ function prepareVolumes(volumes: VolumeOption[] = []): string[] { }); } +function prepareCommands(commands: DockerExtraCommands = []): string[] { + return commands.filter(command => command && typeof command === 'string'); +} + export async function generateDockerCommand( - cmd: string, + commands: string[], options: DockerOptions, config: ExecConfig ): Promise<string> { - const { image, tag, envVars, cwd, volumes = [] } = options; + const { + image, + tag, + envVars, + cwd, + volumes = [], + preCommands, + postCommands, + } = options; const { localDir, cacheDir, dockerUser } = config; const result = ['docker run --rm']; @@ -83,7 +96,12 @@ export async function generateDockerCommand( await prefetchDockerImage(taggedImage); result.push(taggedImage); - result.push(cmd); + const bashCommand = [ + ...prepareCommands(preCommands), + ...commands, + ...prepareCommands(postCommands), + ].join(' && '); + result.push(`bash -l -c "${bashCommand.replace(/"/g, '\\"')}"`); return result.join(' '); } diff --git a/lib/util/exec/index.ts b/lib/util/exec/index.ts index 578e4a326d..a47b6e9323 100644 --- a/lib/util/exec/index.ts +++ b/lib/util/exec/index.ts @@ -103,10 +103,8 @@ export async function exec( envVars: dockerEnvVars(extraEnv, childEnv), }; - let dockerCommand = commands.join(' && '); - dockerCommand = `bash -l -c "${dockerCommand.replace(/"/g, '\\"')}"`; - dockerCommand = await generateDockerCommand( - dockerCommand, + const dockerCommand = await generateDockerCommand( + commands, dockerOptions, execConfig ); diff --git a/test/util/exec.spec.ts b/test/util/exec.spec.ts index e182903c8d..453f819358 100644 --- a/test/util/exec.spec.ts +++ b/test/util/exec.spec.ts @@ -295,7 +295,7 @@ describe(`Child process execution wrapper`, () => { }, processEnv, inCmd, - inOpts: { docker: { image } }, + inOpts: { docker }, outCmd: [ dockerPullCmd, `docker run --rm --user=foobar ${defaultVolumes} -w "${cwd}" ${image} bash -l -c "${inCmd}"`, @@ -303,6 +303,30 @@ describe(`Child process execution wrapper`, () => { outOpts: [dockerPullOpts, { cwd, encoding, env: envMock.basic }], }, ], + + [ + 'Docker extra commands', + { + execConfig: { + ...execConfig, + binarySource: BinarySource.Docker, + }, + processEnv, + inCmd, + inOpts: { + docker: { + image, + preCommands: ['preCommand1', 'preCommand2', null], + postCommands: ['postCommand1', undefined, 'postCommand2'], + }, + }, + outCmd: [ + dockerPullCmd, + `docker run --rm ${defaultVolumes} -w "${cwd}" ${image} bash -l -c "preCommand1 && preCommand2 && ${inCmd} && postCommand1 && postCommand2"`, + ], + outOpts: [dockerPullOpts, { cwd, encoding, env: envMock.basic }], + }, + ], ]; test.each(testInputs)('%s', async (_msg, testOpts) => { -- GitLab