Skip to content

Commit eba184e

Browse files
authored
Made it possible to call docker create --add-host via an --extra-host array option (#140)
1 parent 3a0348b commit eba184e

File tree

9 files changed

+88
-30
lines changed

9 files changed

+88
-30
lines changed

src/handler.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,28 @@ export async function handler(argv: any, writeStreams: WriteStreams) {
3737
} else if (argv.list != null) {
3838
checkFolderAndFile(cwd, argv.file);
3939
const pipelineIid = await state.getPipelineIid(cwd);
40-
parser = await Parser.create(cwd, writeStreams, pipelineIid, false, argv.file, argv.home);
40+
parser = await Parser.create({
41+
cwd, writeStreams, pipelineIid, tabCompletionPhase: false, file: argv.file, home: argv.home, extraHosts: argv.extraHost,
42+
});
4143
Commander.runList(parser, writeStreams);
4244
} else if (argv.job) {
4345
checkFolderAndFile(cwd, argv.file);
4446
if (argv.needs === true) {
4547
await state.incrementPipelineIid(cwd);
4648
}
4749
const pipelineIid = await state.getPipelineIid(cwd);
48-
parser = await Parser.create(cwd, writeStreams, pipelineIid, false, argv.file, argv.home);
50+
parser = await Parser.create({
51+
cwd, writeStreams, pipelineIid, tabCompletionPhase: false, file: argv.file, home: argv.home, extraHosts: argv.extraHost,
52+
});
4953
await Commander.runSingleJob(parser, writeStreams, argv.job, argv.needs || false, argv.privileged || false);
5054
} else {
5155
const time = process.hrtime();
5256
checkFolderAndFile(cwd, argv.file);
5357
await state.incrementPipelineIid(cwd);
5458
const pipelineIid = await state.getPipelineIid(cwd);
55-
parser = await Parser.create(cwd, writeStreams, pipelineIid, false, argv.file, argv.home);
59+
parser = await Parser.create({
60+
cwd, writeStreams, pipelineIid, tabCompletionPhase: false, file: argv.file, home: argv.home, extraHosts: argv.extraHost,
61+
});
5662
await Commander.runPipeline(parser, writeStreams, argv.manual || [], argv.privileged || false);
5763
writeStreams.stdout(chalk`{grey pipeline finished} in {grey ${prettyHrtime(process.hrtime(time))}}\n`);
5864
}

src/index.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,22 @@ process.on("unhandledRejection", e => {
9393
description: "Set docker executor to privileged mode",
9494
requiresArg: false,
9595
})
96+
.option("extra-host", {
97+
type: "array",
98+
description: "Add extra docker host entries",
99+
requiresArg: false,
100+
})
96101
.completion("completion", false, async (_, yargsArgv) => {
97102
try {
98103
const cwd = yargsArgv.cwd || process.cwd();
99104
const pipelineIid = await state.getPipelineIid(cwd);
100-
const parser = await Parser.create(cwd, new ProcessWriteStreams(), pipelineIid, true, yargsArgv.file);
105+
const parser = await Parser.create({
106+
cwd,
107+
writeStreams: new ProcessWriteStreams(),
108+
pipelineIid,
109+
tabCompletionPhase: true,
110+
file: yargsArgv.file,
111+
});
101112
return parser.getJobs().map((j) => j.name);
102113
} catch (e) {
103114
return ["Parser-Failed!"];

src/job.ts

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export class Job {
3232
private _prescriptsExitCode = 0;
3333
private readonly jobData: any;
3434
private readonly writeStreams: WriteStreams;
35+
private readonly extraHosts: string[];
3536
private started = false;
3637
private finished = false;
3738
private running = false;
@@ -45,6 +46,7 @@ export class Job {
4546
const globals = opt.globals;
4647
const homeVariables = opt.homeVariables;
4748

49+
this.extraHosts = opt.extraHosts;
4850
this.writeStreams = opt.writeStreams;
4951
this.jobNamePad = opt.namePad;
5052
this.name = opt.name;
@@ -354,6 +356,10 @@ export class Job {
354356
dockerCmd += `docker create -u 0:0 -i ${this.generateInjectSSHAgentOptions()} `;
355357
}
356358

359+
for (const extraHost of this.extraHosts) {
360+
dockerCmd += `--add-host=${extraHost} `;
361+
}
362+
357363
if (this.imageEntrypoint) {
358364
this.imageEntrypoint.forEach((e) => {
359365
dockerCmd += `--entrypoint "${e}" `;

src/parser.ts

+25-26
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,39 @@ import {Utils} from "./utils";
1515
import {assert} from "./asserts";
1616
import * as path from "path";
1717
import {WriteStreams} from "./types/write-streams";
18+
import {ParserOptions} from "./types/parser-options";
1819

1920
export class Parser {
2021

2122
private readonly jobs: Map<string, Job> = new Map();
2223
private readonly stages: Map<string, Stage> = new Map();
23-
private readonly cwd: string;
24-
private readonly writeStreams: WriteStreams;
25-
private readonly file?: string;
26-
private readonly home?: string;
27-
private readonly pipelineIid: number;
24+
private readonly opt: ParserOptions;
2825

2926
private gitRemote: GitRemote | null = null;
3027
private homeVariables: any;
3128

3229
private gitlabData: any;
3330
private _jobNamePad = 0;
34-
private readonly tabCompletionPhase: boolean;
35-
36-
private constructor(cwd: string, writeStreams: WriteStreams, pipelineIid: number, tabCompletionPhase: boolean, home?: string, file?: string) {
37-
this.cwd = cwd;
38-
this.pipelineIid = pipelineIid;
39-
this.tabCompletionPhase = tabCompletionPhase;
40-
this.file = file;
41-
this.home = home;
42-
this.writeStreams = writeStreams;
31+
32+
private constructor(opt: ParserOptions) {
33+
this.opt = opt;
4334
}
4435

4536
get jobNamePad(): number {
4637
return this._jobNamePad;
4738
}
4839

49-
static async create(cwd: string, writeStreams: WriteStreams, pipelineIid: number, tabCompletionPhase: boolean, home?: string, file?: string) {
50-
const parser = new Parser(cwd, writeStreams, pipelineIid, tabCompletionPhase, file, home);
40+
static async create(opt: ParserOptions) {
41+
const writeStreams = opt.writeStreams;
42+
const parser = new Parser(opt);
5143

5244
const time = process.hrtime();
5345
await parser.init();
5446
await parser.initJobs();
5547
await parser.validateNeedsTags();
5648
const parsingTime = process.hrtime(time);
57-
if (!tabCompletionPhase) {
49+
50+
if (!opt.tabCompletionPhase) {
5851
writeStreams.stdout(chalk`{cyan ${"yml files".padEnd(parser.jobNamePad)}} {magentaBright processed} in {magenta ${prettyHrtime(parsingTime)}}\n`);
5952
}
6053

@@ -146,20 +139,23 @@ export class Parser {
146139
}
147140

148141
async init() {
149-
const cwd = this.cwd;
150-
const writeStreams = this.writeStreams;
142+
const cwd = this.opt.cwd;
143+
const writeStreams = this.opt.writeStreams;
144+
const home = this.opt.home;
145+
const file = this.opt.file;
146+
const tabCompletionPhase = this.opt.tabCompletionPhase;
151147

152148
this.gitRemote = await Parser.initGitRemote(cwd);
153-
this.homeVariables = await Parser.initHomeVariables(cwd, this.gitRemote, this.home ?? process.env.HOME ?? "");
149+
this.homeVariables = await Parser.initHomeVariables(cwd, this.gitRemote, home ?? process.env.HOME ?? "");
154150

155151
let ymlPath, yamlDataList: any[] = [];
156-
ymlPath = this.file ? `${cwd}/${this.file}` : `${cwd}/.gitlab-ci.yml`;
152+
ymlPath = file ? `${cwd}/${file}` : `${cwd}/.gitlab-ci.yml`;
157153
const gitlabCiData = await Parser.loadYaml(ymlPath);
158-
yamlDataList = yamlDataList.concat(await Parser.prepareIncludes(gitlabCiData, cwd, writeStreams, this.gitRemote, this.tabCompletionPhase));
154+
yamlDataList = yamlDataList.concat(await Parser.prepareIncludes(gitlabCiData, cwd, writeStreams, this.gitRemote, tabCompletionPhase));
159155

160156
ymlPath = `${cwd}/.gitlab-ci-local.yml`;
161157
const gitlabCiLocalData = await Parser.loadYaml(ymlPath);
162-
yamlDataList = yamlDataList.concat(await Parser.prepareIncludes(gitlabCiLocalData, cwd, writeStreams, this.gitRemote, this.tabCompletionPhase));
158+
yamlDataList = yamlDataList.concat(await Parser.prepareIncludes(gitlabCiLocalData, cwd, writeStreams, this.gitRemote, tabCompletionPhase));
163159

164160
const gitlabData: any = deepExtend({}, ...yamlDataList);
165161

@@ -235,8 +231,10 @@ export class Parser {
235231
async initJobs() {
236232
assert(this.gitRemote != null, "GitRemote isn't set in parser initJobs function");
237233

238-
const pipelineIid = this.pipelineIid;
239-
const cwd = this.cwd;
234+
const writeStreams = this.opt.writeStreams;
235+
const pipelineIid = this.opt.pipelineIid;
236+
const cwd = this.opt.cwd;
237+
const extraHosts = this.opt.extraHosts || [];
240238
const gitlabData = this.gitlabData;
241239

242240
const gitUser = await Parser.initGitUser(cwd);
@@ -249,7 +247,8 @@ export class Parser {
249247

250248
const jobId = await state.getJobId(cwd);
251249
const job = new Job({
252-
writeStreams: this.writeStreams,
250+
extraHosts,
251+
writeStreams,
253252
name: jobName,
254253
namePad: this.jobNamePad,
255254
homeVariables: this.homeVariables,

src/types/job-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ export interface JobOptions {
1313
id: number;
1414
gitRemote: GitRemote;
1515
gitUser: GitUser;
16+
extraHosts: string[];
1617
homeVariables: { [name: string]: string };
1718
}

src/types/parser-options.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {WriteStreams} from "./write-streams";
2+
3+
export interface ParserOptions {
4+
cwd: string;
5+
writeStreams: WriteStreams;
6+
pipelineIid: number;
7+
tabCompletionPhase: boolean;
8+
extraHosts?: string[];
9+
home?: string;
10+
file?: string;
11+
}
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[remote "origin"]
2+
url = [email protected]/gcl/test-case.git
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
test-job:
3+
image: curlimages/curl:7.69.1
4+
script:
5+
- curl -I http://fake-google.com
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {MockWriteStreams} from "../../../src/mock-write-streams";
2+
import {handler} from "../../../src/handler";
3+
import * as chalk from "chalk";
4+
5+
test("add-host <test-job>", async () => {
6+
const writeStreams = new MockWriteStreams();
7+
await handler({
8+
cwd: "tests/test-cases/extra-host",
9+
job: "test-job",
10+
extraHost: ["fake-google.com:142.250.185.206"],
11+
}, writeStreams);
12+
13+
const expected = [
14+
chalk`{blueBright test-job} {greenBright >} HTTP/1.1 404 Not Found`,
15+
];
16+
expect(writeStreams.stdoutLines).toEqual(expect.arrayContaining(expected));
17+
});

0 commit comments

Comments
 (0)