Skip to content

Commit be7bf44

Browse files
authored
fix(toolkit-cleaner): docker images with prefixed tags are always deleted (#250)
Use the hash of the dummy docker image to determine if there is a prefix. Fixes #246
1 parent 7336490 commit be7bf44

File tree

5 files changed

+47
-10
lines changed

5 files changed

+47
-10
lines changed

src/toolkit-cleaner/extract-template-hashes.lambda.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,21 @@ export async function handler(stackName: string) {
1111
return [];
1212
}
1313

14-
const hashes = template.TemplateBody.match(/[a-f0-9]{64}/g);
14+
if (!process.env.DOCKER_IMAGE_ASSET_HASH) {
15+
throw new Error('Missing DOCKER_IMAGE_ASSET_HASH environment variable');
16+
}
17+
const dockerTagPrefix = findDockerTagPrefix(process.env.DOCKER_IMAGE_ASSET_HASH);
18+
19+
const regexp = new RegExp(`(${dockerTagPrefix})?[a-f0-9]{64}`, 'g');
20+
const hashes = template.TemplateBody.match(regexp);
1521

1622
return [...new Set(hashes)];
1723
}
24+
25+
function findDockerTagPrefix(hash: string): string {
26+
if (hash.length === 64) {
27+
return '';
28+
}
29+
30+
return hash.substring(0, hash.length - 64);
31+
}

src/toolkit-cleaner/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ export class ToolkitCleaner extends Construct {
8282

8383
const extractTemplateHashesFunction = new ExtractTemplateHashesFunction(this, 'ExtractTemplateHashesFunction', {
8484
timeout: Duration.seconds(30),
85+
environment: {
86+
DOCKER_IMAGE_ASSET_HASH: dockerImageAsset.assetHash,
87+
},
8588
});
8689
extractTemplateHashesFunction.addToRolePolicy(new PolicyStatement({
8790
actions: ['cloudformation:GetTemplate'],

test/toolkit-cleaner/extract-template-hashes.test.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import { mockClient } from 'aws-sdk-client-mock';
44
import { handler } from '../../src/toolkit-cleaner/extract-template-hashes.lambda';
55

66
const cloudFormationClientMock = mockClient(CloudFormationClient);
7-
cloudFormationClientMock.on(GetTemplateCommand).resolves({
8-
TemplateBody: 'hello 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 world 486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
9-
});
107

118
test('extracts hashes', async () => {
9+
process.env.DOCKER_IMAGE_ASSET_HASH = '5a7abf30ce10141adcb73c9b836ec68479c65fb4d1693df160563e36ece0d55e';
10+
11+
cloudFormationClientMock.on(GetTemplateCommand).resolves({
12+
TemplateBody: 'hello 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 world 486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
13+
});
1214

1315
const response = await handler('stack1');
1416

@@ -19,3 +21,20 @@ test('extracts hashes', async () => {
1921
'486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
2022
]);
2123
});
24+
25+
test('extracts hashes with docker tag prefix', async () => {
26+
process.env.DOCKER_IMAGE_ASSET_HASH = 'prefix5a7abf30ce10141adcb73c9b836ec68479c65fb4d1693df160563e36ece0d55e';
27+
28+
cloudFormationClientMock.on(GetTemplateCommand).resolves({
29+
TemplateBody: 'hello prefix2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 world 486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
30+
});
31+
32+
const response = await handler('stack1');
33+
34+
expect(cloudFormationClientMock).toHaveReceivedCommandWith(GetTemplateCommand, { StackName: 'stack1' });
35+
36+
expect(response).toEqual([
37+
'prefix2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824',
38+
'486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
39+
]);
40+
});

test/toolkit-cleaner/toolkit-cleaner.integ.snapshot/toolkit-cleaner-integ.assets.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@
2727
}
2828
}
2929
},
30-
"e2fc900c4989c9292d92789a3c86dc4c928e649bf168c2547f48b503dd41a520": {
30+
"839231c3a66de2124ed53cba376ac7d09e962b10a04d77f96cd2f74e930f75c9": {
3131
"source": {
32-
"path": "asset.e2fc900c4989c9292d92789a3c86dc4c928e649bf168c2547f48b503dd41a520.lambda",
32+
"path": "asset.839231c3a66de2124ed53cba376ac7d09e962b10a04d77f96cd2f74e930f75c9.lambda",
3333
"packaging": "zip"
3434
},
3535
"destinations": {
3636
"current_account-current_region": {
3737
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
38-
"objectKey": "e2fc900c4989c9292d92789a3c86dc4c928e649bf168c2547f48b503dd41a520.zip",
38+
"objectKey": "839231c3a66de2124ed53cba376ac7d09e962b10a04d77f96cd2f74e930f75c9.zip",
3939
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
4040
}
4141
}
@@ -79,15 +79,15 @@
7979
}
8080
}
8181
},
82-
"14fd8c2a54dd634868c0496f806f1d30d38056ee29131403ae4e4166ed615812": {
82+
"98fffe1b2edbf8c7f26bc9d9b99a394ae270f6137796d379c74d08efc690cabb": {
8383
"source": {
8484
"path": "toolkit-cleaner-integ.template.json",
8585
"packaging": "file"
8686
},
8787
"destinations": {
8888
"current_account-current_region": {
8989
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
90-
"objectKey": "14fd8c2a54dd634868c0496f806f1d30d38056ee29131403ae4e4166ed615812.json",
90+
"objectKey": "98fffe1b2edbf8c7f26bc9d9b99a394ae270f6137796d379c74d08efc690cabb.json",
9191
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
9292
}
9393
}

test/toolkit-cleaner/toolkit-cleaner.integ.snapshot/toolkit-cleaner-integ.template.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
"S3Bucket": {
145145
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
146146
},
147-
"S3Key": "e2fc900c4989c9292d92789a3c86dc4c928e649bf168c2547f48b503dd41a520.zip"
147+
"S3Key": "839231c3a66de2124ed53cba376ac7d09e962b10a04d77f96cd2f74e930f75c9.zip"
148148
},
149149
"Role": {
150150
"Fn::GetAtt": [
@@ -155,6 +155,7 @@
155155
"Description": "src/toolkit-cleaner/extract-template-hashes.lambda.ts",
156156
"Environment": {
157157
"Variables": {
158+
"DOCKER_IMAGE_ASSET_HASH": "59bc252bbfc4819edcc48f546a0ea71b7b108d3899f8f503cd6f5bcc1f375126",
158159
"AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1"
159160
}
160161
},

0 commit comments

Comments
 (0)