@rlyle1179/serverless-aws-batch 1.1.19 → 1.1.20

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/lib/docker.js CHANGED
@@ -1,139 +1,139 @@
1
- const BbPromise = require('bluebird');
2
- const { spawnSync } = require('child_process');
3
- const _ = require('lodash');
4
- const fse = require('fs-extra');
5
- const path = require('path');
6
- const util = require('util');
7
- const { getDockerLoginToECRCommand } = require('./awscli');
8
-
9
- const DOCKER_TAG = `${Date.now()}`;
10
-
11
- /**
12
- * @returns {string} "<ECR Repo Name>:latest"
13
- */
14
- function getDockerImageName() {
15
- return `${this.provider.naming.getECRRepositoryURL()}:${DOCKER_TAG}`;
16
- }
17
-
18
- /**
19
- * Helper function to run a docker command
20
- * @param {string[]} options
21
- * @param {string} cwd Current working directory
22
- * @return {Object}
23
- */
24
- function dockerCommand(options, cwd = null, stdio = null) {
25
- const cmd = 'docker';
26
- var spawnOptions = {
27
- encoding: 'utf-8'
28
- }
29
- if (cwd != null) {
30
- spawnOptions.cwd = cwd;
31
- }
32
- if (stdio != null) {
33
- spawnOptions.stdio = stdio;
34
- }
35
-
36
- //console.error("dockerCommand:", options, spawnOptions);
37
- const ps = spawnSync(cmd, options, spawnOptions);
38
- if (ps.error) {
39
- if (ps.error.code === 'ENOENT') {
40
- throw new Error('docker not found! Please install it.');
41
- }
42
- throw new Error(ps.error);
43
- } else if (ps.status !== 0) {
44
- //console.error("docker output:", ps.output);
45
- //console.error("docker stdout:", ps.stdout);
46
- //console.error("docker stderr:", ps.stderr)
47
- throw new Error(ps.stderr);
48
- }
49
- return ps;
50
- }
51
-
52
- /**
53
- * Build the custom Docker image by copying our package to the /var/task directory
54
- * in the docker image.
55
- *
56
- * Our base image uses the Lambda Docker Image for the platform:
57
- * https://hub.docker.com/r/lambci/lambda/
58
- */
59
- function buildDockerImage() {
60
- let image = this.provider.naming.getDockerImageName();
61
- this.serverless.cli.log(`Building docker image: "${image}"...`);
62
-
63
- // Get any additional run commands we'd like to include in the docker image
64
- let addtionalBuildCommands = "";
65
- if (this.serverless.service.custom
66
- && this.serverless.service.custom.awsBatch
67
- && this.serverless.service.custom.awsBatch.addtionalBuildCommands) {
68
-
69
- _.forEach(
70
- this.serverless.service.custom.awsBatch.addtionalBuildCommands,
71
- runCommand => {
72
- addtionalBuildCommands += `${runCommand}\n`;
73
- }
74
- )
75
- }
76
-
77
- let additionalCommands = "";
78
- if (this.serverless.service.custom
79
- && this.serverless.service.custom.awsBatch
80
- && this.serverless.service.custom.awsBatch.additionalCommands) {
81
-
82
- _.forEach(
83
- this.serverless.service.custom.awsBatch.additionalCommands,
84
- runCommand => {
85
- additionalCommands += `${runCommand}\n`;
86
- }
87
- )
88
- }
89
-
90
- let buildImage = _.get(this.serverless.service,"custom.awsBatch.buildImage", "368461407828.dkr.ecr.us-east-1.amazonaws.com/build-batch-image-base:latest" );
91
- let batchImage = _.get(this.serverless.service,"custom.awsBatch.batchImage", "368461407828.dkr.ecr.us-east-1.amazonaws.com/batch-image-base:latest" );
92
-
93
- // Override some of the default lambci environmental variables.
94
- // - Function Timeout and Function Memory are set by Env Variables on the Job Definition
95
- // - Access Key and Secret are unset to that we use the role on the container that AWS provides
96
- const dockerFileContents = `
97
- FROM ${buildImage} AS builder
98
- USER root
99
- RUN mkdir -p /tmp/task/
100
- COPY ${this.serverless.service.service}.zip /tmp/task
101
- RUN cd /tmp/task && unzip -q ${this.serverless.service.service}.zip && rm ${this.serverless.service.service}.zip
102
- ${addtionalBuildCommands}
103
-
104
- FROM ${batchImage}
105
- USER root
106
- COPY --from=builder /tmp/task /var/task/
107
- ${additionalCommands}
108
- RUN rm -rf /tmp/*
109
- USER sbx_user1051
110
- `;
111
-
112
- const servicePath = this.serverless.config.servicePath || '';
113
- const packagePath = path.join(servicePath || '.', '.serverless');
114
- const dockerFile = path.join(packagePath, 'Dockerfile');
115
- fse.writeFileSync(dockerFile, dockerFileContents);
116
-
117
- const dockerOptions = ['build', '-f', dockerFile, '-t', image, '.'];
118
- dockerCommand(dockerOptions, packagePath, 'inherit');
119
-
120
- return BbPromise.resolve();
121
- }
122
-
123
- /**
124
- * Uses docker to upload the image to ECR
125
- */
126
- function pushDockerImageToECR() {
127
- // Log docker into our AWS ECR repo so that we can push images to it
128
- this.serverless.cli.log("Logging into ECR...");
129
- const loginCommand = getDockerLoginToECRCommand.bind(this)();
130
- dockerCommand(loginCommand.split(" "));
131
-
132
- // Then perform the upload
133
- this.serverless.cli.log("Uploading to ECR...");
134
- dockerCommand(['push', '--all-tags', this.provider.naming.getECRRepositoryURL()], null, 'inherit');
135
-
136
- return BbPromise.resolve();
137
- }
138
-
139
- module.exports = { getDockerImageName, buildDockerImage, pushDockerImageToECR };
1
+ const BbPromise = require('bluebird');
2
+ const { spawnSync } = require('child_process');
3
+ const _ = require('lodash');
4
+ const fse = require('fs-extra');
5
+ const path = require('path');
6
+ const util = require('util');
7
+ const { getDockerLoginToECRCommand } = require('./awscli');
8
+
9
+ const DOCKER_TAG = `${Date.now()}`;
10
+
11
+ /**
12
+ * @returns {string} "<ECR Repo Name>:latest"
13
+ */
14
+ function getDockerImageName() {
15
+ return `${this.provider.naming.getECRRepositoryURL()}:${DOCKER_TAG}`;
16
+ }
17
+
18
+ /**
19
+ * Helper function to run a docker command
20
+ * @param {string[]} options
21
+ * @param {string} cwd Current working directory
22
+ * @return {Object}
23
+ */
24
+ function dockerCommand(options, cwd = null, stdio = null) {
25
+ const cmd = 'docker';
26
+ var spawnOptions = {
27
+ encoding: 'utf-8'
28
+ }
29
+ if (cwd != null) {
30
+ spawnOptions.cwd = cwd;
31
+ }
32
+ if (stdio != null) {
33
+ spawnOptions.stdio = stdio;
34
+ }
35
+
36
+ //console.error("dockerCommand:", options, spawnOptions);
37
+ const ps = spawnSync(cmd, options, spawnOptions);
38
+ if (ps.error) {
39
+ if (ps.error.code === 'ENOENT') {
40
+ throw new Error('docker not found! Please install it.');
41
+ }
42
+ throw new Error(ps.error);
43
+ } else if (ps.status !== 0) {
44
+ //console.error("docker output:", ps.output);
45
+ //console.error("docker stdout:", ps.stdout);
46
+ //console.error("docker stderr:", ps.stderr)
47
+ throw new Error(ps.stderr);
48
+ }
49
+ return ps;
50
+ }
51
+
52
+ /**
53
+ * Build the custom Docker image by copying our package to the /var/task directory
54
+ * in the docker image.
55
+ *
56
+ * Our base image uses the Lambda Docker Image for the platform:
57
+ * https://hub.docker.com/r/lambci/lambda/
58
+ */
59
+ function buildDockerImage() {
60
+ let image = this.provider.naming.getDockerImageName();
61
+ this.serverless.cli.log(`Building docker image: "${image}"...`);
62
+
63
+ // Get any additional run commands we'd like to include in the docker image
64
+ let addtionalBuildCommands = "";
65
+ if (this.serverless.service.custom
66
+ && this.serverless.service.custom.awsBatch
67
+ && this.serverless.service.custom.awsBatch.addtionalBuildCommands) {
68
+
69
+ _.forEach(
70
+ this.serverless.service.custom.awsBatch.addtionalBuildCommands,
71
+ runCommand => {
72
+ addtionalBuildCommands += `${runCommand}\n`;
73
+ }
74
+ )
75
+ }
76
+
77
+ let additionalCommands = "";
78
+ if (this.serverless.service.custom
79
+ && this.serverless.service.custom.awsBatch
80
+ && this.serverless.service.custom.awsBatch.additionalCommands) {
81
+
82
+ _.forEach(
83
+ this.serverless.service.custom.awsBatch.additionalCommands,
84
+ runCommand => {
85
+ additionalCommands += `${runCommand}\n`;
86
+ }
87
+ )
88
+ }
89
+
90
+ let buildImage = _.get(this.serverless.service,"custom.awsBatch.buildImage", "368461407828.dkr.ecr.us-east-1.amazonaws.com/build-batch-image-base:latest" );
91
+ let batchImage = _.get(this.serverless.service,"custom.awsBatch.batchImage", "368461407828.dkr.ecr.us-east-1.amazonaws.com/batch-image-base:latest" );
92
+
93
+ // Override some of the default lambci environmental variables.
94
+ // - Function Timeout and Function Memory are set by Env Variables on the Job Definition
95
+ // - Access Key and Secret are unset to that we use the role on the container that AWS provides
96
+ const dockerFileContents = `
97
+ FROM ${buildImage} AS builder
98
+ USER root
99
+ RUN mkdir -p /tmp/task/
100
+ COPY ${this.serverless.service.service}.zip /tmp/task
101
+ RUN cd /tmp/task && unzip -q ${this.serverless.service.service}.zip && rm ${this.serverless.service.service}.zip
102
+ ${addtionalBuildCommands}
103
+
104
+ FROM ${batchImage}
105
+ USER root
106
+ COPY --from=builder /tmp/task /var/task/
107
+ ${additionalCommands}
108
+ RUN rm -rf /tmp/*
109
+ USER sbx_user1051
110
+ `;
111
+
112
+ const servicePath = this.serverless.config.servicePath || '';
113
+ const packagePath = path.join(servicePath || '.', '.serverless');
114
+ const dockerFile = path.join(packagePath, 'Dockerfile');
115
+ fse.writeFileSync(dockerFile, dockerFileContents);
116
+
117
+ const dockerOptions = ['build', '-f', dockerFile, '-t', image, '.'];
118
+ dockerCommand(dockerOptions, packagePath, 'inherit');
119
+
120
+ return BbPromise.resolve();
121
+ }
122
+
123
+ /**
124
+ * Uses docker to upload the image to ECR
125
+ */
126
+ function pushDockerImageToECR() {
127
+ // Log docker into our AWS ECR repo so that we can push images to it
128
+ this.serverless.cli.log("Logging into ECR...");
129
+ const loginCommand = getDockerLoginToECRCommand.bind(this)();
130
+ dockerCommand(loginCommand.split(" "));
131
+
132
+ // Then perform the upload
133
+ this.serverless.cli.log("Uploading to ECR...");
134
+ dockerCommand(['push', '--all-tags', this.provider.naming.getECRRepositoryURL()], null, 'inherit');
135
+
136
+ return BbPromise.resolve();
137
+ }
138
+
139
+ module.exports = { getDockerImageName, buildDockerImage, pushDockerImageToECR };
package/lib/ecr.js CHANGED
@@ -1,30 +1,30 @@
1
- const { getAWSAccountID } = require('./awscli');
2
-
3
- /**
4
- * @returns {string} "ECRRepository"
5
- */
6
- function getECRLogicalId() {
7
- return "ECRRepository";
8
- }
9
-
10
- /**
11
- * @returns {string} "<serviceName>-<stage>"
12
- */
13
- function getECRRepositoryName() {
14
- return `${this.provider.serverless.service.service}-${this.provider.getStage()}`;
15
- }
16
-
17
-
18
- /**
19
- * @type {string} "<awsAccountID>.dkr.ecr.us-east-1.amazonaws.com/<serviceName>-<stage>:<tag>"
20
- */
21
-
22
- function getECRRepositoryURL() {
23
- return `${getAWSAccountID()}.dkr.ecr.${this.provider.getRegion()}.amazonaws.com/${this.provider.naming.getECRRepositoryName()}`
24
- }
25
-
26
- module.exports = {
27
- getECRLogicalId,
28
- getECRRepositoryName,
29
- getECRRepositoryURL
1
+ const { getAWSAccountID } = require('./awscli');
2
+
3
+ /**
4
+ * @returns {string} "ECRRepository"
5
+ */
6
+ function getECRLogicalId() {
7
+ return "ECRRepository";
8
+ }
9
+
10
+ /**
11
+ * @returns {string} "<serviceName>-<stage>"
12
+ */
13
+ function getECRRepositoryName() {
14
+ return `${this.provider.serverless.service.service}-${this.provider.getStage()}`;
15
+ }
16
+
17
+
18
+ /**
19
+ * @type {string} "<awsAccountID>.dkr.ecr.us-east-1.amazonaws.com/<serviceName>-<stage>:<tag>"
20
+ */
21
+
22
+ function getECRRepositoryURL() {
23
+ return `${getAWSAccountID()}.dkr.ecr.${this.provider.getRegion()}.amazonaws.com/${this.provider.naming.getECRRepositoryName()}`
24
+ }
25
+
26
+ module.exports = {
27
+ getECRLogicalId,
28
+ getECRRepositoryName,
29
+ getECRRepositoryURL
30
30
  }
@@ -1,121 +1,121 @@
1
- // Handles setting up our ECR repository so that we can push our docker image to it
2
-
3
- 'use strict';
4
-
5
- const BbPromise = require('bluebird');
6
- const path = require('path');
7
- const _ = require('lodash');
8
- var util = require('util');
9
-
10
- const lifeCyclePolicies = {
11
- "rules": [
12
- {
13
- "rulePriority": 1,
14
- "description": "Remove images over 90 days old",
15
- "selection": {
16
- "tagStatus": "any",
17
- "countType": "sinceImagePushed",
18
- "countUnit": "days",
19
- "countNumber": 90
20
- },
21
- "action": {
22
- "type": "expire"
23
- }
24
- }
25
- ]
26
- };
27
-
28
- /**
29
- * Adds the ECR repository to the "create" template so that we have a repository we can upload our docker image to
30
- * during deployment.
31
- */
32
- function generateCoreTemplate() {
33
- // Setup our ECR Repository to delete untagged images after 1 day
34
- // const ecrTemplate = `
35
- // {
36
- // "Type" : "AWS::ECR::Repository",
37
- // "Properties" : {
38
- // "LifecyclePolicy" : {
39
- // "LifecyclePolicyText" : ${JSON.stringify(JSON.stringify(lifeCyclePolicies))}
40
- // },
41
- // "RepositoryName" : "${this.provider.naming.getECRRepositoryName()}"
42
- // }
43
- // }
44
- // `;
45
- const ecrTemplate = `
46
- {
47
- "Type" : "AWS::ECR::Repository",
48
- "Properties" : {
49
- "RepositoryName" : "${this.provider.naming.getECRRepositoryName()}"
50
- }
51
- }
52
- `;
53
-
54
- const newECRObject = {
55
- [this.provider.naming.getECRLogicalId()]: JSON.parse(ecrTemplate)
56
- };
57
-
58
- // Add it to our initial compiled cloud formation templates
59
- _.merge(
60
- this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
61
- newECRObject
62
- );
63
-
64
- // Look for the serverless-log-forwarding custom parameters, if found, then forward the logs
65
- // from our batch jobs to the same ARN...
66
- const logGroupName = _.get(this.serverless.service,"custom.awsBatch.logGroupName");
67
- const logDestinationArn = _.get(this.serverless.service,"custom.logForwarding.destinationARN" );
68
- if ( logDestinationArn && logGroupName ) {
69
- const batchLogGroupTemplate = {
70
- "BatchLogGroupLambdaPermission": {
71
- "Type": "AWS::Lambda::Permission",
72
- "Properties": {
73
- "FunctionName": logDestinationArn,
74
- "Action": "lambda:InvokeFunction",
75
- "Principal": "logs.us-east-1.amazonaws.com"
76
- }
77
- },
78
- "BatchLogGroup": {
79
- "Type": "AWS::Logs::LogGroup",
80
- "Properties": {
81
- "LogGroupName": logGroupName,
82
- "RetentionInDays": 7
83
- }
84
- },
85
- "BatchLogGroupSubscriptionFilter": {
86
- "Type": "AWS::Logs::SubscriptionFilter",
87
- "Properties": {
88
- "DestinationArn": logDestinationArn,
89
- "FilterPattern": "",
90
- "LogGroupName": logGroupName
91
- },
92
- "DependsOn": [
93
- "BatchLogGroupLambdaPermission",
94
- "BatchLogGroup"
95
- ]
96
- }
97
- }
98
-
99
- _.merge(
100
- this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
101
- batchLogGroupTemplate
102
- );
103
- }
104
-
105
- // Then write it back out to the file
106
- const coreTemplateFileName = this.provider.naming.getCoreTemplateFileName();
107
-
108
- const coreTemplateFilePath = path.join(this.serverless.config.servicePath,
109
- '.serverless',
110
- coreTemplateFileName);
111
-
112
- this.serverless.utils.writeFileSync(coreTemplateFilePath,
113
- this.serverless.service.provider.compiledCloudFormationTemplate);
114
-
115
- this.serverless.service.provider.coreCloudFormationTemplate =
116
- _.cloneDeep(this.serverless.service.provider.compiledCloudFormationTemplate);
117
-
118
- return BbPromise.resolve();
119
- }
120
-
1
+ // Handles setting up our ECR repository so that we can push our docker image to it
2
+
3
+ 'use strict';
4
+
5
+ const BbPromise = require('bluebird');
6
+ const path = require('path');
7
+ const _ = require('lodash');
8
+ var util = require('util');
9
+
10
+ const lifeCyclePolicies = {
11
+ "rules": [
12
+ {
13
+ "rulePriority": 1,
14
+ "description": "Remove images over 90 days old",
15
+ "selection": {
16
+ "tagStatus": "any",
17
+ "countType": "sinceImagePushed",
18
+ "countUnit": "days",
19
+ "countNumber": 90
20
+ },
21
+ "action": {
22
+ "type": "expire"
23
+ }
24
+ }
25
+ ]
26
+ };
27
+
28
+ /**
29
+ * Adds the ECR repository to the "create" template so that we have a repository we can upload our docker image to
30
+ * during deployment.
31
+ */
32
+ function generateCoreTemplate() {
33
+ // Setup our ECR Repository to delete untagged images after 1 day
34
+ // const ecrTemplate = `
35
+ // {
36
+ // "Type" : "AWS::ECR::Repository",
37
+ // "Properties" : {
38
+ // "LifecyclePolicy" : {
39
+ // "LifecyclePolicyText" : ${JSON.stringify(JSON.stringify(lifeCyclePolicies))}
40
+ // },
41
+ // "RepositoryName" : "${this.provider.naming.getECRRepositoryName()}"
42
+ // }
43
+ // }
44
+ // `;
45
+ const ecrTemplate = `
46
+ {
47
+ "Type" : "AWS::ECR::Repository",
48
+ "Properties" : {
49
+ "RepositoryName" : "${this.provider.naming.getECRRepositoryName()}"
50
+ }
51
+ }
52
+ `;
53
+
54
+ const newECRObject = {
55
+ [this.provider.naming.getECRLogicalId()]: JSON.parse(ecrTemplate)
56
+ };
57
+
58
+ // Add it to our initial compiled cloud formation templates
59
+ _.merge(
60
+ this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
61
+ newECRObject
62
+ );
63
+
64
+ // Look for the serverless-log-forwarding custom parameters, if found, then forward the logs
65
+ // from our batch jobs to the same ARN...
66
+ const logGroupName = _.get(this.serverless.service,"custom.awsBatch.logGroupName");
67
+ const logDestinationArn = _.get(this.serverless.service,"custom.logForwarding.destinationARN" );
68
+ if ( logDestinationArn && logGroupName ) {
69
+ const batchLogGroupTemplate = {
70
+ "BatchLogGroupLambdaPermission": {
71
+ "Type": "AWS::Lambda::Permission",
72
+ "Properties": {
73
+ "FunctionName": logDestinationArn,
74
+ "Action": "lambda:InvokeFunction",
75
+ "Principal": "logs.us-east-1.amazonaws.com"
76
+ }
77
+ },
78
+ "BatchLogGroup": {
79
+ "Type": "AWS::Logs::LogGroup",
80
+ "Properties": {
81
+ "LogGroupName": logGroupName,
82
+ "RetentionInDays": 7
83
+ }
84
+ },
85
+ "BatchLogGroupSubscriptionFilter": {
86
+ "Type": "AWS::Logs::SubscriptionFilter",
87
+ "Properties": {
88
+ "DestinationArn": logDestinationArn,
89
+ "FilterPattern": "",
90
+ "LogGroupName": logGroupName
91
+ },
92
+ "DependsOn": [
93
+ "BatchLogGroupLambdaPermission",
94
+ "BatchLogGroup"
95
+ ]
96
+ }
97
+ }
98
+
99
+ _.merge(
100
+ this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
101
+ batchLogGroupTemplate
102
+ );
103
+ }
104
+
105
+ // Then write it back out to the file
106
+ const coreTemplateFileName = this.provider.naming.getCoreTemplateFileName();
107
+
108
+ const coreTemplateFilePath = path.join(this.serverless.config.servicePath,
109
+ '.serverless',
110
+ coreTemplateFileName);
111
+
112
+ this.serverless.utils.writeFileSync(coreTemplateFilePath,
113
+ this.serverless.service.provider.compiledCloudFormationTemplate);
114
+
115
+ this.serverless.service.provider.coreCloudFormationTemplate =
116
+ _.cloneDeep(this.serverless.service.provider.compiledCloudFormationTemplate);
117
+
118
+ return BbPromise.resolve();
119
+ }
120
+
121
121
  module.exports = { generateCoreTemplate };