diff --git a/packages/@aws-cdk/aws-s3-assets/README.md b/packages/@aws-cdk/aws-s3-assets/README.md index 3d508070d6a50..aab4c46d9c44d 100644 --- a/packages/@aws-cdk/aws-s3-assets/README.md +++ b/packages/@aws-cdk/aws-s3-assets/README.md @@ -115,6 +115,7 @@ new assets.Asset(this, 'BundledAsset', { }, // Docker bundling fallback image: BundlingDockerImage.fromRegistry('alpine'), + entrypoint: ['/bin/sh', '-c'], command: ['bundle'], }, }); diff --git a/packages/@aws-cdk/core/lib/bundling.ts b/packages/@aws-cdk/core/lib/bundling.ts index c9a9c07e77f34..b1247fd913ea0 100644 --- a/packages/@aws-cdk/core/lib/bundling.ts +++ b/packages/@aws-cdk/core/lib/bundling.ts @@ -13,6 +13,17 @@ export interface BundlingOptions { */ readonly image: BundlingDockerImage; + /** + * The entrypoint to run in the Docker container. + * + * @example ['/bin/sh', '-c'] + * + * @see https://docs.docker.com/engine/reference/builder/#entrypoint + * + * @default - run the entrypoint defined in the image + */ + readonly entrypoint?: string[]; + /** * The command to run in the Docker container. * @@ -152,7 +163,15 @@ export class BundlingDockerImage { public run(options: DockerRunOptions = {}) { const volumes = options.volumes || []; const environment = options.environment || {}; - const command = options.command || []; + const entrypoint = options.entrypoint?.[0] || null; + const command = [ + ...options.entrypoint?.[1] + ? [...options.entrypoint.slice(1)] + : [], + ...options.command + ? [...options.command] + : [], + ]; const dockerArgs: string[] = [ 'run', '--rm', @@ -164,6 +183,9 @@ export class BundlingDockerImage { ...options.workingDirectory ? ['-w', options.workingDirectory] : [], + ...entrypoint + ? ['--entrypoint', entrypoint] + : [], this.image, ...command, ]; @@ -238,6 +260,13 @@ export enum DockerVolumeConsistency { * Docker run options */ export interface DockerRunOptions { + /** + * The entrypoint to run in the container. + * + * @default - run the entrypoint defined in the image + */ + readonly entrypoint?: string[]; + /** * The command to run in the container. * diff --git a/packages/@aws-cdk/core/test/bundling.test.ts b/packages/@aws-cdk/core/test/bundling.test.ts index e2b0d6b43b98b..258860d65585c 100644 --- a/packages/@aws-cdk/core/test/bundling.test.ts +++ b/packages/@aws-cdk/core/test/bundling.test.ts @@ -171,6 +171,44 @@ nodeunitShim({ test.done(); }, + 'custom entrypoint is passed through to docker exec'(test: Test) { + const spawnSyncStub = sinon.stub(child_process, 'spawnSync').returns({ + status: 0, + stderr: Buffer.from('stderr'), + stdout: Buffer.from('stdout'), + pid: 123, + output: ['stdout', 'stderr'], + signal: null, + }); + + const image = BundlingDockerImage.fromRegistry('alpine'); + image.run({ + entrypoint: ['/cool/entrypoint', '--cool-entrypoint-arg'], + command: ['cool', 'command'], + environment: { + VAR1: 'value1', + VAR2: 'value2', + }, + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + workingDirectory: '/working-directory', + user: 'user:group', + }); + + test.ok(spawnSyncStub.calledWith('docker', [ + 'run', '--rm', + '-u', 'user:group', + '-v', '/host-path:/container-path:delegated', + '--env', 'VAR1=value1', + '--env', 'VAR2=value2', + '-w', '/working-directory', + '--entrypoint', '/cool/entrypoint', + 'alpine', + '--cool-entrypoint-arg', + 'cool', 'command', + ], { stdio: ['ignore', process.stderr, 'inherit'] })); + test.done(); + }, + 'cp utility copies from an image'(test: Test) { // GIVEN const containerId = '1234567890abcdef1234567890abcdef';