Skip to content

Commit 440e444

Browse files
committed
First version
1 parent fd83095 commit 440e444

File tree

7 files changed

+202
-2
lines changed

7 files changed

+202
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

index.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const util = require('util');
4+
const exec = util.promisify(require('child_process').exec);
5+
const axios = require('axios');
6+
const version = require('utils/version_cleaner')(process.args[process.args.length - 1]);
7+
const downloadURL = `https://nodejs.org/dist/v${version}/node-v${version}-linux-x64.tar.xz`;
8+
9+
async function main() {
10+
let runtimeFileNumber;
11+
while (fs.existsSync(path.join(`node_runtime${runtimeFileNumber ? `_${runtimeFileNumber}` : ""}.js`))) {
12+
if (runtimeFileNumber) {
13+
runtimeFileNumber++;
14+
} else {
15+
runtimeFileNumber = 0;
16+
}
17+
}
18+
const nodeRunnerFile = `node_runtime${runtimeFileNumber ? `_${runtimeFileNumber}` : ""}.js`;
19+
fs.copyFileSync(path.join(__dirname, 'templates', 'node_runtime.js'), path.join(nodeRunnerFile));
20+
fs.copyFileSync(path.join(__dirname, 'templates', 'bootstrap'), path.join(`bootstrap`));
21+
22+
let bootstrap = fs.readFileSync(path.join(`bootstrap`), 'utf8').replace(/{{NODE_VERSION}}/g, version).replace(/{{NODE_VERSION}}/g, version).replace(/{{NODE_RUNNER_FILE}}/g, nodeRunnerFile);
23+
fs.writeFileSync(path.join(`bootstrap`), bootstrap);
24+
25+
// Download Node.js
26+
try {
27+
await downloadFile(downloadURL, path.join(`node-v${version}-linux-x64.tar.xz`));
28+
await unzip(path.join(`node-v${version}-linux-x64.tar.xz`));
29+
fs.unlinkSync(path.join(`node-v${version}-linux-x64.tar.xz`));
30+
} catch (e) {
31+
console.error(e);
32+
}
33+
}
34+
main();
35+
36+
37+
async function downloadFile(url, path) {
38+
const response = await axios({
39+
method: 'GET',
40+
url,
41+
responseType: 'stream'
42+
});
43+
44+
response.data.pipe(fs.createWriteStream(path));
45+
46+
return new Promise((resolve, reject) => {
47+
response.data.on('end', () => {
48+
resolve();
49+
});
50+
51+
response.data.on('error', () => {
52+
reject();
53+
});
54+
});
55+
}
56+
57+
async function unzip(file) {
58+
const { stdout, stderr } = await exec(`tar -xJf ${file}`);
59+
}

package-lock.json

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
{
22
"name": "aws-lambda-custom-node-runtime",
3-
"version": "1.0.0",
3+
"version": "0.0.1",
44
"description": "",
55
"main": "index.js",
66
"scripts": {
77
"test": "echo \"Error: no test specified\" && exit 1"
88
},
99
"keywords": [],
1010
"author": "rrainn, Inc.",
11-
"license": "MIT"
11+
"license": "MIT",
12+
"dependencies": {
13+
"axios": "^0.18.0"
14+
}
1215
}

templates/bootstrap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
cd $LAMBDA_TASK_ROOT
3+
./node-v{{NODE_VERSION}}-linux-x64/bin/node {{NODE_RUNNER_FILE}}

templates/node_runtime.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
var http = require('http');
2+
var Buffer = require('buffer').Buffer;
3+
4+
function run() {
5+
request({
6+
url: process.env.AWS_LAMBDA_RUNTIME_API + '/2018-06-01/runtime/invocation/next',
7+
}, function(err, invoke_result) {
8+
if (err) {
9+
return request({
10+
url: process.env.AWS_LAMBDA_RUNTIME_API + '/2018-06-01/runtime/init/error',
11+
method: 'POST',
12+
data: err
13+
}, run);
14+
}
15+
var event_data = invoke_result.data;
16+
var request_id = invoke_result.resp.headers['lambda-runtime-aws-request-id'];
17+
18+
var response = require(process.env.LAMBDA_TASK_ROOT + '/' + process.env._HANDLER.split('.')[0] + '.js')[process.env._HANDLER.split('.')[1]](JSON.parse(event_data), {}, function (err, result) {
19+
if (err) {
20+
failure(err);
21+
} else {
22+
success(result);
23+
}
24+
});
25+
if (response && response.then && typeof response.then === 'function') {
26+
response.then(success);
27+
}
28+
if (response && response.catch && typeof response.catch === 'function') {
29+
response.catch(failure);
30+
}
31+
32+
function success(result) {
33+
request({
34+
url: process.env.AWS_LAMBDA_RUNTIME_API + '/2018-06-01/runtime/invocation/' + request_id + '/response',
35+
method: 'POST',
36+
data: result
37+
}, run);
38+
}
39+
function failure(err) {
40+
request({
41+
url: process.env.AWS_LAMBDA_RUNTIME_API + '/2018-06-01/runtime/invocation/' + request_id + '/error',
42+
method: 'POST',
43+
data: err
44+
}, run);
45+
}
46+
});
47+
}
48+
run();
49+
50+
function request(options, cb) {
51+
if (!cb) {
52+
cb = function(){};
53+
}
54+
if (options.data && typeof options.data === 'object') {
55+
options.data = JSON.stringify(options.data);
56+
}
57+
if (options.data && !options.headers) {
58+
options.headers = {};
59+
}
60+
if (options.data && !options.headers['Content-Length']) {
61+
options.headers['Content-Length'] = Buffer.byteLength(options.data);
62+
}
63+
if (options.data && !options.headers['Content-Type']) {
64+
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
65+
}
66+
options.timeout = 1000;
67+
var req = http.request('http://' + options.url, options, function(resp) {
68+
var data = '';
69+
resp.on('data', function(chunk) {
70+
data += chunk;
71+
});
72+
resp.on('end', function() {
73+
cb(null, {data: data, resp: resp});
74+
});
75+
}).on('error', function(err) {
76+
cb(err);
77+
});
78+
79+
if (options.data) {
80+
req.write(options.data);
81+
}
82+
req.end();
83+
}

utils/version_cleaner.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = version => {
2+
version = version.replace(/^v/g, "");
3+
let versionArray = version.split(".");
4+
while (versionArray.length < 3) {
5+
versionArray.push("0");
6+
}
7+
return versionArray.join(".");
8+
};

0 commit comments

Comments
 (0)