From 2f8df4395ed7897ce3d450983c694cc40405f330 Mon Sep 17 00:00:00 2001 From: Taylor Ondrey Date: Fri, 14 Jul 2023 13:20:31 -0400 Subject: [PATCH] feat(core): allow user to specify --platform (#26368) Allowing user to provide a `platform` property when bundling docker assets ([ref](https://docs.docker.com/build/building/multi-platform/)). Currently, this is not possible when using an existing Docker image via the [BundlingOptions](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.BundlingOptions.html). You can specify this when building a [DockerImageAsset](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerImageAsset.html#platform), but not when using an image as a builder: Closes #25759. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk-lib/core/lib/bundling.ts | 21 ++++++++++++ .../aws-cdk-lib/core/test/bundling.test.ts | 33 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/packages/aws-cdk-lib/core/lib/bundling.ts b/packages/aws-cdk-lib/core/lib/bundling.ts index 1037c41bfdc42..e54978e093de8 100644 --- a/packages/aws-cdk-lib/core/lib/bundling.ts +++ b/packages/aws-cdk-lib/core/lib/bundling.ts @@ -133,6 +133,15 @@ export interface BundlingOptions { * @default - BundlingFileAccess.BIND_MOUNT */ readonly bundlingFileAccess?: BundlingFileAccess; + + /** + * Platform to build for. _Requires Docker Buildx_. + * + * Specify this property to build images on a specific platform. + * + * @default - no platform specified (the current machine architecture will be used) + */ + readonly platform?: string; } /** @@ -256,6 +265,9 @@ export class BundlingDockerImage { ...options.network ? ['--network', options.network] : [], + ...options.platform + ? ['--platform', options.platform] + : [], ...options.user ? ['-u', options.user] : [], @@ -535,6 +547,15 @@ export interface DockerRunOptions { * @default - no networking options */ readonly network?: string; + + /** + * Set platform if server is multi-platform capable. _Requires Docker Engine API v1.38+_. + * + * Example value: `linux/amd64` + * + * @default - no platform specified + */ + readonly platform?: string; } /** diff --git a/packages/aws-cdk-lib/core/test/bundling.test.ts b/packages/aws-cdk-lib/core/test/bundling.test.ts index 90793758844db..531fec2aca68b 100644 --- a/packages/aws-cdk-lib/core/test/bundling.test.ts +++ b/packages/aws-cdk-lib/core/test/bundling.test.ts @@ -439,6 +439,39 @@ describe('bundling', () => { ], { encoding: 'utf-8', stdio: ['ignore', process.stderr, 'inherit'] })).toEqual(true); }); + test('adding user provided platform', () => { + // GIVEN + sinon.stub(process, 'platform').value('darwin'); + 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 = DockerImage.fromRegistry('alpine'); + + // GIVEN + image.run({ + command: ['cool', 'command'], + platform: 'linux/amd64', + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + workingDirectory: '/working-directory', + user: 'user:group', + }); + + expect(spawnSyncStub.calledWith(dockerCmd, [ + 'run', '--rm', + '--platform', 'linux/amd64', + '-u', 'user:group', + '-v', '/host-path:/container-path:delegated', + '-w', '/working-directory', + 'alpine', + 'cool', 'command', + ], { encoding: 'utf-8', stdio: ['ignore', process.stderr, 'inherit'] })).toEqual(true); + }); + test('adding user provided docker volume options', () => { // GIVEN sinon.stub(process, 'platform').value('darwin');