Skip to content

Commit 9417b02

Browse files
authored
chore(core): show Docker build output for BundlingDockerImage.fromAsset() (#12001)
Remove the `-q` option and use a known tag derived from the path to the Dockerfile and the build options. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent f813bff commit 9417b02

File tree

2 files changed

+37
-38
lines changed

2 files changed

+37
-38
lines changed

packages/@aws-cdk/core/lib/bundling.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { spawnSync, SpawnSyncOptions } from 'child_process';
2+
import * as crypto from 'crypto';
23
import { FileSystem } from './fs';
34

45
/**
@@ -108,28 +109,29 @@ export class BundlingDockerImage {
108109
public static fromAsset(path: string, options: DockerBuildOptions = {}) {
109110
const buildArgs = options.buildArgs || {};
110111

112+
// Image tag derived from path and build options
113+
const tagHash = crypto.createHash('sha256').update(JSON.stringify({
114+
path,
115+
...options,
116+
})).digest('hex');
117+
const tag = `cdk-${tagHash}`;
118+
111119
const dockerArgs: string[] = [
112-
'build', '-q',
120+
'build', '-t', tag,
113121
...(options.file ? ['-f', options.file] : []),
114122
...flatten(Object.entries(buildArgs).map(([k, v]) => ['--build-arg', `${k}=${v}`])),
115123
path,
116124
];
117125

118-
const docker = dockerExec(dockerArgs);
119-
120-
const match = docker.stdout.toString().match(/sha256:[a-z0-9]+/);
121-
122-
if (!match) {
123-
throw new Error('Failed to extract image ID from Docker build output');
124-
}
126+
dockerExec(dockerArgs);
125127

126128
// Fingerprints the directory containing the Dockerfile we're building and
127129
// differentiates the fingerprint based on build arguments. We do this so
128130
// we can provide a stable image hash. Otherwise, the image ID will be
129131
// different every time the Docker layer cache is cleared, due primarily to
130132
// timestamps.
131133
const hash = FileSystem.fingerprint(path, { extraHash: JSON.stringify(options) });
132-
return new BundlingDockerImage(match[0], hash);
134+
return new BundlingDockerImage(tag, hash);
133135
}
134136

135137
/** @param image The Docker image */
@@ -166,13 +168,7 @@ export class BundlingDockerImage {
166168
...command,
167169
];
168170

169-
dockerExec(dockerArgs, {
170-
stdio: [ // show Docker output
171-
'ignore', // ignore stdio
172-
process.stderr, // redirect stdout to stderr
173-
'inherit', // inherit stderr
174-
],
175-
});
171+
dockerExec(dockerArgs);
176172
}
177173

178174
/**
@@ -303,7 +299,13 @@ function flatten(x: string[][]) {
303299

304300
function dockerExec(args: string[], options?: SpawnSyncOptions) {
305301
const prog = process.env.CDK_DOCKER ?? 'docker';
306-
const proc = spawnSync(prog, args, options);
302+
const proc = spawnSync(prog, args, options ?? {
303+
stdio: [ // show Docker output
304+
'ignore', // ignore stdio
305+
process.stderr, // redirect stdout to stderr
306+
'inherit', // inherit stderr
307+
],
308+
});
307309

308310
if (proc.error) {
309311
throw proc.error;

packages/@aws-cdk/core/test/bundling.test.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as child_process from 'child_process';
2+
import * as crypto from 'crypto';
23
import * as path from 'path';
34
import { nodeunitShim, Test } from 'nodeunit-shim';
45
import * as sinon from 'sinon';
@@ -46,11 +47,10 @@ nodeunitShim({
4647
},
4748

4849
'bundling with image from asset'(test: Test) {
49-
const imageId = 'sha256:abcdef123456';
5050
const spawnSyncStub = sinon.stub(child_process, 'spawnSync').returns({
5151
status: 0,
5252
stderr: Buffer.from('stderr'),
53-
stdout: Buffer.from(imageId),
53+
stdout: Buffer.from('stdout'),
5454
pid: 123,
5555
output: ['stdout', 'stderr'],
5656
signal: null,
@@ -67,33 +67,27 @@ nodeunitShim({
6767
});
6868
image.run();
6969

70+
const tagHash = crypto.createHash('sha256').update(JSON.stringify({
71+
path: 'docker-path',
72+
buildArgs: {
73+
TEST_ARG: 'cdk-test',
74+
},
75+
})).digest('hex');
76+
const tag = `cdk-${tagHash}`;
77+
7078
test.ok(spawnSyncStub.firstCall.calledWith('docker', [
71-
'build', '-q',
79+
'build', '-t', tag,
7280
'--build-arg', 'TEST_ARG=cdk-test',
7381
'docker-path',
7482
]));
7583

7684
test.ok(spawnSyncStub.secondCall.calledWith('docker', [
7785
'run', '--rm',
78-
imageId,
86+
tag,
7987
]));
8088
test.done();
8189
},
8290

83-
'throws if image id cannot be extracted from build output'(test: Test) {
84-
sinon.stub(child_process, 'spawnSync').returns({
85-
status: 0,
86-
stderr: Buffer.from('stderr'),
87-
stdout: Buffer.from('stdout'),
88-
pid: 123,
89-
output: ['stdout', 'stderr'],
90-
signal: null,
91-
});
92-
93-
test.throws(() => BundlingDockerImage.fromAsset('docker-path'), /Failed to extract image ID from Docker build output/);
94-
test.done();
95-
},
96-
9791
'throws in case of spawnSync error'(test: Test) {
9892
sinon.stub(child_process, 'spawnSync').returns({
9993
status: 0,
@@ -133,11 +127,10 @@ nodeunitShim({
133127
},
134128

135129
'BundlerDockerImage json is the bundler image if building an image'(test: Test) {
136-
const imageId = 'sha256:abcdef123456';
137130
sinon.stub(child_process, 'spawnSync').returns({
138131
status: 0,
139132
stderr: Buffer.from('stderr'),
140-
stdout: Buffer.from(imageId),
133+
stdout: Buffer.from('stdout'),
141134
pid: 123,
142135
output: ['stdout', 'stderr'],
143136
signal: null,
@@ -148,7 +141,11 @@ nodeunitShim({
148141

149142
const image = BundlingDockerImage.fromAsset('docker-path');
150143

151-
test.equals(image.image, imageId);
144+
const tagHash = crypto.createHash('sha256').update(JSON.stringify({
145+
path: 'docker-path',
146+
})).digest('hex');
147+
148+
test.equals(image.image, `cdk-${tagHash}`);
152149
test.equals(image.toJSON(), imageHash);
153150
test.ok(fingerprintStub.calledWith('docker-path', sinon.match({ extraHash: JSON.stringify({}) })));
154151
test.done();

0 commit comments

Comments
 (0)