deploy-time-build
Version:
Build during CDK deployment.
115 lines • 16 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SociIndexBuild = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path_1 = require("path");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_codebuild_1 = require("aws-cdk-lib/aws-codebuild");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
const constructs_1 = require("constructs");
const singleton_project_1 = require("./singleton-project");
/**
* Build and publish a SOCI index for a container image.
* A SOCI index helps start Fargate tasks faster in some cases.
* Please read the following document for more details: https://docs.aws.amazon.com/AmazonECS/latest/userguide/container-considerations.html
*/
class SociIndexBuild extends constructs_1.Construct {
/**
* A utility method to create a SociIndexBuild construct from a DockerImageAsset instance.
*/
static fromDockerImageAsset(scope, id, imageAsset) {
return new SociIndexBuild(scope, id, {
repository: imageAsset.repository,
imageTag: imageAsset.assetHash,
});
}
constructor(scope, id, props) {
super(scope, id);
const sociWrapperVersion = 'v0.2.3';
const binaryUrl = `https://github.com/tmokmss/soci-wrapper/releases/download/${sociWrapperVersion}/soci-wrapper-${sociWrapperVersion}-linux-amd64.tar.gz`;
const handler = new aws_lambda_1.SingletonFunction(this, 'CustomResourceHandler', {
// Use raw string to avoid from tightening CDK version requirement
runtime: new aws_lambda_1.Runtime('nodejs20.x', aws_lambda_1.RuntimeFamily.NODEJS),
code: aws_lambda_1.Code.fromAsset((0, path_1.join)(__dirname, '../lambda/trigger-codebuild/dist')),
handler: 'index.handler',
uuid: 'db740fd5-5436-4a84-8a09-e6dfcd01f4f3', // generated for this construct
lambdaPurpose: 'DeployTimeBuildCustomResourceHandler',
timeout: aws_cdk_lib_1.Duration.minutes(5),
});
const project = new singleton_project_1.SingletonProject(this, 'Project', {
uuid: '024cf76a-1003-4aa4-aa4b-12c32c09ca3c', // generated for this construct
projectPurpose: 'SociIndexBuild',
environment: { buildImage: aws_codebuild_1.LinuxBuildImage.fromCodeBuildImageId('aws/codebuild/standard:7.0') },
buildSpec: aws_codebuild_1.BuildSpec.fromObject({
version: '0.2',
phases: {
build: {
commands: [
'current_dir=$(pwd)',
`wget --quiet -O soci-wrapper.tar.gz ${binaryUrl}`,
'tar -xvzf soci-wrapper.tar.gz',
'',
'export AWS_ACCOUNT=$(aws sts get-caller-identity --query "Account" --output text)',
'export REGISTRY_USER=AWS',
'export REGISTRY_PASSWORD=$(aws ecr get-login-password --region $AWS_REGION)',
'export REGISTRY=$AWS_ACCOUNT.dkr.ecr.$AWS_REGION.amazonaws.com',
'aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $REGISTRY',
'REPO_NAME=$repositoryName',
'IMAGE_TAG=$imageTag',
'DIGEST=$(aws ecr describe-images --repository-name $REPO_NAME --image-ids imageTag=$IMAGE_TAG --query imageDetails[0].imageDigest --output text)',
'./soci-wrapper --repo $REPO_NAME --digest $DIGEST --region $AWS_REGION --account $AWS_ACCOUNT',
],
},
post_build: {
commands: [
'echo Build completed on `date`',
`
STATUS='SUCCESS'
if [ $CODEBUILD_BUILD_SUCCEEDING -ne 1 ] # Test if the build is failing
then
STATUS='FAILED'
REASON="deploy-time-build failed. See CloudWatch Log stream for the detailed reason:
https://$AWS_REGION.console.aws.amazon.com/cloudwatch/home?region=$AWS_REGION#logsV2:log-groups/log-group/\\$252Faws\\$252Fcodebuild\\$252F$projectName/log-events/$CODEBUILD_LOG_PATH"
fi
cat <<EOF > payload.json
{
"StackId": "$stackId",
"RequestId": "$requestId",
"LogicalResourceId":"$logicalResourceId",
"PhysicalResourceId": "$imageTag",
"Status": "$STATUS",
"Reason": "$REASON"
}
EOF
curl -vv -i -X PUT -H 'Content-Type:' -d "@payload.json" "$responseURL"
`,
],
},
},
}),
}).project;
handler.addToRolePolicy(new aws_iam_1.PolicyStatement({
actions: ['codebuild:StartBuild'],
resources: [project.projectArn],
}));
props.repository.grantPullPush(project);
props.repository.grant(project, 'ecr:DescribeImages');
const properties = {
type: 'SociIndexBuild',
imageTag: props.imageTag,
repositoryName: props.repository.repositoryName,
codeBuildProjectName: project.projectName,
};
new aws_cdk_lib_1.CustomResource(this, 'Resource', {
serviceToken: handler.functionArn,
resourceType: 'Custom::CDKSociIndexBuild',
properties,
});
}
}
exports.SociIndexBuild = SociIndexBuild;
_a = JSII_RTTI_SYMBOL_1;
SociIndexBuild[_a] = { fqn: "deploy-time-build.SociIndexBuild", version: "0.3.37" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29jaS1pbmRleC1idWlsZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zb2NpLWluZGV4LWJ1aWxkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0JBQTRCO0FBQzVCLDZDQUF1RDtBQUN2RCw2REFBdUU7QUFHdkUsaURBQXNEO0FBQ3RELHVEQUF5RjtBQUN6RiwyQ0FBdUM7QUFDdkMsMkRBQXVEO0FBaUJ2RDs7OztHQUlHO0FBQ0gsTUFBYSxjQUFlLFNBQVEsc0JBQVM7SUFDM0M7O09BRUc7SUFDSSxNQUFNLENBQUMsb0JBQW9CLENBQUMsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsVUFBNEI7UUFDM0YsT0FBTyxJQUFJLGNBQWMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ25DLFVBQVUsRUFBRSxVQUFVLENBQUMsVUFBVTtZQUNqQyxRQUFRLEVBQUUsVUFBVSxDQUFDLFNBQVM7U0FDL0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBMEI7UUFDbEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLGtCQUFrQixHQUFHLFFBQVEsQ0FBQztRQUVwQyxNQUFNLFNBQVMsR0FBRyw2REFBNkQsa0JBQWtCLGlCQUFpQixrQkFBa0IscUJBQXFCLENBQUM7UUFFMUosTUFBTSxPQUFPLEdBQUcsSUFBSSw4QkFBaUIsQ0FBQyxJQUFJLEVBQUUsdUJBQXVCLEVBQUU7WUFDbkUsa0VBQWtFO1lBQ2xFLE9BQU8sRUFBRSxJQUFJLG9CQUFPLENBQUMsWUFBWSxFQUFFLDBCQUFhLENBQUMsTUFBTSxDQUFDO1lBQ3hELElBQUksRUFBRSxpQkFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsa0NBQWtDLENBQUMsQ0FBQztZQUN6RSxPQUFPLEVBQUUsZUFBZTtZQUN4QixJQUFJLEVBQUUsc0NBQXNDLEVBQUUsK0JBQStCO1lBQzdFLGFBQWEsRUFBRSxzQ0FBc0M7WUFDckQsT0FBTyxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztTQUM3QixDQUFDLENBQUM7UUFFSCxNQUFNLE9BQU8sR0FBRyxJQUFJLG9DQUFnQixDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDcEQsSUFBSSxFQUFFLHNDQUFzQyxFQUFFLCtCQUErQjtZQUM3RSxjQUFjLEVBQUUsZ0JBQWdCO1lBQ2hDLFdBQVcsRUFBRSxFQUFFLFVBQVUsRUFBRSwrQkFBZSxDQUFDLG9CQUFvQixDQUFDLDRCQUE0QixDQUFDLEVBQUU7WUFDL0YsU0FBUyxFQUFFLHlCQUFTLENBQUMsVUFBVSxDQUFDO2dCQUM5QixPQUFPLEVBQUUsS0FBSztnQkFDZCxNQUFNLEVBQUU7b0JBQ04sS0FBSyxFQUFFO3dCQUNMLFFBQVEsRUFBRTs0QkFDUixvQkFBb0I7NEJBQ3BCLHVDQUF1QyxTQUFTLEVBQUU7NEJBQ2xELCtCQUErQjs0QkFDL0IsRUFBRTs0QkFDRixtRkFBbUY7NEJBQ25GLDBCQUEwQjs0QkFDMUIsNkVBQTZFOzRCQUM3RSxnRUFBZ0U7NEJBQ2hFLDBHQUEwRzs0QkFDMUcsMkJBQTJCOzRCQUMzQixxQkFBcUI7NEJBQ3JCLGtKQUFrSjs0QkFDbEosK0ZBQStGO3lCQUNoRztxQkFDRjtvQkFDRCxVQUFVLEVBQUU7d0JBQ1YsUUFBUSxFQUFFOzRCQUNSLGdDQUFnQzs0QkFDaEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7ZUFtQkM7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDO1NBQ0gsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUVYLE9BQU8sQ0FBQyxlQUFlLENBQ3JCLElBQUkseUJBQWUsQ0FBQztZQUNsQixPQUFPLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQztZQUNqQyxTQUFTLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO1NBQ2hDLENBQUMsQ0FDSCxDQUFDO1FBRUYsS0FBSyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLG9CQUFvQixDQUFDLENBQUM7UUFFdEQsTUFBTSxVQUFVLEdBQWdDO1lBQzlDLElBQUksRUFBRSxnQkFBZ0I7WUFDdEIsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLGNBQWMsRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDLGNBQWM7WUFDL0Msb0JBQW9CLEVBQUUsT0FBTyxDQUFDLFdBQVc7U0FDMUMsQ0FBQztRQUVGLElBQUksNEJBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ25DLFlBQVksRUFBRSxPQUFPLENBQUMsV0FBVztZQUNqQyxZQUFZLEVBQUUsMkJBQTJCO1lBQ3pDLFVBQVU7U0FDWCxDQUFDLENBQUM7SUFDTCxDQUFDOztBQXZHSCx3Q0F3R0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBDdXN0b21SZXNvdXJjZSwgRHVyYXRpb24gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBCdWlsZFNwZWMsIExpbnV4QnVpbGRJbWFnZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jb2RlYnVpbGQnO1xuaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNyJztcbmltcG9ydCB7IERvY2tlckltYWdlQXNzZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNyLWFzc2V0cyc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IENvZGUsIFJ1bnRpbWUsIFJ1bnRpbWVGYW1pbHksIFNpbmdsZXRvbkZ1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IFNpbmdsZXRvblByb2plY3QgfSBmcm9tICcuL3NpbmdsZXRvbi1wcm9qZWN0JztcbmltcG9ydCB7IFNvY2lJbmRleEJ1aWxkUmVzb3VyY2VQcm9wcyB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNvY2lJbmRleEJ1aWxkUHJvcHMge1xuICAvKipcbiAgICogVGhlIEVDUiByZXBvc2l0b3J5IHlvdXIgY29udGFpbmVyIGltYWdlIGlzIHN0b3JlZC5cbiAgICogWW91IGNhbiBvbmx5IHNwZWNpZnkgYSByZXBvc2l0b3J5IGluIHRoZSBzYW1lIGVudmlyb25tZW50IChhY2NvdW50L3JlZ2lvbikuXG4gICAqIFRoZSBpbmRleCBhcnRpZmFjdCB3aWxsIGJlIHVwbG9hZGVkIHRvIHRoaXMgcmVwb3NpdG9yeS5cbiAgICovXG4gIHJlYWRvbmx5IHJlcG9zaXRvcnk6IElSZXBvc2l0b3J5O1xuXG4gIC8qKlxuICAgKiBUaGUgdGFnIG9mIHRoZSBjb250YWluZXIgaW1hZ2UgeW91IHdhbnQgdG8gYnVpbGQgaW5kZXggZm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgaW1hZ2VUYWc6IHN0cmluZztcbn1cblxuLyoqXG4gKiBCdWlsZCBhbmQgcHVibGlzaCBhIFNPQ0kgaW5kZXggZm9yIGEgY29udGFpbmVyIGltYWdlLlxuICogQSBTT0NJIGluZGV4IGhlbHBzIHN0YXJ0IEZhcmdhdGUgdGFza3MgZmFzdGVyIGluIHNvbWUgY2FzZXMuXG4gKiBQbGVhc2UgcmVhZCB0aGUgZm9sbG93aW5nIGRvY3VtZW50IGZvciBtb3JlIGRldGFpbHM6IGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L3VzZXJndWlkZS9jb250YWluZXItY29uc2lkZXJhdGlvbnMuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgU29jaUluZGV4QnVpbGQgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogQSB1dGlsaXR5IG1ldGhvZCB0byBjcmVhdGUgYSBTb2NpSW5kZXhCdWlsZCBjb25zdHJ1Y3QgZnJvbSBhIERvY2tlckltYWdlQXNzZXQgaW5zdGFuY2UuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21Eb2NrZXJJbWFnZUFzc2V0KHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGltYWdlQXNzZXQ6IERvY2tlckltYWdlQXNzZXQpIHtcbiAgICByZXR1cm4gbmV3IFNvY2lJbmRleEJ1aWxkKHNjb3BlLCBpZCwge1xuICAgICAgcmVwb3NpdG9yeTogaW1hZ2VBc3NldC5yZXBvc2l0b3J5LFxuICAgICAgaW1hZ2VUYWc6IGltYWdlQXNzZXQuYXNzZXRIYXNoLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFNvY2lJbmRleEJ1aWxkUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qgc29jaVdyYXBwZXJWZXJzaW9uID0gJ3YwLjIuMyc7XG5cbiAgICBjb25zdCBiaW5hcnlVcmwgPSBgaHR0cHM6Ly9naXRodWIuY29tL3Rtb2ttc3Mvc29jaS13cmFwcGVyL3JlbGVhc2VzL2Rvd25sb2FkLyR7c29jaVdyYXBwZXJWZXJzaW9ufS9zb2NpLXdyYXBwZXItJHtzb2NpV3JhcHBlclZlcnNpb259LWxpbnV4LWFtZDY0LnRhci5nemA7XG5cbiAgICBjb25zdCBoYW5kbGVyID0gbmV3IFNpbmdsZXRvbkZ1bmN0aW9uKHRoaXMsICdDdXN0b21SZXNvdXJjZUhhbmRsZXInLCB7XG4gICAgICAvLyBVc2UgcmF3IHN0cmluZyB0byBhdm9pZCBmcm9tIHRpZ2h0ZW5pbmcgQ0RLIHZlcnNpb24gcmVxdWlyZW1lbnRcbiAgICAgIHJ1bnRpbWU6IG5ldyBSdW50aW1lKCdub2RlanMyMC54JywgUnVudGltZUZhbWlseS5OT0RFSlMpLFxuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQoam9pbihfX2Rpcm5hbWUsICcuLi9sYW1iZGEvdHJpZ2dlci1jb2RlYnVpbGQvZGlzdCcpKSxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIHV1aWQ6ICdkYjc0MGZkNS01NDM2LTRhODQtOGEwOS1lNmRmY2QwMWY0ZjMnLCAvLyBnZW5lcmF0ZWQgZm9yIHRoaXMgY29uc3RydWN0XG4gICAgICBsYW1iZGFQdXJwb3NlOiAnRGVwbG95VGltZUJ1aWxkQ3VzdG9tUmVzb3VyY2VIYW5kbGVyJyxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9qZWN0ID0gbmV3IFNpbmdsZXRvblByb2plY3QodGhpcywgJ1Byb2plY3QnLCB7XG4gICAgICB1dWlkOiAnMDI0Y2Y3NmEtMTAwMy00YWE0LWFhNGItMTJjMzJjMDljYTNjJywgLy8gZ2VuZXJhdGVkIGZvciB0aGlzIGNvbnN0cnVjdFxuICAgICAgcHJvamVjdFB1cnBvc2U6ICdTb2NpSW5kZXhCdWlsZCcsXG4gICAgICBlbnZpcm9ubWVudDogeyBidWlsZEltYWdlOiBMaW51eEJ1aWxkSW1hZ2UuZnJvbUNvZGVCdWlsZEltYWdlSWQoJ2F3cy9jb2RlYnVpbGQvc3RhbmRhcmQ6Ny4wJykgfSxcbiAgICAgIGJ1aWxkU3BlYzogQnVpbGRTcGVjLmZyb21PYmplY3Qoe1xuICAgICAgICB2ZXJzaW9uOiAnMC4yJyxcbiAgICAgICAgcGhhc2VzOiB7XG4gICAgICAgICAgYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdjdXJyZW50X2Rpcj0kKHB3ZCknLFxuICAgICAgICAgICAgICBgd2dldCAtLXF1aWV0IC1PIHNvY2ktd3JhcHBlci50YXIuZ3ogJHtiaW5hcnlVcmx9YCxcbiAgICAgICAgICAgICAgJ3RhciAteHZ6ZiBzb2NpLXdyYXBwZXIudGFyLmd6JyxcbiAgICAgICAgICAgICAgJycsXG4gICAgICAgICAgICAgICdleHBvcnQgQVdTX0FDQ09VTlQ9JChhd3Mgc3RzIGdldC1jYWxsZXItaWRlbnRpdHkgLS1xdWVyeSBcIkFjY291bnRcIiAtLW91dHB1dCB0ZXh0KScsXG4gICAgICAgICAgICAgICdleHBvcnQgUkVHSVNUUllfVVNFUj1BV1MnLFxuICAgICAgICAgICAgICAnZXhwb3J0IFJFR0lTVFJZX1BBU1NXT1JEPSQoYXdzIGVjciBnZXQtbG9naW4tcGFzc3dvcmQgLS1yZWdpb24gJEFXU19SRUdJT04pJyxcbiAgICAgICAgICAgICAgJ2V4cG9ydCBSRUdJU1RSWT0kQVdTX0FDQ09VTlQuZGtyLmVjci4kQVdTX1JFR0lPTi5hbWF6b25hd3MuY29tJyxcbiAgICAgICAgICAgICAgJ2F3cyBlY3IgZ2V0LWxvZ2luLXBhc3N3b3JkIC0tcmVnaW9uICRBV1NfUkVHSU9OIHwgZG9ja2VyIGxvZ2luIC0tdXNlcm5hbWUgQVdTIC0tcGFzc3dvcmQtc3RkaW4gJFJFR0lTVFJZJyxcbiAgICAgICAgICAgICAgJ1JFUE9fTkFNRT0kcmVwb3NpdG9yeU5hbWUnLFxuICAgICAgICAgICAgICAnSU1BR0VfVEFHPSRpbWFnZVRhZycsXG4gICAgICAgICAgICAgICdESUdFU1Q9JChhd3MgZWNyIGRlc2NyaWJlLWltYWdlcyAtLXJlcG9zaXRvcnktbmFtZSAkUkVQT19OQU1FIC0taW1hZ2UtaWRzIGltYWdlVGFnPSRJTUFHRV9UQUcgLS1xdWVyeSBpbWFnZURldGFpbHNbMF0uaW1hZ2VEaWdlc3QgLS1vdXRwdXQgdGV4dCknLFxuICAgICAgICAgICAgICAnLi9zb2NpLXdyYXBwZXIgLS1yZXBvICRSRVBPX05BTUUgLS1kaWdlc3QgJERJR0VTVCAtLXJlZ2lvbiAkQVdTX1JFR0lPTiAtLWFjY291bnQgJEFXU19BQ0NPVU5UJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwb3N0X2J1aWxkOiB7XG4gICAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgICAnZWNobyBCdWlsZCBjb21wbGV0ZWQgb24gYGRhdGVgJyxcbiAgICAgICAgICAgICAgYFxuU1RBVFVTPSdTVUNDRVNTJ1xuaWYgWyAkQ09ERUJVSUxEX0JVSUxEX1NVQ0NFRURJTkcgLW5lIDEgXSAjIFRlc3QgaWYgdGhlIGJ1aWxkIGlzIGZhaWxpbmdcbnRoZW5cblNUQVRVUz0nRkFJTEVEJ1xuUkVBU09OPVwiZGVwbG95LXRpbWUtYnVpbGQgZmFpbGVkLiBTZWUgQ2xvdWRXYXRjaCBMb2cgc3RyZWFtIGZvciB0aGUgZGV0YWlsZWQgcmVhc29uOiBcbmh0dHBzOi8vJEFXU19SRUdJT04uY29uc29sZS5hd3MuYW1hem9uLmNvbS9jbG91ZHdhdGNoL2hvbWU/cmVnaW9uPSRBV1NfUkVHSU9OI2xvZ3NWMjpsb2ctZ3JvdXBzL2xvZy1ncm91cC9cXFxcJDI1MkZhd3NcXFxcJDI1MkZjb2RlYnVpbGRcXFxcJDI1MkYkcHJvamVjdE5hbWUvbG9nLWV2ZW50cy8kQ09ERUJVSUxEX0xPR19QQVRIXCJcbmZpXG5jYXQgPDxFT0YgPiBwYXlsb2FkLmpzb25cbntcbiAgXCJTdGFja0lkXCI6IFwiJHN0YWNrSWRcIixcbiAgXCJSZXF1ZXN0SWRcIjogXCIkcmVxdWVzdElkXCIsXG4gIFwiTG9naWNhbFJlc291cmNlSWRcIjpcIiRsb2dpY2FsUmVzb3VyY2VJZFwiLFxuICBcIlBoeXNpY2FsUmVzb3VyY2VJZFwiOiBcIiRpbWFnZVRhZ1wiLFxuICBcIlN0YXR1c1wiOiBcIiRTVEFUVVNcIixcbiAgXCJSZWFzb25cIjogXCIkUkVBU09OXCJcbn1cbkVPRlxuY3VybCAtdnYgLWkgLVggUFVUIC1IICdDb250ZW50LVR5cGU6JyAtZCBcIkBwYXlsb2FkLmpzb25cIiBcIiRyZXNwb25zZVVSTFwiXG4gICAgICAgICAgICAgIGAsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICB9KS5wcm9qZWN0O1xuXG4gICAgaGFuZGxlci5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogWydjb2RlYnVpbGQ6U3RhcnRCdWlsZCddLFxuICAgICAgICByZXNvdXJjZXM6IFtwcm9qZWN0LnByb2plY3RBcm5dLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIHByb3BzLnJlcG9zaXRvcnkuZ3JhbnRQdWxsUHVzaChwcm9qZWN0KTtcbiAgICBwcm9wcy5yZXBvc2l0b3J5LmdyYW50KHByb2plY3QsICdlY3I6RGVzY3JpYmVJbWFnZXMnKTtcblxuICAgIGNvbnN0IHByb3BlcnRpZXM6IFNvY2lJbmRleEJ1aWxkUmVzb3VyY2VQcm9wcyA9IHtcbiAgICAgIHR5cGU6ICdTb2NpSW5kZXhCdWlsZCcsXG4gICAgICBpbWFnZVRhZzogcHJvcHMuaW1hZ2VUYWcsXG4gICAgICByZXBvc2l0b3J5TmFtZTogcHJvcHMucmVwb3NpdG9yeS5yZXBvc2l0b3J5TmFtZSxcbiAgICAgIGNvZGVCdWlsZFByb2plY3ROYW1lOiBwcm9qZWN0LnByb2plY3ROYW1lLFxuICAgIH07XG5cbiAgICBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgc2VydmljZVRva2VuOiBoYW5kbGVyLmZ1bmN0aW9uQXJuLFxuICAgICAgcmVzb3VyY2VUeXBlOiAnQ3VzdG9tOjpDREtTb2NpSW5kZXhCdWlsZCcsXG4gICAgICBwcm9wZXJ0aWVzLFxuICAgIH0pO1xuICB9XG59XG4iXX0=