@cloudsnorkel/cdk-github-runners 0.9.4 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +5 -3
- package/.jsii +332 -284
- package/API.md +55 -19
- package/README.md +135 -65
- package/assets/{providers/image-builders → image-builders}/aws-image-builder/delete-ami.lambda/index.js +2 -2
- package/assets/{providers/image-builders → image-builders}/aws-image-builder/filter-failed-builds.lambda/index.js +1 -1
- package/assets/image-builders/aws-image-builder/reaper.lambda/index.js +163 -0
- package/assets/{providers/image-builders → image-builders}/aws-image-builder/versioner.lambda/index.js +2 -2
- package/cdk.json +10 -0
- package/lib/access.js +1 -1
- package/lib/image-builders/api.js +47 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/ami.d.ts +2 -3
- package/lib/image-builders/aws-image-builder/ami.js +93 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/builder.d.ts +10 -3
- package/lib/image-builders/aws-image-builder/builder.js +568 -0
- package/lib/image-builders/aws-image-builder/common.js +46 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/container.d.ts +1 -1
- package/lib/image-builders/aws-image-builder/container.js +63 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/delete-ami-function.d.ts +1 -1
- package/lib/image-builders/aws-image-builder/delete-ami-function.js +23 -0
- package/lib/image-builders/aws-image-builder/delete-ami.lambda.js +87 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/deprecated/ami.d.ts +4 -4
- package/lib/image-builders/aws-image-builder/deprecated/ami.js +240 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/deprecated/common.d.ts +1 -1
- package/lib/image-builders/aws-image-builder/deprecated/common.js +144 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/deprecated/container.d.ts +3 -3
- package/lib/image-builders/aws-image-builder/deprecated/container.js +222 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/deprecated/index.js +1 -1
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/deprecated/linux-components.d.ts +1 -1
- package/lib/image-builders/aws-image-builder/deprecated/linux-components.js +172 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/deprecated/windows-components.d.ts +1 -1
- package/lib/image-builders/aws-image-builder/deprecated/windows-components.js +126 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/filter-failed-builds-function.d.ts +1 -1
- package/lib/image-builders/aws-image-builder/filter-failed-builds-function.js +23 -0
- package/lib/image-builders/aws-image-builder/filter-failed-builds.lambda.js +18 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/index.js +1 -1
- package/lib/image-builders/aws-image-builder/reaper-function.d.ts +13 -0
- package/lib/image-builders/aws-image-builder/reaper-function.js +23 -0
- package/lib/image-builders/aws-image-builder/reaper.lambda.d.ts +1 -0
- package/lib/image-builders/aws-image-builder/reaper.lambda.js +149 -0
- package/lib/{providers/image-builders → image-builders}/aws-image-builder/versioner-function.d.ts +1 -1
- package/lib/image-builders/aws-image-builder/versioner-function.js +23 -0
- package/lib/image-builders/aws-image-builder/versioner.lambda.js +96 -0
- package/lib/{providers/image-builders → image-builders}/codebuild-deprecated.d.ts +5 -5
- package/lib/image-builders/codebuild-deprecated.js +373 -0
- package/lib/{providers/image-builders → image-builders}/codebuild.d.ts +2 -2
- package/lib/image-builders/codebuild.js +289 -0
- package/lib/{providers/image-builders → image-builders}/common.d.ts +6 -4
- package/lib/{providers/image-builders → image-builders}/common.js +1 -1
- package/lib/{providers/image-builders → image-builders}/components.d.ts +8 -2
- package/lib/image-builders/components.js +568 -0
- package/lib/{providers/image-builders → image-builders}/index.js +1 -1
- package/lib/{providers/image-builders → image-builders}/static.d.ts +1 -1
- package/lib/image-builders/static.js +58 -0
- package/lib/providers/codebuild.d.ts +1 -1
- package/lib/providers/codebuild.js +4 -4
- package/lib/providers/common.js +3 -3
- package/lib/providers/ec2.d.ts +2 -2
- package/lib/providers/ec2.js +4 -4
- package/lib/providers/ecs.d.ts +1 -1
- package/lib/providers/ecs.js +3 -3
- package/lib/providers/fargate.d.ts +1 -1
- package/lib/providers/fargate.js +4 -4
- package/lib/providers/index.d.ts +1 -1
- package/lib/providers/index.js +2 -2
- package/lib/providers/lambda.d.ts +1 -1
- package/lib/providers/lambda.js +4 -4
- package/lib/runner.d.ts +3 -3
- package/lib/runner.js +5 -5
- package/lib/secrets.js +1 -1
- package/package.json +12 -10
- package/lib/providers/image-builders/api.js +0 -47
- package/lib/providers/image-builders/aws-image-builder/ami.js +0 -81
- package/lib/providers/image-builders/aws-image-builder/builder.js +0 -520
- package/lib/providers/image-builders/aws-image-builder/common.js +0 -46
- package/lib/providers/image-builders/aws-image-builder/container.js +0 -63
- package/lib/providers/image-builders/aws-image-builder/delete-ami-function.js +0 -23
- package/lib/providers/image-builders/aws-image-builder/delete-ami.lambda.js +0 -87
- package/lib/providers/image-builders/aws-image-builder/deprecated/ami.js +0 -240
- package/lib/providers/image-builders/aws-image-builder/deprecated/common.js +0 -144
- package/lib/providers/image-builders/aws-image-builder/deprecated/container.js +0 -222
- package/lib/providers/image-builders/aws-image-builder/deprecated/linux-components.js +0 -172
- package/lib/providers/image-builders/aws-image-builder/deprecated/windows-components.js +0 -129
- package/lib/providers/image-builders/aws-image-builder/filter-failed-builds-function.js +0 -23
- package/lib/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.js +0 -18
- package/lib/providers/image-builders/aws-image-builder/versioner-function.js +0 -23
- package/lib/providers/image-builders/aws-image-builder/versioner.lambda.js +0 -96
- package/lib/providers/image-builders/codebuild-deprecated.js +0 -373
- package/lib/providers/image-builders/codebuild.js +0 -287
- package/lib/providers/image-builders/components.js +0 -535
- package/lib/providers/image-builders/static.js +0 -58
- /package/lib/{providers/image-builders → image-builders}/api.d.ts +0 -0
- /package/lib/{providers/image-builders → image-builders}/aws-image-builder/common.d.ts +0 -0
- /package/lib/{providers/image-builders → image-builders}/aws-image-builder/delete-ami.lambda.d.ts +0 -0
- /package/lib/{providers/image-builders → image-builders}/aws-image-builder/deprecated/index.d.ts +0 -0
- /package/lib/{providers/image-builders → image-builders}/aws-image-builder/filter-failed-builds.lambda.d.ts +0 -0
- /package/lib/{providers/image-builders → image-builders}/aws-image-builder/index.d.ts +0 -0
- /package/lib/{providers/image-builders → image-builders}/aws-image-builder/versioner.lambda.d.ts +0 -0
- /package/lib/{providers/image-builders → image-builders}/index.d.ts +0 -0
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var _a;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.CodeBuildImageBuilder = void 0;
|
|
5
|
-
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
-
const crypto = require("crypto");
|
|
7
|
-
const cdk = require("aws-cdk-lib");
|
|
8
|
-
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
9
|
-
const aws_codebuild_1 = require("aws-cdk-lib/aws-codebuild");
|
|
10
|
-
const aws_ecr_1 = require("aws-cdk-lib/aws-ecr");
|
|
11
|
-
const aws_logs_1 = require("aws-cdk-lib/aws-logs");
|
|
12
|
-
const constructs_1 = require("constructs");
|
|
13
|
-
const utils_1 = require("../../utils");
|
|
14
|
-
const build_image_function_1 = require("../build-image-function");
|
|
15
|
-
const common_1 = require("../common");
|
|
16
|
-
/**
|
|
17
|
-
* An image builder that uses CodeBuild to build Docker images pre-baked with all the GitHub Actions runner requirements. Builders can be used with runner providers.
|
|
18
|
-
*
|
|
19
|
-
* Each builder re-runs automatically at a set interval to make sure the images contain the latest versions of everything.
|
|
20
|
-
*
|
|
21
|
-
* You can create an instance of this construct to customize the image used to spin-up runners. Each provider has its own requirements for what an image should do. That's why they each provide their own Dockerfile.
|
|
22
|
-
*
|
|
23
|
-
* For example, to set a specific runner version, rebuild the image every 2 weeks, and add a few packages for the Fargate provider, use:
|
|
24
|
-
*
|
|
25
|
-
* ```
|
|
26
|
-
* const builder = new CodeBuildImageBuilder(this, 'Builder', {
|
|
27
|
-
* dockerfilePath: FargateProvider.LINUX_X64_DOCKERFILE_PATH,
|
|
28
|
-
* runnerVersion: RunnerVersion.specific('2.293.0'),
|
|
29
|
-
* rebuildInterval: Duration.days(14),
|
|
30
|
-
* });
|
|
31
|
-
* builder.setBuildArg('EXTRA_PACKAGES', 'nginx xz-utils');
|
|
32
|
-
* new FargateRunner(this, 'Fargate provider', {
|
|
33
|
-
* label: 'customized-fargate',
|
|
34
|
-
* imageBuilder: builder,
|
|
35
|
-
* });
|
|
36
|
-
* ```
|
|
37
|
-
*
|
|
38
|
-
* @deprecated use RunnerImageBuilder
|
|
39
|
-
*/
|
|
40
|
-
class CodeBuildImageBuilder extends constructs_1.Construct {
|
|
41
|
-
constructor(scope, id, props) {
|
|
42
|
-
super(scope, id);
|
|
43
|
-
this.props = props;
|
|
44
|
-
this.preBuild = [];
|
|
45
|
-
this.postBuild = [];
|
|
46
|
-
this.buildArgs = new Map();
|
|
47
|
-
this.policyStatements = [];
|
|
48
|
-
this.secondaryAssets = new Map();
|
|
49
|
-
if (props.subnetSelection?.subnetType == aws_cdk_lib_1.aws_ec2.SubnetType.PRIVATE_ISOLATED) {
|
|
50
|
-
aws_cdk_lib_1.Annotations.of(this).addWarning('Private isolated subnets cannot pull from public ECR and VPC endpoint is not supported yet. ' +
|
|
51
|
-
'See https://github.com/aws/containers-roadmap/issues/1160');
|
|
52
|
-
}
|
|
53
|
-
// set platform
|
|
54
|
-
this.architecture = props.architecture ?? common_1.Architecture.X86_64;
|
|
55
|
-
this.os = props.os ?? common_1.Os.LINUX;
|
|
56
|
-
// create repository that only keeps one tag
|
|
57
|
-
this.repository = new aws_cdk_lib_1.aws_ecr.Repository(this, 'Repository', {
|
|
58
|
-
imageScanOnPush: true,
|
|
59
|
-
imageTagMutability: aws_ecr_1.TagMutability.MUTABLE,
|
|
60
|
-
removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
|
|
61
|
-
lifecycleRules: [
|
|
62
|
-
{
|
|
63
|
-
description: 'Remove untagged images that have been replaced by CodeBuild',
|
|
64
|
-
tagStatus: aws_ecr_1.TagStatus.UNTAGGED,
|
|
65
|
-
maxImageAge: aws_cdk_lib_1.Duration.days(1),
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
});
|
|
69
|
-
// upload Dockerfile to S3 as an asset
|
|
70
|
-
this.dockerfile = new aws_cdk_lib_1.aws_s3_assets.Asset(this, 'Dockerfile', {
|
|
71
|
-
path: props.dockerfilePath,
|
|
72
|
-
});
|
|
73
|
-
// choose build image
|
|
74
|
-
this.buildImage = props?.buildImage ?? this.getBuildImage();
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Uploads a folder to the build server at a given folder name.
|
|
78
|
-
*
|
|
79
|
-
* @param sourcePath path to source directory
|
|
80
|
-
* @param destName name of destination folder
|
|
81
|
-
*/
|
|
82
|
-
addFiles(sourcePath, destName) {
|
|
83
|
-
if (this.boundImage) {
|
|
84
|
-
throw new Error('Image is already bound. Use this method before passing the builder to a runner provider.');
|
|
85
|
-
}
|
|
86
|
-
const asset = new aws_cdk_lib_1.aws_s3_assets.Asset(this, destName, { path: sourcePath });
|
|
87
|
-
this.secondaryAssets.set(destName, asset);
|
|
88
|
-
this.preBuild.push(`rm -rf "${destName}" && cp -r "$CODEBUILD_SRC_DIR_${destName}" "${destName}"`); // symlinks don't work with docker
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Adds a command that runs before `docker build`.
|
|
92
|
-
*
|
|
93
|
-
* @param command command to add
|
|
94
|
-
*/
|
|
95
|
-
addPreBuildCommand(command) {
|
|
96
|
-
if (this.boundImage) {
|
|
97
|
-
throw new Error('Image is already bound. Use this method before passing the builder to a runner provider.');
|
|
98
|
-
}
|
|
99
|
-
this.preBuild.push(command);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Adds a command that runs after `docker build` and `docker push`.
|
|
103
|
-
*
|
|
104
|
-
* @param command command to add
|
|
105
|
-
*/
|
|
106
|
-
addPostBuildCommand(command) {
|
|
107
|
-
if (this.boundImage) {
|
|
108
|
-
throw new Error('Image is already bound. Use this method before passing the builder to a runner provider.');
|
|
109
|
-
}
|
|
110
|
-
this.postBuild.push(command);
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Adds a build argument for Docker. See the documentation for the Dockerfile you're using for a list of supported build arguments.
|
|
114
|
-
*
|
|
115
|
-
* @param name build argument name
|
|
116
|
-
* @param value build argument value
|
|
117
|
-
*/
|
|
118
|
-
setBuildArg(name, value) {
|
|
119
|
-
if (this.boundImage) {
|
|
120
|
-
throw new Error('Image is already bound. Use this method before passing the builder to a runner provider.');
|
|
121
|
-
}
|
|
122
|
-
this.buildArgs.set(name, value);
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Add a policy statement to the builder to access resources required to the image build.
|
|
126
|
-
*
|
|
127
|
-
* @param statement IAM policy statement
|
|
128
|
-
*/
|
|
129
|
-
addPolicyStatement(statement) {
|
|
130
|
-
if (this.boundImage) {
|
|
131
|
-
throw new Error('Image is already bound. Use this method before passing the builder to a runner provider.');
|
|
132
|
-
}
|
|
133
|
-
this.policyStatements.push(statement);
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Add extra trusted certificates. This helps deal with self-signed certificates for GitHub Enterprise Server.
|
|
137
|
-
*
|
|
138
|
-
* All first party Dockerfiles support this. Others may not.
|
|
139
|
-
*
|
|
140
|
-
* @param path path to directory containing a file called certs.pem containing all the required certificates
|
|
141
|
-
*/
|
|
142
|
-
addExtraCertificates(path) {
|
|
143
|
-
if (this.boundImage) {
|
|
144
|
-
throw new Error('Image is already bound. Use this method before passing the builder to a runner provider.');
|
|
145
|
-
}
|
|
146
|
-
this.addFiles(path, 'extra_certs');
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Called by IRunnerProvider to finalize settings and create the image builder.
|
|
150
|
-
*/
|
|
151
|
-
bindDockerImage() {
|
|
152
|
-
if (this.boundImage) {
|
|
153
|
-
return this.boundImage;
|
|
154
|
-
}
|
|
155
|
-
// log group for the image builds
|
|
156
|
-
const logGroup = new aws_cdk_lib_1.aws_logs.LogGroup(this, 'Logs', {
|
|
157
|
-
retention: this.props.logRetention ?? aws_logs_1.RetentionDays.ONE_MONTH,
|
|
158
|
-
removalPolicy: this.props.logRemovalPolicy ?? aws_cdk_lib_1.RemovalPolicy.DESTROY,
|
|
159
|
-
});
|
|
160
|
-
// generate buildSpec
|
|
161
|
-
const buildSpec = this.getBuildSpec(this.repository, logGroup, this.props.runnerVersion);
|
|
162
|
-
// create CodeBuild project that builds Dockerfile and pushes to repository
|
|
163
|
-
const project = new aws_cdk_lib_1.aws_codebuild.Project(this, 'CodeBuild', {
|
|
164
|
-
description: `Build docker image for self-hosted GitHub runner ${this.node.path} (${this.os.name}/${this.architecture.name})`,
|
|
165
|
-
buildSpec: aws_cdk_lib_1.aws_codebuild.BuildSpec.fromObject(buildSpec),
|
|
166
|
-
source: aws_cdk_lib_1.aws_codebuild.Source.s3({
|
|
167
|
-
bucket: this.dockerfile.bucket,
|
|
168
|
-
path: this.dockerfile.s3ObjectKey,
|
|
169
|
-
}),
|
|
170
|
-
vpc: this.props.vpc,
|
|
171
|
-
securityGroups: this.props.securityGroup ? [this.props.securityGroup] : undefined,
|
|
172
|
-
subnetSelection: this.props.subnetSelection,
|
|
173
|
-
timeout: this.props.timeout ?? aws_cdk_lib_1.Duration.hours(1),
|
|
174
|
-
environment: {
|
|
175
|
-
buildImage: this.buildImage,
|
|
176
|
-
computeType: this.props.computeType ?? aws_codebuild_1.ComputeType.SMALL,
|
|
177
|
-
privileged: true,
|
|
178
|
-
},
|
|
179
|
-
logging: {
|
|
180
|
-
cloudWatch: {
|
|
181
|
-
logGroup,
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
});
|
|
185
|
-
// permissions
|
|
186
|
-
this.repository.grantPullPush(project);
|
|
187
|
-
this.policyStatements.forEach(project.addToRolePolicy);
|
|
188
|
-
// call CodeBuild during deployment and delete all images from repository during destruction
|
|
189
|
-
const cr = this.customResource(project);
|
|
190
|
-
// rebuild image on a schedule
|
|
191
|
-
this.rebuildImageOnSchedule(project, this.props.rebuildInterval);
|
|
192
|
-
for (const [assetPath, asset] of this.secondaryAssets.entries()) {
|
|
193
|
-
project.addSecondarySource(aws_cdk_lib_1.aws_codebuild.Source.s3({
|
|
194
|
-
identifier: assetPath,
|
|
195
|
-
bucket: asset.bucket,
|
|
196
|
-
path: asset.s3ObjectKey,
|
|
197
|
-
}));
|
|
198
|
-
}
|
|
199
|
-
this.boundImage = {
|
|
200
|
-
imageRepository: aws_cdk_lib_1.aws_ecr.Repository.fromRepositoryAttributes(this, 'Dependable Image', {
|
|
201
|
-
// There are simpler ways to get name and ARN, but we want an image object that depends on the custom resource.
|
|
202
|
-
// We want whoever is using this image to automatically wait for CodeBuild to start and finish through the custom resource.
|
|
203
|
-
repositoryName: cr.getAttString('Name'),
|
|
204
|
-
repositoryArn: cr.ref,
|
|
205
|
-
}),
|
|
206
|
-
imageTag: 'latest',
|
|
207
|
-
architecture: this.architecture,
|
|
208
|
-
os: this.os,
|
|
209
|
-
logGroup,
|
|
210
|
-
runnerVersion: this.props.runnerVersion ?? common_1.RunnerVersion.latest(),
|
|
211
|
-
};
|
|
212
|
-
return this.boundImage;
|
|
213
|
-
}
|
|
214
|
-
getBuildImage() {
|
|
215
|
-
if (this.os.is(common_1.Os.LINUX)) {
|
|
216
|
-
if (this.architecture.is(common_1.Architecture.X86_64)) {
|
|
217
|
-
return aws_cdk_lib_1.aws_codebuild.LinuxBuildImage.STANDARD_6_0;
|
|
218
|
-
}
|
|
219
|
-
else if (this.architecture.is(common_1.Architecture.ARM64)) {
|
|
220
|
-
return aws_cdk_lib_1.aws_codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
if (this.os.is(common_1.Os.WINDOWS)) {
|
|
224
|
-
throw new Error('CodeBuild cannot be used to build Windows Docker images https://github.com/docker-library/docker/issues/49');
|
|
225
|
-
}
|
|
226
|
-
throw new Error(`Unable to find CodeBuild image for ${this.os.name}/${this.architecture.name}`);
|
|
227
|
-
}
|
|
228
|
-
getBuildSpec(repository, logGroup, runnerVersion) {
|
|
229
|
-
// don't forget to change BUILDSPEC_VERSION when the buildSpec changes, and you want to trigger a rebuild on deploy
|
|
230
|
-
let buildArgs = '';
|
|
231
|
-
for (const [name, value] of this.buildArgs.entries()) {
|
|
232
|
-
buildArgs += ` --build-arg "${name}"="${value}"`;
|
|
233
|
-
}
|
|
234
|
-
buildArgs += ` --build-arg RUNNER_VERSION="${runnerVersion ? runnerVersion.version : common_1.RunnerVersion.latest().version}"`;
|
|
235
|
-
const thisStack = cdk.Stack.of(this);
|
|
236
|
-
return {
|
|
237
|
-
version: '0.2',
|
|
238
|
-
env: {
|
|
239
|
-
variables: {
|
|
240
|
-
REPO_ARN: repository.repositoryArn,
|
|
241
|
-
REPO_URI: repository.repositoryUri,
|
|
242
|
-
STACK_ID: 'unspecified',
|
|
243
|
-
REQUEST_ID: 'unspecified',
|
|
244
|
-
LOGICAL_RESOURCE_ID: 'unspecified',
|
|
245
|
-
RESPONSE_URL: 'unspecified',
|
|
246
|
-
RUNNER_VERSION: runnerVersion ? runnerVersion.version : common_1.RunnerVersion.latest().version,
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
|
-
phases: {
|
|
250
|
-
pre_build: {
|
|
251
|
-
commands: this.preBuild.concat([
|
|
252
|
-
'mkdir -p extra_certs',
|
|
253
|
-
`aws ecr get-login-password --region "$AWS_DEFAULT_REGION" | docker login --username AWS --password-stdin ${thisStack.account}.dkr.ecr.${thisStack.region}.amazonaws.com`,
|
|
254
|
-
]),
|
|
255
|
-
},
|
|
256
|
-
build: {
|
|
257
|
-
commands: [
|
|
258
|
-
`docker build . -t "$REPO_URI" ${buildArgs}`,
|
|
259
|
-
'docker push "$REPO_URI"',
|
|
260
|
-
],
|
|
261
|
-
},
|
|
262
|
-
post_build: {
|
|
263
|
-
commands: this.postBuild.concat([
|
|
264
|
-
'STATUS="SUCCESS"',
|
|
265
|
-
'if [ $CODEBUILD_BUILD_SUCCEEDING -ne 1 ]; then STATUS="FAILED"; fi',
|
|
266
|
-
'cat <<EOF > /tmp/payload.json\n' +
|
|
267
|
-
'{\n' +
|
|
268
|
-
' "StackId": "$STACK_ID",\n' +
|
|
269
|
-
' "RequestId": "$REQUEST_ID",\n' +
|
|
270
|
-
' "LogicalResourceId": "$LOGICAL_RESOURCE_ID",\n' +
|
|
271
|
-
' "PhysicalResourceId": "$REPO_ARN",\n' +
|
|
272
|
-
' "Status": "$STATUS",\n' +
|
|
273
|
-
` "Reason": "See logs in ${logGroup.logGroupName}/$CODEBUILD_LOG_PATH (deploy again with \'cdk deploy -R\' or logRemovalPolicy=RemovalPolicy.RETAIN if they are already deleted)",\n` +
|
|
274
|
-
` "Data": {"Name": "${repository.repositoryName}"}\n` +
|
|
275
|
-
'}\n' +
|
|
276
|
-
'EOF',
|
|
277
|
-
'if [ "$RESPONSE_URL" != "unspecified" ]; then jq . /tmp/payload.json; curl -fsSL -X PUT -H "Content-Type:" -d "@/tmp/payload.json" "$RESPONSE_URL"; fi',
|
|
278
|
-
]),
|
|
279
|
-
},
|
|
280
|
-
},
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
customResource(project) {
|
|
284
|
-
const crHandler = (0, utils_1.singletonLambda)(build_image_function_1.BuildImageFunction, this, 'build-image', {
|
|
285
|
-
description: 'Custom resource handler that triggers CodeBuild to build runner images, and cleans-up images on deletion',
|
|
286
|
-
timeout: cdk.Duration.minutes(3),
|
|
287
|
-
logRetention: aws_cdk_lib_1.aws_logs.RetentionDays.ONE_MONTH,
|
|
288
|
-
});
|
|
289
|
-
const policy = new aws_cdk_lib_1.aws_iam.Policy(this, 'CR Policy', {
|
|
290
|
-
statements: [
|
|
291
|
-
new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
292
|
-
actions: ['codebuild:StartBuild'],
|
|
293
|
-
resources: [project.projectArn],
|
|
294
|
-
}),
|
|
295
|
-
new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
296
|
-
actions: ['ecr:BatchDeleteImage', 'ecr:ListImages'],
|
|
297
|
-
resources: [this.repository.repositoryArn],
|
|
298
|
-
}),
|
|
299
|
-
],
|
|
300
|
-
});
|
|
301
|
-
crHandler.role?.attachInlinePolicy(policy);
|
|
302
|
-
const cr = new aws_cdk_lib_1.CustomResource(this, 'Builder', {
|
|
303
|
-
serviceToken: crHandler.functionArn,
|
|
304
|
-
resourceType: 'Custom::ImageBuilder',
|
|
305
|
-
properties: {
|
|
306
|
-
RepoName: this.repository.repositoryName,
|
|
307
|
-
ProjectName: project.projectName,
|
|
308
|
-
// We include a hash so the image is built immediately on changes, and we don't have to wait for its scheduled build.
|
|
309
|
-
// This also helps make sure the changes are good. If they have a bug, the deployment will fail instead of just the scheduled build.
|
|
310
|
-
BuildHash: this.hashBuildSettings(),
|
|
311
|
-
},
|
|
312
|
-
});
|
|
313
|
-
// add dependencies to make sure resources are there when we need them
|
|
314
|
-
cr.node.addDependency(project);
|
|
315
|
-
cr.node.addDependency(policy);
|
|
316
|
-
cr.node.addDependency(crHandler);
|
|
317
|
-
return cr;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Return hash of all settings that can affect the result image so we can trigger the build when it changes.
|
|
321
|
-
* @private
|
|
322
|
-
*/
|
|
323
|
-
hashBuildSettings() {
|
|
324
|
-
// main Dockerfile
|
|
325
|
-
let components = [this.dockerfile.assetHash];
|
|
326
|
-
// all additional files
|
|
327
|
-
for (const [name, asset] of this.secondaryAssets.entries()) {
|
|
328
|
-
components.push(name);
|
|
329
|
-
components.push(asset.assetHash);
|
|
330
|
-
}
|
|
331
|
-
// buildspec.yml version
|
|
332
|
-
components.push(`v${CodeBuildImageBuilder.BUILDSPEC_VERSION}`);
|
|
333
|
-
// runner version
|
|
334
|
-
components.push(this.props.runnerVersion?.version ?? common_1.RunnerVersion.latest().version);
|
|
335
|
-
// user commands
|
|
336
|
-
components = components.concat(this.preBuild);
|
|
337
|
-
components = components.concat(this.postBuild);
|
|
338
|
-
for (const [name, value] of this.buildArgs.entries()) {
|
|
339
|
-
components.push(name);
|
|
340
|
-
components.push(value);
|
|
341
|
-
}
|
|
342
|
-
// hash it
|
|
343
|
-
const all = components.join('-');
|
|
344
|
-
return crypto.createHash('md5').update(all).digest('hex');
|
|
345
|
-
}
|
|
346
|
-
rebuildImageOnSchedule(project, rebuildInterval) {
|
|
347
|
-
rebuildInterval = rebuildInterval ?? aws_cdk_lib_1.Duration.days(7);
|
|
348
|
-
if (rebuildInterval.toMilliseconds() != 0) {
|
|
349
|
-
const scheduleRule = new aws_cdk_lib_1.aws_events.Rule(this, 'Build Schedule', {
|
|
350
|
-
description: `Rebuild runner image for ${this.repository.repositoryName}`,
|
|
351
|
-
schedule: aws_cdk_lib_1.aws_events.Schedule.rate(rebuildInterval),
|
|
352
|
-
});
|
|
353
|
-
scheduleRule.addTarget(new aws_cdk_lib_1.aws_events_targets.CodeBuildProject(project));
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
get connections() {
|
|
357
|
-
return new aws_cdk_lib_1.aws_ec2.Connections({
|
|
358
|
-
securityGroups: this.props.securityGroup ? [this.props.securityGroup] : [],
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
bindAmi() {
|
|
362
|
-
throw new Error('CodeBuildImageBuilder does not support building AMIs');
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
_a = JSII_RTTI_SYMBOL_1;
|
|
366
|
-
CodeBuildImageBuilder[_a] = { fqn: "@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder", version: "0.9.4" };
|
|
367
|
-
/**
|
|
368
|
-
* Bump this number every time the buildspec or any important setting of the project changes. It will force a rebuild of the image.
|
|
369
|
-
* @private
|
|
370
|
-
*/
|
|
371
|
-
CodeBuildImageBuilder.BUILDSPEC_VERSION = 2;
|
|
372
|
-
exports.CodeBuildImageBuilder = CodeBuildImageBuilder;
|
|
373
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZWJ1aWxkLWRlcHJlY2F0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHJvdmlkZXJzL2ltYWdlLWJ1aWxkZXJzL2NvZGVidWlsZC1kZXByZWNhdGVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaUNBQWlDO0FBQ2pDLG1DQUFtQztBQUNuQyw2Q0FhcUI7QUFDckIsNkRBQXdEO0FBQ3hELGlEQUErRDtBQUMvRCxtREFBcUQ7QUFDckQsMkNBQXVDO0FBRXZDLHVDQUE4QztBQUM5QyxrRUFBNkQ7QUFDN0Qsc0NBQW9GO0FBa0hwRjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxNQUFhLHFCQUFzQixTQUFRLHNCQUFTO0lBbUJsRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFXLEtBQWlDO1FBQ2xGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFEZ0MsVUFBSyxHQUFMLEtBQUssQ0FBNEI7UUFSNUUsYUFBUSxHQUFhLEVBQUUsQ0FBQztRQUN4QixjQUFTLEdBQWEsRUFBRSxDQUFDO1FBQ3pCLGNBQVMsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUMzQyxxQkFBZ0IsR0FBMEIsRUFBRSxDQUFDO1FBQzdDLG9CQUFlLEdBQWlDLElBQUksR0FBRyxFQUFFLENBQUM7UUFPaEUsSUFBSSxLQUFLLENBQUMsZUFBZSxFQUFFLFVBQVUsSUFBSSxxQkFBRyxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRTtZQUN4RSx5QkFBVyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsOEZBQThGO2dCQUMxSCwyREFBMkQsQ0FBQyxDQUFDO1NBQ2xFO1FBRUQsZUFBZTtRQUNmLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLFlBQVksSUFBSSxxQkFBWSxDQUFDLE1BQU0sQ0FBQztRQUM5RCxJQUFJLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFF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Q25GLGVBQWUsR0FBRyxlQUFlLElBQUksc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEQsSUFBSSxlQUFlLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxFQUFFO1lBQ3pDLE1BQU0sWUFBWSxHQUFHLElBQUksd0JBQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFO2dCQUMzRCxXQUFXLEVBQUUsNEJBQTRCLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxFQUFFO2dCQUN6RSxRQUFRLEVBQUUsd0JBQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQzthQUNoRCxDQUFDLENBQUM7WUFDSCxZQUFZLENBQUMsU0FBUyxDQUFDLElBQUksZ0NBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1NBQ3RFO0lBQ0gsQ0FBQztJQUVELElBQUksV0FBVztRQUNiLE9BQU8sSUFBSSxxQkFBRyxDQUFDLFdBQVcsQ0FBQztZQUN6QixjQUFjLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtTQUMzRSxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTztRQUNMLE1BQU0sSUFBSSxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztJQUMxRSxDQUFDOzs7O0FBcFhEOzs7R0FHRztBQUNZLHVDQUFpQixHQUFHLENBQUMsQUFBSixDQUFLO0FBTDFCLHNEQUFxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7XG4gIEFubm90YXRpb25zLFxuICBhd3NfY29kZWJ1aWxkIGFzIGNvZGVidWlsZCxcbiAgYXdzX2VjMiBhcyBlYzIsXG4gIGF3c19lY3IgYXMgZWNyLFxuICBhd3NfZXZlbnRzIGFzIGV2ZW50cyxcbiAgYXdzX2V2ZW50c190YXJnZXRzIGFzIGV2ZW50c190YXJnZXRzLFxuICBhd3NfaWFtIGFzIGlhbSxcbiAgYXdzX2xvZ3MgYXMgbG9ncyxcbiAgYXdzX3MzX2Fzc2V0cyBhcyBzM19hc3NldHMsXG4gIEN1c3RvbVJlc291cmNlLFxuICBEdXJhdGlvbixcbiAgUmVtb3ZhbFBvbGljeSxcbn0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ29tcHV0ZVR5cGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY29kZWJ1aWxkJztcbmltcG9ydCB7IFRhZ011dGFiaWxpdHksIFRhZ1N0YXR1cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3InO1xuaW1wb3J0IHsgUmV0ZW50aW9uRGF5cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sb2dzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgSVJ1bm5lckltYWdlQnVpbGRlciB9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7IHNpbmdsZXRvbkxhbWJkYSB9IGZyb20gJy4uLy4uL3V0aWxzJztcbmltcG9ydCB7IEJ1aWxkSW1hZ2VGdW5jdGlvbiB9IGZyb20gJy4uL2J1aWxkLWltYWdlLWZ1bmN0aW9uJztcbmltcG9ydCB7IEFyY2hpdGVjdHVyZSwgT3MsIFJ1bm5lckFtaSwgUnVubmVySW1hZ2UsIFJ1bm5lclZlcnNpb24gfSBmcm9tICcuLi9jb21tb24nO1xuXG4vKlxuQVdTIEltYWdlIEJ1aWxkZXIgd2FzIG5vdCB1c2VkIGJlY2F1c2U6XG4gIDEuIEl0J3MgdG9vIHNsb3cuIEl0IGhhcyB3ZWlyZCAxNSBtaW51dGVzIG92ZXJoZWFkIHdoZXJlIGl0IHNlZW1zIHRvIGp1c3QgYmUgd2FpdGluZy5cbiAgMi4gTm8gZWFzeSBsb2cgdmlzaWJpbGl0eS5cbiAgMy4gVmVyc2lvbnMgbmVlZCB0byBiZSBidW1wZWQgbWFudWFsbHkuXG4gKi9cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBDb2RlQnVpbGRJbWFnZUJ1aWxkZXIgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvZGVCdWlsZEltYWdlQnVpbGRlclByb3BzIHtcbiAgLyoqXG4gICAqIEltYWdlIGFyY2hpdGVjdHVyZS5cbiAgICpcbiAgICogQGRlZmF1bHQgQXJjaGl0ZWN0dXJlLlg4Nl82NFxuICAgKi9cbiAgcmVhZG9ubHkgYXJjaGl0ZWN0dXJlPzogQXJjaGl0ZWN0dXJlO1xuXG4gIC8qKlxuICAgKiBJbWFnZSBPUy5cbiAgICpcbiAgICogQGRlZmF1bHQgT1MuTElOVVhcbiAgICovXG4gIHJlYWRvbmx5IG9zPzogT3M7XG5cbiAgLyoqXG4gICAqIFBhdGggdG8gRG9ja2VyZmlsZSB0byBiZSBidWlsdC4gSXQgY2FuIGJlIGEgcGF0aCB0byBhIERvY2tlcmZpbGUsIGEgZm9sZGVyIGNvbnRhaW5pbmcgYSBEb2NrZXJmaWxlLCBvciBhIHppcCBmaWxlIGNvbnRhaW5pbmcgYSBEb2NrZXJmaWxlLlxuICAgKi9cbiAgcmVhZG9ubHkgZG9ja2VyZmlsZVBhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogVmVyc2lvbiBvZiBHaXRIdWIgUnVubmVycyB0byBpbnN0YWxsLlxuICAgKlxuICAgKiBAZGVmYXVsdCBsYXRlc3QgdmVyc2lvbiBhdmFpbGFibGVcbiAgICovXG4gIHJlYWRvbmx5IHJ1bm5lclZlcnNpb24/OiBSdW5uZXJWZXJzaW9uO1xuXG4gIC8qKlxuICAgKiBTY2hlZHVsZSB0aGUgaW1hZ2UgdG8gYmUgcmVidWlsdCBldmVyeSBnaXZlbiBpbnRlcnZhbC4gVXNlZnVsIGZvciBrZWVwaW5nIHRoZSBpbWFnZSB1cC1kby1kYXRlIHdpdGggdGhlIGxhdGVzdCBHaXRIdWIgcnVubmVyIHZlcnNpb24gYW5kIGxhdGVzdCBPUyB1cGRhdGVzLlxuICAgKlxuICAgKiBTZXQgdG8gemVybyB0byBkaXNhYmxlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBEdXJhdGlvbi5kYXlzKDcpXG4gICAqL1xuICByZWFkb25seSByZWJ1aWxkSW50ZXJ2YWw/OiBEdXJhdGlvbjtcblxuICAvKipcbiAgICogVlBDIHRvIGJ1aWxkIHRoZSBpbWFnZSBpbi5cbiAgICpcbiAgICogQGRlZmF1bHQgbm8gVlBDXG4gICAqL1xuICByZWFkb25seSB2cGM/OiBlYzIuSVZwYztcblxuICAvKipcbiAgICogU2VjdXJpdHkgR3JvdXAgdG8gYXNzaWduIHRvIHRoaXMgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IHB1YmxpYyBwcm9qZWN0IHdpdGggbm8gc2VjdXJpdHkgZ3JvdXBcbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXA/OiBlYzIuSVNlY3VyaXR5R3JvdXA7XG5cbiAgLyoqXG4gICAqIFdoZXJlIHRvIHBsYWNlIHRoZSBuZXR3b3JrIGludGVyZmFjZXMgd2l0aGluIHRoZSBWUEMuXG4gICAqXG4gICAqIEBkZWZhdWx0IG5vIHN1Ym5ldFxuICAgKi9cbiAgcmVhZG9ubHkgc3VibmV0U2VsZWN0aW9uPzogZWMyLlN1Ym5ldFNlbGVjdGlvbjtcblxuICAvKipcbiAgICogVGhlIHR5cGUgb2YgY29tcHV0ZSB0byB1c2UgZm9yIHRoaXMgYnVpbGQuXG4gICAqIFNlZSB0aGUge0BsaW5rIENvbXB1dGVUeXBlfSBlbnVtIGZvciB0aGUgcG9zc2libGUgdmFsdWVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCB7QGxpbmsgQ29tcHV0ZVR5cGUjU01BTEx9XG4gICAqL1xuICByZWFkb25seSBjb21wdXRlVHlwZT86IGNvZGVidWlsZC5Db21wdXRlVHlwZTtcblxuICAvKipcbiAgICogQnVpbGQgaW1hZ2UgdG8gdXNlIGluIENvZGVCdWlsZC4gVGhpcyBpcyB0aGUgaW1hZ2UgdGhhdCdzIGdvaW5nIHRvIHJ1biB0aGUgY29kZSB0aGF0IGJ1aWxkcyB0aGUgcnVubmVyIGltYWdlLlxuICAgKlxuICAgKiBUaGUgb25seSBhY3Rpb24gdGFrZW4gaW4gQ29kZUJ1aWxkIGlzIHJ1bm5pbmcgYGRvY2tlciBidWlsZGAuIFlvdSB3b3VsZCB0aGVyZWZvcmUgbm90IG5lZWQgdG8gY2hhbmdlIHRoaXMgc2V0dGluZyBvZnRlbi5cbiAgICpcbiAgICogQGRlZmF1bHQgVWJ1bnR1IDIwLjA0IGZvciB4NjQgYW5kIEFtYXpvbiBMaW51eCAyIGZvciBBUk02NFxuICAgKi9cbiAgcmVhZG9ubHkgYnVpbGRJbWFnZT86IGNvZGVidWlsZC5JQnVpbGRJbWFnZTtcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBtaW51dGVzIGFmdGVyIHdoaWNoIEFXUyBDb2RlQnVpbGQgc3RvcHMgdGhlIGJ1aWxkIGlmIGl0J3NcbiAgICogbm90IGNvbXBsZXRlLiBGb3IgdmFsaWQgdmFsdWVzLCBzZWUgdGhlIHRpbWVvdXRJbk1pbnV0ZXMgZmllbGQgaW4gdGhlIEFXU1xuICAgKiBDb2RlQnVpbGQgVXNlciBHdWlkZS5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24uaG91cnMoMSlcbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBEdXJhdGlvbjtcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBkYXlzIGxvZyBldmVudHMgYXJlIGtlcHQgaW4gQ2xvdWRXYXRjaCBMb2dzLiBXaGVuIHVwZGF0aW5nXG4gICAqIHRoaXMgcHJvcGVydHksIHVuc2V0dGluZyBpdCBkb2Vzbid0IHJlbW92ZSB0aGUgbG9nIHJldGVudGlvbiBwb2xpY3kuIFRvXG4gICAqIHJlbW92ZSB0aGUgcmV0ZW50aW9uIHBvbGljeSwgc2V0IHRoZSB2YWx1ZSB0byBgSU5GSU5JVEVgLlxuICAgKlxuICAgKiBAZGVmYXVsdCBsb2dzLlJldGVudGlvbkRheXMuT05FX01PTlRIXG4gICAqL1xuICByZWFkb25seSBsb2dSZXRlbnRpb24/OiBsb2dzLlJldGVudGlvbkRheXM7XG5cbiAgLyoqXG4gICAqIFJlbW92YWwgcG9saWN5IGZvciBsb2dzIG9mIGltYWdlIGJ1aWxkcy4gSWYgZGVwbG95bWVudCBmYWlscyBvbiB0aGUgY3VzdG9tIHJlc291cmNlLCB0cnkgc2V0dGluZyB0aGlzIHRvIGBSZW1vdmFsUG9saWN5LlJFVEFJTmAuIFRoaXMgd2F5IHRoZSBDb2RlQnVpbGQgbG9ncyBjYW4gc3RpbGwgYmUgdmlld2VkLCBhbmQgeW91IGNhbiBzZWUgd2h5IHRoZSBidWlsZCBmYWlsZWQuXG4gICAqXG4gICAqIFdlIHRyeSB0byBub3QgbGVhdmUgYW55dGhpbmcgYmVoaW5kIHdoZW4gcmVtb3ZlZC4gQnV0IHNvbWV0aW1lcyBhIGxvZyBzdGF5aW5nIGJlaGluZCBpcyB1c2VmdWwuXG4gICAqXG4gICAqIEBkZWZhdWx0IFJlbW92YWxQb2xpY3kuREVTVFJPWVxuICAgKi9cbiAgcmVhZG9ubHkgbG9nUmVtb3ZhbFBvbGljeT86IFJlbW92YWxQb2xpY3k7XG59XG5cbi8qKlxuICogQW4gaW1hZ2UgYnVpbGRlciB0aGF0IHVzZXMgQ29kZUJ1aWxkIHRvIGJ1aWxkIERvY2tlciBpbWFnZXMgcHJlLWJha2VkIHdpdGggYWxsIHRoZSBHaXRIdWIgQWN0aW9ucyBydW5uZXIgcmVxdWlyZW1lbnRzLiBCdWlsZGVycyBjYW4gYmUgdXNlZCB3aXRoIHJ1bm5lciBwcm92aWRlcnMuXG4gKlxuICogRWFjaCBidWlsZGVyIHJlLXJ1bnMgYXV0b21hdGljYWxseSBhdCBhIHNldCBpbnRlcnZhbCB0byBtYWtlIHN1cmUgdGhlIGltYWdlcyBjb250YWluIHRoZSBsYXRlc3QgdmVyc2lvbnMgb2YgZXZlcnl0aGluZy5cbiAqXG4gKiBZb3UgY2FuIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGlzIGNvbnN0cnVjdCB0byBjdXN0b21pemUgdGhlIGltYWdlIHVzZWQgdG8gc3Bpbi11cCBydW5uZXJzLiBFYWNoIHByb3ZpZGVyIGhhcyBpdHMgb3duIHJlcXVpcmVtZW50cyBmb3Igd2hhdCBhbiBpbWFnZSBzaG91bGQgZG8uIFRoYXQncyB3aHkgdGhleSBlYWNoIHByb3ZpZGUgdGhlaXIgb3duIERvY2tlcmZpbGUuXG4gKlxuICogRm9yIGV4YW1wbGUsIHRvIHNldCBhIHNwZWNpZmljIHJ1bm5lciB2ZXJzaW9uLCByZWJ1aWxkIHRoZSBpbWFnZSBldmVyeSAyIHdlZWtzLCBhbmQgYWRkIGEgZmV3IHBhY2thZ2VzIGZvciB0aGUgRmFyZ2F0ZSBwcm92aWRlciwgdXNlOlxuICpcbiAqIGBgYFxuICogY29uc3QgYnVpbGRlciA9IG5ldyBDb2RlQnVpbGRJbWFnZUJ1aWxkZXIodGhpcywgJ0J1aWxkZXInLCB7XG4gKiAgICAgZG9ja2VyZmlsZVBhdGg6IEZhcmdhdGVQcm92aWRlci5MSU5VWF9YNjRfRE9DS0VSRklMRV9QQVRILFxuICogICAgIHJ1bm5lclZlcnNpb246IFJ1bm5lclZlcnNpb24uc3BlY2lmaWMoJzIuMjkzLjAnKSxcbiAqICAgICByZWJ1aWxkSW50ZXJ2YWw6IER1cmF0aW9uLmRheXMoMTQpLFxuICogfSk7XG4gKiBidWlsZGVyLnNldEJ1aWxkQXJnKCdFWFRSQV9QQUNLQUdFUycsICduZ2lueCB4ei11dGlscycpO1xuICogbmV3IEZhcmdhdGVSdW5uZXIodGhpcywgJ0ZhcmdhdGUgcHJvdmlkZXInLCB7XG4gKiAgICAgbGFiZWw6ICdjdXN0b21pemVkLWZhcmdhdGUnLFxuICogICAgIGltYWdlQnVpbGRlcjogYnVpbGRlcixcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQGRlcHJlY2F0ZWQgdXNlIFJ1bm5lckltYWdlQnVpbGRlclxuICovXG5leHBvcnQgY2xhc3MgQ29kZUJ1aWxkSW1hZ2VCdWlsZGVyIGV4dGVuZHMgQ29uc3RydWN0IGltcGxlbWVudHMgSVJ1bm5lckltYWdlQnVpbGRlciB7XG4gIC8qKlxuICAgKiBCdW1wIHRoaXMgbnVtYmVyIGV2ZXJ5IHRpbWUgdGhlIGJ1aWxkc3BlYyBvciBhbnkgaW1wb3J0YW50IHNldHRpbmcgb2YgdGhlIHByb2plY3QgY2hhbmdlcy4gSXQgd2lsbCBmb3JjZSBhIHJlYnVpbGQgb2YgdGhlIGltYWdlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgQlVJTERTUEVDX1ZFUlNJT04gPSAyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgYXJjaGl0ZWN0dXJlOiBBcmNoaXRlY3R1cmU7XG4gIHByaXZhdGUgcmVhZG9ubHkgb3M6IE9zO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlcG9zaXRvcnk6IGVjci5SZXBvc2l0b3J5O1xuICBwcml2YXRlIHJlYWRvbmx5IGRvY2tlcmZpbGU6IHMzX2Fzc2V0cy5Bc3NldDtcbiAgcHJpdmF0ZSBwcmVCdWlsZDogc3RyaW5nW10gPSBbXTtcbiAgcHJpdmF0ZSBwb3N0QnVpbGQ6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgYnVpbGRBcmdzOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHBvbGljeVN0YXRlbWVudHM6IGlhbS5Qb2xpY3lTdGF0ZW1lbnRbXSA9IFtdO1xuICBwcml2YXRlIHNlY29uZGFyeUFzc2V0czogTWFwPHN0cmluZywgczNfYXNzZXRzLkFzc2V0PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSByZWFkb25seSBidWlsZEltYWdlOiBjb2RlYnVpbGQuSUJ1aWxkSW1hZ2U7XG4gIHByaXZhdGUgYm91bmRJbWFnZT86IFJ1bm5lckltYWdlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlYWRvbmx5IHByb3BzOiBDb2RlQnVpbGRJbWFnZUJ1aWxkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBpZiAocHJvcHMuc3VibmV0U2VsZWN0aW9uPy5zdWJuZXRUeXBlID09IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfSVNPTEFURUQpIHtcbiAgICAgIEFubm90YXRpb25zLm9mKHRoaXMpLmFkZFdhcm5pbmcoJ1ByaXZhdGUgaXNvbGF0ZWQgc3VibmV0cyBjYW5ub3QgcHVsbCBmcm9tIHB1YmxpYyBFQ1IgYW5kIFZQQyBlbmRwb2ludCBpcyBub3Qgc3VwcG9ydGVkIHlldC4gJyArXG4gICAgICAgICAgJ1NlZSBodHRwczovL2dpdGh1Yi5jb20vYXdzL2NvbnRhaW5lcnMtcm9hZG1hcC9pc3N1ZXMvMTE2MCcpO1xuICAgIH1cblxuICAgIC8vIHNldCBwbGF0Zm9ybVxuICAgIHRoaXMuYXJjaGl0ZWN0dXJlID0gcHJvcHMuYXJjaGl0ZWN0dXJlID8/IEFyY2hpdGVjdHVyZS5YODZfNjQ7XG4gICAgdGhpcy5vcyA9IHByb3BzLm9zID8/IE9zLkxJTlVYO1xuXG4gICAgLy8gY3JlYXRlIHJlcG9zaXRvcnkgdGhhdCBvbmx5IGtlZXBzIG9uZSB0YWdcbiAgICB0aGlzLnJlcG9zaXRvcnkgPSBuZXcgZWNyLlJlcG9zaXRvcnkodGhpcywgJ1JlcG9zaXRvcnknLCB7XG4gICAgICBpbWFnZVNjYW5PblB1c2g6IHRydWUsXG4gICAgICBpbWFnZVRhZ011dGFiaWxpdHk6IFRhZ011dGFiaWxpdHkuTVVUQUJMRSxcbiAgICAgIHJlbW92YWxQb2xpY3k6IFJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICAgIGxpZmVjeWNsZVJ1bGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1JlbW92ZSB1bnRhZ2dlZCBpbWFnZXMgdGhhdCBoYXZlIGJlZW4gcmVwbGFjZWQgYnkgQ29kZUJ1aWxkJyxcbiAgICAgICAgICB0YWdTdGF0dXM6IFRhZ1N0YXR1cy5VTlRBR0dFRCxcbiAgICAgICAgICBtYXhJbWFnZUFnZTogRHVyYXRpb24uZGF5cygxKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICAvLyB1cGxvYWQgRG9ja2VyZmlsZSB0byBTMyBhcyBhbiBhc3NldFxuICAgIHRoaXMuZG9ja2VyZmlsZSA9IG5ldyBzM19hc3NldHMuQXNzZXQodGhpcywgJ0RvY2tlcmZpbGUnLCB7XG4gICAgICBwYXRoOiBwcm9wcy5kb2NrZXJmaWxlUGF0aCxcbiAgICB9KTtcblxuICAgIC8vIGNob29zZSBidWlsZCBpbWFnZVxuICAgIHRoaXMuYnVpbGRJbWFnZSA9IHByb3BzPy5idWlsZEltYWdlID8/IHRoaXMuZ2V0QnVpbGRJbWFnZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwbG9hZHMgYSBmb2xkZXIgdG8gdGhlIGJ1aWxkIHNlcnZlciBhdCBhIGdpdmVuIGZvbGRlciBuYW1lLlxuICAgKlxuICAgKiBAcGFyYW0gc291cmNlUGF0aCBwYXRoIHRvIHNvdXJjZSBkaXJlY3RvcnlcbiAgICogQHBhcmFtIGRlc3ROYW1lIG5hbWUgb2YgZGVzdGluYXRpb24gZm9sZGVyXG4gICAqL1xuICBwdWJsaWMgYWRkRmlsZXMoc291cmNlUGF0aDogc3RyaW5nLCBkZXN0TmFtZTogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuYm91bmRJbWFnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZSBpcyBhbHJlYWR5IGJvdW5kLiBVc2UgdGhpcyBtZXRob2QgYmVmb3JlIHBhc3NpbmcgdGhlIGJ1aWxkZXIgdG8gYSBydW5uZXIgcHJvdmlkZXIuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYXNzZXQgPSBuZXcgczNfYXNzZXRzLkFzc2V0KHRoaXMsIGRlc3ROYW1lLCB7IHBhdGg6IHNvdXJjZVBhdGggfSk7XG4gICAgdGhpcy5zZWNvbmRhcnlBc3NldHMuc2V0KGRlc3ROYW1lLCBhc3NldCk7XG4gICAgdGhpcy5wcmVCdWlsZC5wdXNoKGBybSAtcmYgXCIke2Rlc3ROYW1lfVwiICYmIGNwIC1yIFwiJENPREVCVUlMRF9TUkNfRElSXyR7ZGVzdE5hbWV9XCIgXCIke2Rlc3ROYW1lfVwiYCk7IC8vIHN5bWxpbmtzIGRvbid0IHdvcmsgd2l0aCBkb2NrZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgY29tbWFuZCB0aGF0IHJ1bnMgYmVmb3JlIGBkb2NrZXIgYnVpbGRgLlxuICAgKlxuICAgKiBAcGFyYW0gY29tbWFuZCBjb21tYW5kIHRvIGFkZFxuICAgKi9cbiAgcHVibGljIGFkZFByZUJ1aWxkQ29tbWFuZChjb21tYW5kOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5ib3VuZEltYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlIGlzIGFscmVhZHkgYm91bmQuIFVzZSB0aGlzIG1ldGhvZCBiZWZvcmUgcGFzc2luZyB0aGUgYnVpbGRlciB0byBhIHJ1bm5lciBwcm92aWRlci4nKTtcbiAgICB9XG4gICAgdGhpcy5wcmVCdWlsZC5wdXNoKGNvbW1hbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBjb21tYW5kIHRoYXQgcnVucyBhZnRlciBgZG9ja2VyIGJ1aWxkYCBhbmQgYGRvY2tlciBwdXNoYC5cbiAgICpcbiAgICogQHBhcmFtIGNvbW1hbmQgY29tbWFuZCB0byBhZGRcbiAgICovXG4gIHB1YmxpYyBhZGRQb3N0QnVpbGRDb21tYW5kKGNvbW1hbmQ6IHN0cmluZykge1xuICAgIGlmICh0aGlzLmJvdW5kSW1hZ2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW1hZ2UgaXMgYWxyZWFkeSBib3VuZC4gVXNlIHRoaXMgbWV0aG9kIGJlZm9yZSBwYXNzaW5nIHRoZSBidWlsZGVyIHRvIGEgcnVubmVyIHByb3ZpZGVyLicpO1xuICAgIH1cbiAgICB0aGlzLnBvc3RCdWlsZC5wdXNoKGNvbW1hbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBidWlsZCBhcmd1bWVudCBmb3IgRG9ja2VyLiBTZWUgdGhlIGRvY3VtZW50YXRpb24gZm9yIHRoZSBEb2NrZXJmaWxlIHlvdSdyZSB1c2luZyBmb3IgYSBsaXN0IG9mIHN1cHBvcnRlZCBidWlsZCBhcmd1bWVudHMuXG4gICAqXG4gICAqIEBwYXJhbSBuYW1lIGJ1aWxkIGFyZ3VtZW50IG5hbWVcbiAgICogQHBhcmFtIHZhbHVlIGJ1aWxkIGFyZ3VtZW50IHZhbHVlXG4gICAqL1xuICBwdWJsaWMgc2V0QnVpbGRBcmcobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuYm91bmRJbWFnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZSBpcyBhbHJlYWR5IGJvdW5kLiBVc2UgdGhpcyBtZXRob2QgYmVmb3JlIHBhc3NpbmcgdGhlIGJ1aWxkZXIgdG8gYSBydW5uZXIgcHJvdmlkZXIuJyk7XG4gICAgfVxuICAgIHRoaXMuYnVpbGRBcmdzLnNldChuYW1lLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgcG9saWN5IHN0YXRlbWVudCB0byB0aGUgYnVpbGRlciB0byBhY2Nlc3MgcmVzb3VyY2VzIHJlcXVpcmVkIHRvIHRoZSBpbWFnZSBidWlsZC5cbiAgICpcbiAgICogQHBhcmFtIHN0YXRlbWVudCBJQU0gcG9saWN5IHN0YXRlbWVudFxuICAgKi9cbiAgcHVibGljIGFkZFBvbGljeVN0YXRlbWVudChzdGF0ZW1lbnQ6IGlhbS5Qb2xpY3lTdGF0ZW1lbnQpIHtcbiAgICBpZiAodGhpcy5ib3VuZEltYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlIGlzIGFscmVhZHkgYm91bmQuIFVzZSB0aGlzIG1ldGhvZCBiZWZvcmUgcGFzc2luZyB0aGUgYnVpbGRlciB0byBhIHJ1bm5lciBwcm92aWRlci4nKTtcbiAgICB9XG4gICAgdGhpcy5wb2xpY3lTdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgZXh0cmEgdHJ1c3RlZCBjZXJ0aWZpY2F0ZXMuIFRoaXMgaGVscHMgZGVhbCB3aXRoIHNlbGYtc2lnbmVkIGNlcnRpZmljYXRlcyBmb3IgR2l0SHViIEVudGVycHJpc2UgU2VydmVyLlxuICAgKlxuICAgKiBBbGwgZmlyc3QgcGFydHkgRG9ja2VyZmlsZXMgc3VwcG9ydCB0aGlzLiBPdGhlcnMgbWF5IG5vdC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggcGF0aCB0byBkaXJlY3RvcnkgY29udGFpbmluZyBhIGZpbGUgY2FsbGVkIGNlcnRzLnBlbSBjb250YWluaW5nIGFsbCB0aGUgcmVxdWlyZWQgY2VydGlmaWNhdGVzXG4gICAqL1xuICBwdWJsaWMgYWRkRXh0cmFDZXJ0aWZpY2F0ZXMocGF0aDogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuYm91bmRJbWFnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZSBpcyBhbHJlYWR5IGJvdW5kLiBVc2UgdGhpcyBtZXRob2QgYmVmb3JlIHBhc3NpbmcgdGhlIGJ1aWxkZXIgdG8gYSBydW5uZXIgcHJvdmlkZXIuJyk7XG4gICAgfVxuICAgIHRoaXMuYWRkRmlsZXMocGF0aCwgJ2V4dHJhX2NlcnRzJyk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIGJ5IElSdW5uZXJQcm92aWRlciB0byBmaW5hbGl6ZSBzZXR0aW5ncyBhbmQgY3JlYXRlIHRoZSBpbWFnZSBidWlsZGVyLlxuICAgKi9cbiAgcHVibGljIGJpbmREb2NrZXJJbWFnZSgpOiBSdW5uZXJJbWFnZSB7XG4gICAgaWYgKHRoaXMuYm91bmRJbWFnZSkge1xuICAgICAgcmV0dXJuIHRoaXMuYm91bmRJbWFnZTtcbiAgICB9XG5cbiAgICAvLyBsb2cgZ3JvdXAgZm9yIHRoZSBpbWFnZSBidWlsZHNcbiAgICBjb25zdCBsb2dHcm91cCA9IG5ldyBsb2dzLkxvZ0dyb3VwKFxuICAgICAgdGhpcyxcbiAgICAgICdMb2dzJyxcbiAgICAgIHtcbiAgICAgICAgcmV0ZW50aW9uOiB0aGlzLnByb3BzLmxvZ1JldGVudGlvbiA/PyBSZXRlbnRpb25EYXlzLk9ORV9NT05USCxcbiAgICAgICAgcmVtb3ZhbFBvbGljeTogdGhpcy5wcm9wcy5sb2dSZW1vdmFsUG9saWN5ID8/IFJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIGdlbmVyYXRlIGJ1aWxkU3BlY1xuICAgIGNvbnN0IGJ1aWxkU3BlYyA9IHRoaXMuZ2V0QnVpbGRTcGVjKHRoaXMucmVwb3NpdG9yeSwgbG9nR3JvdXAsIHRoaXMucHJvcHMucnVubmVyVmVyc2lvbik7XG5cbiAgICAvLyBjcmVhdGUgQ29kZUJ1aWxkIHByb2plY3QgdGhhdCBidWlsZHMgRG9ja2VyZmlsZSBhbmQgcHVzaGVzIHRvIHJlcG9zaXRvcnlcbiAgICBjb25zdCBwcm9qZWN0ID0gbmV3IGNvZGVidWlsZC5Qcm9qZWN0KHRoaXMsICdDb2RlQnVpbGQnLCB7XG4gICAgICBkZXNjcmlwdGlvbjogYEJ1aWxkIGRvY2tlciBpbWFnZSBmb3Igc2VsZi1ob3N0ZWQgR2l0SHViIHJ1bm5lciAke3RoaXMubm9kZS5wYXRofSAoJHt0aGlzLm9zLm5hbWV9LyR7dGhpcy5hcmNoaXRlY3R1cmUubmFtZX0pYCxcbiAgICAgIGJ1aWxkU3BlYzogY29kZWJ1aWxkLkJ1aWxkU3BlYy5mcm9tT2JqZWN0KGJ1aWxkU3BlYyksXG4gICAgICBzb3VyY2U6IGNvZGVidWlsZC5Tb3VyY2UuczMoe1xuICAgICAgICBidWNrZXQ6IHRoaXMuZG9ja2VyZmlsZS5idWNrZXQsXG4gICAgICAgIHBhdGg6IHRoaXMuZG9ja2VyZmlsZS5zM09iamVjdEtleSxcbiAgICAgIH0pLFxuICAgICAgdnBjOiB0aGlzLnByb3BzLnZwYyxcbiAgICAgIHNlY3VyaXR5R3JvdXBzOiB0aGlzLnByb3BzLnNlY3VyaXR5R3JvdXAgPyBbdGhpcy5wcm9wcy5zZWN1cml0eUdyb3VwXSA6IHVuZGVmaW5lZCxcbiAgICAgIHN1Ym5ldFNlbGVjdGlvbjogdGhpcy5wcm9wcy5zdWJuZXRTZWxlY3Rpb24sXG4gICAgICB0aW1lb3V0OiB0aGlzLnByb3BzLnRpbWVvdXQgPz8gRHVyYXRpb24uaG91cnMoMSksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBidWlsZEltYWdlOiB0aGlzLmJ1aWxkSW1hZ2UsXG4gICAgICAgIGNvbXB1dGVUeXBlOiB0aGlzLnByb3BzLmNvbXB1dGVUeXBlID8/IENvbXB1dGVUeXBlLlNNQUxMLFxuICAgICAgICBwcml2aWxlZ2VkOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIGxvZ2dpbmc6IHtcbiAgICAgICAgY2xvdWRXYXRjaDoge1xuICAgICAgICAgIGxvZ0dyb3VwLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIHBlcm1pc3Npb25zXG4gICAgdGhpcy5yZXBvc2l0b3J5LmdyYW50UHVsbFB1c2gocHJvamVjdCk7XG4gICAgdGhpcy5wb2xpY3lTdGF0ZW1lbnRzLmZvckVhY2gocHJvamVjdC5hZGRUb1JvbGVQb2xpY3kpO1xuXG4gICAgLy8gY2FsbCBDb2RlQnVpbGQgZHVyaW5nIGRlcGxveW1lbnQgYW5kIGRlbGV0ZSBhbGwgaW1hZ2VzIGZyb20gcmVwb3NpdG9yeSBkdXJpbmcgZGVzdHJ1Y3Rpb25cbiAgICBjb25zdCBjciA9IHRoaXMuY3VzdG9tUmVzb3VyY2UocHJvamVjdCk7XG5cbiAgICAvLyByZWJ1aWxkIGltYWdlIG9uIGEgc2NoZWR1bGVcbiAgICB0aGlzLnJlYnVpbGRJbWFnZU9uU2NoZWR1bGUocHJvamVjdCwgdGhpcy5wcm9wcy5yZWJ1aWxkSW50ZXJ2YWwpO1xuXG4gICAgZm9yIChjb25zdCBbYXNzZXRQYXRoLCBhc3NldF0gb2YgdGhpcy5zZWNvbmRhcnlBc3NldHMuZW50cmllcygpKSB7XG4gICAgICBwcm9qZWN0LmFkZFNlY29uZGFyeVNvdXJjZShjb2RlYnVpbGQuU291cmNlLnMzKHtcbiAgICAgICAgaWRlbnRpZmllcjogYXNzZXRQYXRoLFxuICAgICAgICBidWNrZXQ6IGFzc2V0LmJ1Y2tldCxcbiAgICAgICAgcGF0aDogYXNzZXQuczNPYmplY3RLZXksXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgdGhpcy5ib3VuZEltYWdlID0ge1xuICAgICAgaW1hZ2VSZXBvc2l0b3J5OiBlY3IuUmVwb3NpdG9yeS5mcm9tUmVwb3NpdG9yeUF0dHJpYnV0ZXModGhpcywgJ0RlcGVuZGFibGUgSW1hZ2UnLCB7XG4gICAgICAgIC8vIFRoZXJlIGFyZSBzaW1wbGVyIHdheXMgdG8gZ2V0IG5hbWUgYW5kIEFSTiwgYnV0IHdlIHdhbnQgYW4gaW1hZ2Ugb2JqZWN0IHRoYXQgZGVwZW5kcyBvbiB0aGUgY3VzdG9tIHJlc291cmNlLlxuICAgICAgICAvLyBXZSB3YW50IHdob2V2ZXIgaXMgdXNpbmcgdGhpcyBpbWFnZSB0byBhdXRvbWF0aWNhbGx5IHdhaXQgZm9yIENvZGVCdWlsZCB0byBzdGFydCBhbmQgZmluaXNoIHRocm91Z2ggdGhlIGN1c3RvbSByZXNvdXJjZS5cbiAgICAgICAgcmVwb3NpdG9yeU5hbWU6IGNyLmdldEF0dFN0cmluZygnTmFtZScpLFxuICAgICAgICByZXBvc2l0b3J5QXJuOiBjci5yZWYsXG4gICAgICB9KSxcbiAgICAgIGltYWdlVGFnOiAnbGF0ZXN0JyxcbiAgICAgIGFyY2hpdGVjdHVyZTogdGhpcy5hcmNoaXRlY3R1cmUsXG4gICAgICBvczogdGhpcy5vcyxcbiAgICAgIGxvZ0dyb3VwLFxuICAgICAgcnVubmVyVmVyc2lvbjogdGhpcy5wcm9wcy5ydW5uZXJWZXJzaW9uID8/IFJ1bm5lclZlcnNpb24ubGF0ZXN0KCksXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5ib3VuZEltYWdlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRCdWlsZEltYWdlKCk6IGNvZGVidWlsZC5JQnVpbGRJbWFnZSB7XG4gICAgaWYgKHRoaXMub3MuaXMoT3MuTElOVVgpKSB7XG4gICAgICBpZiAodGhpcy5hcmNoaXRlY3R1cmUuaXMoQXJjaGl0ZWN0dXJlLlg4Nl82NCkpIHtcbiAgICAgICAgcmV0dXJuIGNvZGVidWlsZC5MaW51eEJ1aWxkSW1hZ2UuU1RBTkRBUkRfNl8wO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmFyY2hpdGVjdHVyZS5pcyhBcmNoaXRlY3R1cmUuQVJNNjQpKSB7XG4gICAgICAgIHJldHVybiBjb2RlYnVpbGQuTGludXhBcm1CdWlsZEltYWdlLkFNQVpPTl9MSU5VWF8yX1NUQU5EQVJEXzJfMDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMub3MuaXMoT3MuV0lORE9XUykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29kZUJ1aWxkIGNhbm5vdCBiZSB1c2VkIHRvIGJ1aWxkIFdpbmRvd3MgRG9ja2VyIGltYWdlcyBodHRwczovL2dpdGh1Yi5jb20vZG9ja2VyLWxpYnJhcnkvZG9ja2VyL2lzc3Vlcy80OScpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgQ29kZUJ1aWxkIGltYWdlIGZvciAke3RoaXMub3MubmFtZX0vJHt0aGlzLmFyY2hpdGVjdHVyZS5uYW1lfWApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRCdWlsZFNwZWMocmVwb3NpdG9yeTogZWNyLlJlcG9zaXRvcnksIGxvZ0dyb3VwOiBsb2dzLkxvZ0dyb3VwLCBydW5uZXJWZXJzaW9uPzogUnVubmVyVmVyc2lvbik6IGFueSB7XG4gICAgLy8gZG9uJ3QgZm9yZ2V0IHRvIGNoYW5nZSBCVUlMRFNQRUNfVkVSU0lPTiB3aGVuIHRoZSBidWlsZFNwZWMgY2hhbmdlcywgYW5kIHlvdSB3YW50IHRvIHRyaWdnZXIgYSByZWJ1aWxkIG9uIGRlcGxveVxuICAgIGxldCBidWlsZEFyZ3MgPSAnJztcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZV0gb2YgdGhpcy5idWlsZEFyZ3MuZW50cmllcygpKSB7XG4gICAgICBidWlsZEFyZ3MgKz0gYCAtLWJ1aWxkLWFyZyBcIiR7bmFtZX1cIj1cIiR7dmFsdWV9XCJgO1xuICAgIH1cbiAgICBidWlsZEFyZ3MgKz0gYCAtLWJ1aWxkLWFyZyBSVU5ORVJfVkVSU0lPTj1cIiR7cnVubmVyVmVyc2lvbiA/IHJ1bm5lclZlcnNpb24udmVyc2lvbiA6IFJ1bm5lclZlcnNpb24ubGF0ZXN0KCkudmVyc2lvbn1cImA7XG5cbiAgICBjb25zdCB0aGlzU3RhY2sgPSBjZGsuU3RhY2sub2YodGhpcyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdmVyc2lvbjogJzAuMicsXG4gICAgICBlbnY6IHtcbiAgICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgICAgUkVQT19BUk46IHJlcG9zaXRvcnkucmVwb3NpdG9yeUFybixcbiAgICAgICAgICBSRVBPX1VSSTogcmVwb3NpdG9yeS5yZXBvc2l0b3J5VXJpLFxuICAgICAgICAgIFNUQUNLX0lEOiAndW5zcGVjaWZpZWQnLFxuICAgICAgICAgIFJFUVVFU1RfSUQ6ICd1bnNwZWNpZmllZCcsXG4gICAgICAgICAgTE9HSUNBTF9SRVNPVVJDRV9JRDogJ3Vuc3BlY2lmaWVkJyxcbiAgICAgICAgICBSRVNQT05TRV9VUkw6ICd1bnNwZWNpZmllZCcsXG4gICAgICAgICAgUlVOTkVSX1ZFUlNJT046IHJ1bm5lclZlcnNpb24gPyBydW5uZXJWZXJzaW9uLnZlcnNpb24gOiBSdW5uZXJWZXJzaW9uLmxhdGVzdCgpLnZlcnNpb24sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcGhhc2VzOiB7XG4gICAgICAgIHByZV9idWlsZDoge1xuICAgICAgICAgIGNvbW1hbmRzOiB0aGlzLnByZUJ1aWxkLmNvbmNhdChbXG4gICAgICAgICAgICAnbWtkaXIgLXAgZXh0cmFfY2VydHMnLFxuICAgICAgICAgICAgYGF3cyBlY3IgZ2V0LWxvZ2luLXBhc3N3b3JkIC0tcmVnaW9uIFwiJEFXU19ERUZBVUxUX1JFR0lPTlwiIHwgZG9ja2VyIGxvZ2luIC0tdXNlcm5hbWUgQVdTIC0tcGFzc3dvcmQtc3RkaW4gJHt0aGlzU3RhY2suYWNjb3VudH0uZGtyLmVjci4ke3RoaXNTdGFjay5yZWdpb259LmFtYXpvbmF3cy5jb21gLFxuICAgICAgICAgIF0pLFxuICAgICAgICB9LFxuICAgICAgICBidWlsZDoge1xuICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICBgZG9ja2VyIGJ1aWxkIC4gLXQgXCIkUkVQT19VUklcIiAke2J1aWxkQXJnc31gLFxuICAgICAgICAgICAgJ2RvY2tlciBwdXNoIFwiJFJFUE9fVVJJXCInLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIHBvc3RfYnVpbGQ6IHtcbiAgICAgICAgICBjb21tYW5kczogdGhpcy5wb3N0QnVpbGQuY29uY2F0KFtcbiAgICAgICAgICAgICdTVEFUVVM9XCJTVUNDRVNTXCInLFxuICAgICAgICAgICAgJ2lmIFsgJENPREVCVUlMRF9CVUlMRF9TVUNDRUVESU5HIC1uZSAxIF07IHRoZW4gU1RBVFVTPVwiRkFJTEVEXCI7IGZpJyxcbiAgICAgICAgICAgICdjYXQgPDxFT0YgPiAvdG1wL3BheWxvYWQuanNvblxcbicgK1xuICAgICAgICAgICAgJ3tcXG4nICtcbiAgICAgICAgICAgICcgIFwiU3RhY2tJZFwiOiBcIiRTVEFDS19JRFwiLFxcbicgK1xuICAgICAgICAgICAgJyAgXCJSZXF1ZXN0SWRcIjogXCIkUkVRVUVTVF9JRFwiLFxcbicgK1xuICAgICAgICAgICAgJyAgXCJMb2dpY2FsUmVzb3VyY2VJZFwiOiBcIiRMT0dJQ0FMX1JFU09VUkNFX0lEXCIsXFxuJyArXG4gICAgICAgICAgICAnICBcIlBoeXNpY2FsUmVzb3VyY2VJZFwiOiBcIiRSRVBPX0FSTlwiLFxcbicgK1xuICAgICAgICAgICAgJyAgXCJTdGF0dXNcIjogXCIkU1RBVFVTXCIsXFxuJyArXG4gICAgICAgICAgICBgICBcIlJlYXNvblwiOiBcIlNlZSBsb2dzIGluICR7bG9nR3JvdXAubG9nR3JvdXBOYW1lfS8kQ09ERUJVSUxEX0xPR19QQVRIIChkZXBsb3kgYWdhaW4gd2l0aCBcXCdjZGsgZGVwbG95IC1SXFwnIG9yIGxvZ1JlbW92YWxQb2xpY3k9UmVtb3ZhbFBvbGljeS5SRVRBSU4gaWYgdGhleSBhcmUgYWxyZWFkeSBkZWxldGVkKVwiLFxcbmAgK1xuICAgICAgICAgICAgYCAgXCJEYXRhXCI6IHtcIk5hbWVcIjogXCIke3JlcG9zaXRvcnkucmVwb3NpdG9yeU5hbWV9XCJ9XFxuYCArXG4gICAgICAgICAgICAnfVxcbicgK1xuICAgICAgICAgICAgJ0VPRicsXG4gICAgICAgICAgICAnaWYgWyBcIiRSRVNQT05TRV9VUkxcIiAhPSBcInVuc3BlY2lmaWVkXCIgXTsgdGhlbiBqcSAuIC90bXAvcGF5bG9hZC5qc29uOyBjdXJsIC1mc1NMIC1YIFBVVCAtSCBcIkNvbnRlbnQtVHlwZTpcIiAtZCBcIkAvdG1wL3BheWxvYWQuanNvblwiIFwiJFJFU1BPTlNFX1VSTFwiOyBmaScsXG4gICAgICAgICAgXSksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGN1c3RvbVJlc291cmNlKHByb2plY3Q6IGNvZGVidWlsZC5Qcm9qZWN0KSB7XG4gICAgY29uc3QgY3JIYW5kbGVyID0gc2luZ2xldG9uTGFtYmRhKEJ1aWxkSW1hZ2VGdW5jdGlvbiwgdGhpcywgJ2J1aWxkLWltYWdlJywge1xuICAgICAgZGVzY3JpcHRpb246ICdDdXN0b20gcmVzb3VyY2UgaGFuZGxlciB0aGF0IHRyaWdnZXJzIENvZGVCdWlsZCB0byBidWlsZCBydW5uZXIgaW1hZ2VzLCBhbmQgY2xlYW5zLXVwIGltYWdlcyBvbiBkZWxldGlvbicsXG4gICAgICB0aW1lb3V0OiBjZGsuRHVyYXRpb24ubWludXRlcygzKSxcbiAgICAgIGxvZ1JldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9NT05USCxcbiAgICB9KTtcblxuICAgIGNvbnN0IHBvbGljeSA9IG5ldyBpYW0uUG9saWN5KHRoaXMsICdDUiBQb2xpY3knLCB7XG4gICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbJ2NvZGVidWlsZDpTdGFydEJ1aWxkJ10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbcHJvamVjdC5wcm9qZWN0QXJuXSxcbiAgICAgICAgfSksXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbJ2VjcjpCYXRjaERlbGV0ZUltYWdlJywgJ2VjcjpMaXN0SW1hZ2VzJ10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbdGhpcy5yZXBvc2l0b3J5LnJlcG9zaXRvcnlBcm5dLFxuICAgICAgICB9KSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgY3JIYW5kbGVyLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShwb2xpY3kpO1xuXG4gICAgY29uc3QgY3IgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgJ0J1aWxkZXInLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IGNySGFuZGxlci5mdW5jdGlvbkFybixcbiAgICAgIHJlc291cmNlVHlwZTogJ0N1c3RvbTo6SW1hZ2VCdWlsZGVyJyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgUmVwb05hbWU6IHRoaXMucmVwb3NpdG9yeS5yZXBvc2l0b3J5TmFtZSxcbiAgICAgICAgUHJvamVjdE5hbWU6IHByb2plY3QucHJvamVjdE5hbWUsXG4gICAgICAgIC8vIFdlIGluY2x1ZGUgYSBoYXNoIHNvIHRoZSBpbWFnZSBpcyBidWlsdCBpbW1lZGlhdGVseSBvbiBjaGFuZ2VzLCBhbmQgd2UgZG9uJ3QgaGF2ZSB0byB3YWl0IGZvciBpdHMgc2NoZWR1bGVkIGJ1aWxkLlxuICAgICAgICAvLyBUaGlzIGFsc28gaGVscHMgbWFrZSBzdXJlIHRoZSBjaGFuZ2VzIGFyZSBnb29kLiBJZiB0aGV5IGhhdmUgYSBidWcsIHRoZSBkZXBsb3ltZW50IHdpbGwgZmFpbCBpbnN0ZWFkIG9mIGp1c3QgdGhlIHNjaGVkdWxlZCBidWlsZC5cbiAgICAgICAgQnVpbGRIYXNoOiB0aGlzLmhhc2hCdWlsZFNldHRpbmdzKCksXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gYWRkIGRlcGVuZGVuY2llcyB0byBtYWtlIHN1cmUgcmVzb3VyY2VzIGFyZSB0aGVyZSB3aGVuIHdlIG5lZWQgdGhlbVxuICAgIGNyLm5vZGUuYWRkRGVwZW5kZW5jeShwcm9qZWN0KTtcbiAgICBjci5ub2RlLmFkZERlcGVuZGVuY3kocG9saWN5KTtcbiAgICBjci5ub2RlLmFkZERlcGVuZGVuY3koY3JIYW5kbGVyKTtcblxuICAgIHJldHVybiBjcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gaGFzaCBvZiBhbGwgc2V0dGluZ3MgdGhhdCBjYW4gYWZmZWN0IHRoZSByZXN1bHQgaW1hZ2Ugc28gd2UgY2FuIHRyaWdnZXIgdGhlIGJ1aWxkIHdoZW4gaXQgY2hhbmdlcy5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgaGFzaEJ1aWxkU2V0dGluZ3MoKTogc3RyaW5nIHtcbiAgICAvLyBtYWluIERvY2tlcmZpbGVcbiAgICBsZXQgY29tcG9uZW50czogc3RyaW5nW10gPSBbdGhpcy5kb2NrZXJmaWxlLmFzc2V0SGFzaF07XG4gICAgLy8gYWxsIGFkZGl0aW9uYWwgZmlsZXNcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBhc3NldF0gb2YgdGhpcy5zZWNvbmRhcnlBc3NldHMuZW50cmllcygpKSB7XG4gICAgICBjb21wb25lbnRzLnB1c2gobmFtZSk7XG4gICAgICBjb21wb25lbnRzLnB1c2goYXNzZXQuYXNzZXRIYXNoKTtcbiAgICB9XG4gICAgLy8gYnVpbGRzcGVjLnltbCB2ZXJzaW9uXG4gICAgY29tcG9uZW50cy5wdXNoKGB2JHtDb2RlQnVpbGRJbWFnZUJ1aWxkZXIuQlVJTERTUEVDX1ZFUlNJT059YCk7XG4gICAgLy8gcnVubmVyIHZlcnNpb25cbiAgICBjb21wb25lbnRzLnB1c2godGhpcy5wcm9wcy5ydW5uZXJWZXJzaW9uPy52ZXJzaW9uID8/IFJ1bm5lclZlcnNpb24ubGF0ZXN0KCkudmVyc2lvbik7XG4gICAgLy8gdXNlciBjb21tYW5kc1xuICAgIGNvbXBvbmVudHMgPSBjb21wb25lbnRzLmNvbmNhdCh0aGlzLnByZUJ1aWxkKTtcbiAgICBjb21wb25lbnRzID0gY29tcG9uZW50cy5jb25jYXQodGhpcy5wb3N0QnVpbGQpO1xuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiB0aGlzLmJ1aWxkQXJncy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbXBvbmVudHMucHVzaChuYW1lKTtcbiAgICAgIGNvbXBvbmVudHMucHVzaCh2YWx1ZSk7XG4gICAgfVxuICAgIC8vIGhhc2ggaXRcbiAgICBjb25zdCBhbGwgPSBjb21wb25lbnRzLmpvaW4oJy0nKTtcbiAgICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpLnVwZGF0ZShhbGwpLmRpZ2VzdCgnaGV4Jyk7XG4gIH1cblxuICBwcml2YXRlIHJlYnVpbGRJbWFnZU9uU2NoZWR1bGUocHJvamVjdDogY29kZWJ1aWxkLlByb2plY3QsIHJlYnVpbGRJbnRlcnZhbD86IER1cmF0aW9uKSB7XG4gICAgcmVidWlsZEludGVydmFsID0gcmVidWlsZEludGVydmFsID8/IER1cmF0aW9uLmRheXMoNyk7XG4gICAgaWYgKHJlYnVpbGRJbnRlcnZhbC50b01pbGxpc2Vjb25kcygpICE9IDApIHtcbiAgICAgIGNvbnN0IHNjaGVkdWxlUnVsZSA9IG5ldyBldmVudHMuUnVsZSh0aGlzLCAnQnVpbGQgU2NoZWR1bGUnLCB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgUmVidWlsZCBydW5uZXIgaW1hZ2UgZm9yICR7dGhpcy5yZXBvc2l0b3J5LnJlcG9zaXRvcnlOYW1lfWAsXG4gICAgICAgIHNjaGVkdWxlOiBldmVudHMuU2NoZWR1bGUucmF0ZShyZWJ1aWxkSW50ZXJ2YWwpLFxuICAgICAgfSk7XG4gICAgICBzY2hlZHVsZVJ1bGUuYWRkVGFyZ2V0KG5ldyBldmVudHNfdGFyZ2V0cy5Db2RlQnVpbGRQcm9qZWN0KHByb2plY3QpKTtcbiAgICB9XG4gIH1cblxuICBnZXQgY29ubmVjdGlvbnMoKTogZWMyLkNvbm5lY3Rpb25zIHtcbiAgICByZXR1cm4gbmV3IGVjMi5Db25uZWN0aW9ucyh7XG4gICAgICBzZWN1cml0eUdyb3VwczogdGhpcy5wcm9wcy5zZWN1cml0eUdyb3VwID8gW3RoaXMucHJvcHMuc2VjdXJpdHlHcm91cF0gOiBbXSxcbiAgICB9KTtcbiAgfVxuXG4gIGJpbmRBbWkoKTogUnVubmVyQW1pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvZGVCdWlsZEltYWdlQnVpbGRlciBkb2VzIG5vdCBzdXBwb3J0IGJ1aWxkaW5nIEFNSXMnKTtcbiAgfVxufVxuIl19
|