Skip to content

Commit

Permalink
fix(lambda): fromDockerBuild output is located under /asset (#13539)
Browse files Browse the repository at this point in the history
Ensure `imagePath` ends with `/.` so that the content at that location
is copied.

See https://docs.docker.com/engine/reference/commandline/cp/

Closes #13439


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
jogold authored Mar 11, 2021
1 parent e9cd1e8 commit 77449f6
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
12 changes: 11 additions & 1 deletion packages/@aws-cdk/aws-lambda/lib/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,19 @@ export abstract class Code {
* @param options Docker build options
*/
public static fromDockerBuild(path: string, options: DockerBuildAssetOptions = {}): AssetCode {
let imagePath = options.imagePath ?? '/asset/.';

// ensure imagePath ends with /. to copy the **content** at this path
if (imagePath.endsWith('/')) {
imagePath = `${imagePath}.`;
} else if (!imagePath.endsWith('/.')) {
imagePath = `${imagePath}/.`;
}

const assetPath = cdk.DockerImage
.fromBuild(path, options)
.cp(options.imagePath ?? '/asset', options.outputPath);
.cp(imagePath, options.outputPath);

return new AssetCode(assetPath);
}

Expand Down
56 changes: 55 additions & 1 deletion packages/@aws-cdk/aws-lambda/test/code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,23 @@ describe('code', () => {
});

describe('lambda.Code.fromDockerBuild', () => {
let fromBuildMock: jest.SpyInstance<cdk.DockerImage>;
let cpMock: jest.Mock<any, any>;

beforeEach(() => {
cpMock = jest.fn().mockReturnValue(path.join(__dirname, 'docker-build-lambda'));
fromBuildMock = jest.spyOn(cdk.DockerImage, 'fromBuild').mockImplementation(() => ({
cp: cpMock,
image: 'tag',
run: jest.fn(),
toJSON: jest.fn(),
}));
});

afterEach(() => {
fromBuildMock.mockRestore();
});

test('can use the result of a Docker build as an asset', () => {
// given
const stack = new cdk.Stack();
Expand All @@ -346,10 +363,47 @@ describe('code', () => {
// then
expect(stack).toHaveResource('AWS::Lambda::Function', {
Metadata: {
[cxapi.ASSET_RESOURCE_METADATA_PATH_KEY]: 'asset.38cd320fa97b348accac88e48d9cede4923f7cab270ce794c95a665be83681a8',
[cxapi.ASSET_RESOURCE_METADATA_PATH_KEY]: 'asset.fbafdbb9ae8d1bae0def415b791a93c486d18ebc63270c748abecc3ac0ab9533',
[cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY]: 'Code',
},
}, ResourcePart.CompleteDefinition);

expect(fromBuildMock).toHaveBeenCalledWith(path.join(__dirname, 'docker-build-lambda'), {});
expect(cpMock).toHaveBeenCalledWith('/asset/.', undefined);
});

test('fromDockerBuild appends /. to an image path not ending with a /', () => {
// given
const stack = new cdk.Stack();

// when
new lambda.Function(stack, 'Fn', {
code: lambda.Code.fromDockerBuild(path.join(__dirname, 'docker-build-lambda'), {
imagePath: '/my/image/path',
}),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_12_X,
});

// then
expect(cpMock).toHaveBeenCalledWith('/my/image/path/.', undefined);
});

test('fromDockerBuild appends . to an image path ending with a /', () => {
// given
const stack = new cdk.Stack();

// when
new lambda.Function(stack, 'Fn', {
code: lambda.Code.fromDockerBuild(path.join(__dirname, 'docker-build-lambda'), {
imagePath: '/my/image/path/',
}),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_12_X,
});

// then
expect(cpMock).toHaveBeenCalledWith('/my/image/path/.', undefined);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
FROM public.ecr.aws/amazonlinux/amazonlinux:latest

COPY index.js /asset
COPY index.js /asset/

0 comments on commit 77449f6

Please sign in to comment.