From ce3c55d086eca2c745585df8808c540268f7dab2 Mon Sep 17 00:00:00 2001 From: Nikola Jokic <97525037+nikola-jokic@users.noreply.github.com> Date: Thu, 8 Dec 2022 08:09:51 +0100 Subject: [PATCH] exposing env variables from runner with `DOCKER_` envs to respect docker options set on host (#40) * exposing env variables from runner with DOCKER_ prefix to respect rootless docker * Prioritize DOCKER cli over workflow envs * formatted --- .../docker/src/dockerCommands/container.ts | 3 ++ packages/docker/src/utils.ts | 40 +++++++++++++++++++ packages/docker/tests/utils-test.ts | 39 +++++++++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/packages/docker/src/dockerCommands/container.ts b/packages/docker/src/dockerCommands/container.ts index 68c3f26..116115f 100644 --- a/packages/docker/src/dockerCommands/container.ts +++ b/packages/docker/src/dockerCommands/container.ts @@ -427,6 +427,9 @@ export async function containerRun( dockerArgs.push(args.image) if (args.entryPointArgs) { for (const entryPointArg of args.entryPointArgs) { + if (!entryPointArg) { + continue + } dockerArgs.push(entryPointArg) } } diff --git a/packages/docker/src/utils.ts b/packages/docker/src/utils.ts index fd974c5..4f2bdf7 100644 --- a/packages/docker/src/utils.ts +++ b/packages/docker/src/utils.ts @@ -16,6 +16,7 @@ export async function runDockerCommand( args: string[], options?: RunDockerCommandOptions ): Promise { + options = optionsWithDockerEnvs(options) const pipes = await exec.getExecOutput('docker', args, options) if (pipes.exitCode !== 0) { core.error(`Docker failed with exit code ${pipes.exitCode}`) @@ -24,6 +25,45 @@ export async function runDockerCommand( return Promise.resolve(pipes.stdout) } +export function optionsWithDockerEnvs( + options?: RunDockerCommandOptions +): RunDockerCommandOptions | undefined { + // From https://docs.docker.com/engine/reference/commandline/cli/#environment-variables + const dockerCliEnvs = new Set([ + 'DOCKER_API_VERSION', + 'DOCKER_CERT_PATH', + 'DOCKER_CONFIG', + 'DOCKER_CONTENT_TRUST_SERVER', + 'DOCKER_CONTENT_TRUST', + 'DOCKER_CONTEXT', + 'DOCKER_DEFAULT_PLATFORM', + 'DOCKER_HIDE_LEGACY_COMMANDS', + 'DOCKER_HOST', + 'DOCKER_STACK_ORCHESTRATOR', + 'DOCKER_TLS_VERIFY', + 'BUILDKIT_PROGRESS' + ]) + const dockerEnvs = {} + for (const key in process.env) { + if (dockerCliEnvs.has(key)) { + dockerEnvs[key] = process.env[key] + } + } + + const newOptions = { + workingDir: options?.workingDir, + input: options?.input, + env: options?.env || {} + } + + // Set docker envs or overwrite provided ones + for (const [key, value] of Object.entries(dockerEnvs)) { + newOptions.env[key] = value as string + } + + return newOptions +} + export function sanitize(val: string): string { if (!val || typeof val !== 'string') { return '' diff --git a/packages/docker/tests/utils-test.ts b/packages/docker/tests/utils-test.ts index ec6768d..6211b62 100644 --- a/packages/docker/tests/utils-test.ts +++ b/packages/docker/tests/utils-test.ts @@ -1,4 +1,4 @@ -import { sanitize } from '../src/utils' +import { optionsWithDockerEnvs, sanitize } from '../src/utils' describe('Utilities', () => { it('should return sanitized image name', () => { @@ -9,4 +9,41 @@ describe('Utilities', () => { const validStr = 'teststr8_one' expect(sanitize(validStr)).toBe(validStr) }) + + describe('with docker options', () => { + it('should augment options with docker environment variables', () => { + process.env.DOCKER_HOST = 'unix:///run/user/1001/docker.sock' + process.env.DOCKER_NOTEXIST = 'notexist' + + const optionDefinitions: any = [ + undefined, + {}, + { env: {} }, + { env: { DOCKER_HOST: 'unix://var/run/docker.sock' } } + ] + for (const opt of optionDefinitions) { + let options = optionsWithDockerEnvs(opt) + expect(options).toBeDefined() + expect(options?.env).toBeDefined() + expect(options?.env?.DOCKER_HOST).toBe(process.env.DOCKER_HOST) + expect(options?.env?.DOCKER_NOTEXIST).toBeUndefined() + } + }) + + it('should not overwrite other options', () => { + process.env.DOCKER_HOST = 'unix:///run/user/1001/docker.sock' + const opt = { + workingDir: 'test', + input: Buffer.from('test') + } + + const options = optionsWithDockerEnvs(opt) + expect(options).toBeDefined() + expect(options?.workingDir).toBe(opt.workingDir) + expect(options?.input).toBe(opt.input) + expect(options?.env).toStrictEqual({ + DOCKER_HOST: process.env.DOCKER_HOST + }) + }) + }) })