UNPKG

16.5 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.npmInstall = void 0;
4const archiver = require("archiver");
5const aws_sdk_1 = require("aws-sdk");
6const child_process_1 = require("child_process");
7const fs_extra_1 = require("fs-extra");
8const os_1 = require("os");
9const path = require("path");
10const util_1 = require("util");
11const shared_1 = require("../shared");
12async function exec(cmds) {
13 let rv = "";
14 for (const cmd of cmds) {
15 rv += (0, child_process_1.execSync)(cmd).toString();
16 }
17 return rv;
18}
19async function npmInstall({ LayerName, packageJsonContents, FunctionName, region, quiet, retentionInDays }) {
20 const log = quiet ? (_) => { } : console.log;
21 log(`*** This faast invocation is an internal lambda call used when the packageJson option is specified to createFunction(). ***`);
22 log(`*** Its purpose is to create a node_modules package and cache it, then combine with user code to form an AWS Lambda code package and upload it to S3 ***`);
23 const buildParentDir = path.join((0, os_1.tmpdir)(), FunctionName);
24 const buildDir = path.join(buildParentDir, "nodejs");
25 await (0, fs_extra_1.ensureDir)(buildDir);
26 await (0, fs_extra_1.writeFile)(path.join(buildDir, "package.json"), packageJsonContents);
27 const awsconfig = { correctClockSkew: true, maxRetries: 6 };
28 let installLog = "";
29 log("Checking cache");
30 log(`Checking faast layers for ${LayerName}`);
31 const lambda = new aws_sdk_1.Lambda({ apiVersion: "2015-03-31", region, ...awsconfig });
32 const cached = await lambda
33 .listLayerVersions({ LayerName, CompatibleRuntime: "nodejs" })
34 .promise()
35 .catch(_ => undefined);
36 const layerVersion = cached?.LayerVersions?.[0];
37 if (layerVersion && !(0, shared_1.hasExpired)(layerVersion.CreatedDate, retentionInDays)) {
38 const layerInfo = {
39 LayerName,
40 Version: layerVersion.Version,
41 LayerVersionArn: layerVersion.LayerVersionArn
42 };
43 log(`CACHED, ${(0, util_1.inspect)(layerInfo)}`);
44 return { installLog, layerInfo };
45 }
46 log("NOT CACHED, running npm install");
47 installLog += await exec([`echo "hello world"`]);
48 installLog += await exec([
49 `export HOME=/tmp; npm install --prefix=${buildDir} --no-package-lock`
50 ]);
51 log(`Running archiver`);
52 const cacheArchive = archiver("zip", { zlib: { level: 8 } });
53 cacheArchive.directory(buildParentDir, false).finalize();
54 log(`Converting archive to buffer`);
55 const ZipFile = await (0, shared_1.streamToBuffer)(cacheArchive);
56 log(`Code ZipFile size: ${ZipFile.length}`);
57 log(`Removing ${buildParentDir}`);
58 const removePromise = (0, fs_extra_1.remove)(buildParentDir);
59 let Content;
60 const Bucket = FunctionName;
61 const s3 = new aws_sdk_1.S3({ region, ...awsconfig });
62 const zipSize = ZipFile.length;
63 try {
64 if (ZipFile.length > 50 * 2 ** 20) {
65 // Try to use S3 to allow for a larger limit
66 log(`Creating s3 bucket ${Bucket}`);
67 await s3
68 .createBucket({ Bucket })
69 .promise()
70 .catch(_ => { });
71 log(`Uploading bucket: ${Bucket}, object: ${LayerName}`);
72 await s3.upload({ Bucket, Key: LayerName, Body: ZipFile }).promise();
73 Content = { S3Bucket: Bucket, S3Key: LayerName };
74 }
75 else {
76 Content = { ZipFile };
77 }
78 log(`Creating lambda layer: ${LayerName}, zip file size: ${ZipFile.length}`);
79 const publishResponse = await lambda
80 .publishLayerVersion({
81 LayerName,
82 Description: `faast packageJson layer with LayerName ${LayerName}`,
83 Content,
84 CompatibleRuntimes: ["nodejs"]
85 })
86 .promise();
87 const { Version } = publishResponse;
88 log(`Created lambda layer: ${LayerName}:${Version}`);
89 log(`DONE`);
90 return {
91 installLog,
92 layerInfo: {
93 LayerName,
94 LayerVersionArn: publishResponse.LayerVersionArn,
95 Version: publishResponse.Version
96 },
97 zipSize
98 };
99 }
100 finally {
101 if (Content?.S3Bucket) {
102 try {
103 await s3.deleteObject({ Bucket, Key: LayerName }).promise();
104 await s3.deleteBucket({ Bucket }).promise();
105 }
106 catch { }
107 }
108 await removePromise;
109 }
110}
111exports.npmInstall = npmInstall;
112//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLW5wbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hd3MvYXdzLW5wbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxQ0FBcUM7QUFDckMscUNBQXFDO0FBQ3JDLGlEQUF5QztBQUN6Qyx1Q0FBd0Q7QUFDeEQsMkJBQTRCO0FBQzVCLDZCQUE2QjtBQUM3QiwrQkFBK0I7QUFDL0Isc0NBQXVEO0FBRXZELEtBQUssVUFBVSxJQUFJLENBQUMsSUFBYztJQUM5QixJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDWixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRTtRQUNwQixFQUFFLElBQUksSUFBQSx3QkFBUSxFQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0tBQ2xDO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDZCxDQUFDO0FBdUJNLEtBQUssVUFBVSxVQUFVLENBQUMsRUFDN0IsU0FBUyxFQUNULG1CQUFtQixFQUNuQixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFDTCxlQUFlLEVBQ0Y7SUFDYixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsR0FBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7SUFFcEQsR0FBRyxDQUNDLDZIQUE2SCxDQUNoSSxDQUFDO0lBQ0YsR0FBRyxDQUNDLDBKQUEwSixDQUM3SixDQUFDO0lBRUYsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFBLFdBQU0sR0FBRSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3pELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3JELE1BQU0sSUFBQSxvQkFBUyxFQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzFCLE1BQU0sSUFBQSxvQkFBUyxFQUFDLElBQUksQ0FB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RUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzVELE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDL0M7WUFBQyxNQUFNLEdBQUU7U0FDYjtRQUNELE1BQU0sYUFBYSxDQUFDO0tBQ3ZCO0FBQ0wsQ0FBQztBQTFHRCxnQ0EwR0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhcmNoaXZlciBmcm9tIFwiYXJjaGl2ZXJcIjtcbmltcG9ydCB7IExhbWJkYSwgUzMgfSBmcm9tIFwiYXdzLXNka1wiO1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgZW5zdXJlRGlyLCByZW1vdmUsIHdyaXRlRmlsZSB9IGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSBcIm9zXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSBcInV0aWxcIjtcbmltcG9ydCB7IHN0cmVhbVRvQnVmZmVyLCBoYXNFeHBpcmVkIH0gZnJvbSBcIi4uL3NoYXJlZFwiO1xuXG5hc3luYyBmdW5jdGlvbiBleGVjKGNtZHM6IHN0cmluZ1tdKSB7XG4gICAgbGV0IHJ2ID0gXCJcIjtcbiAgICBmb3IgKGNvbnN0IGNtZCBvZiBjbWRzKSB7XG4gICAgICAgIHJ2ICs9IGV4ZWNTeW5jKGNtZCkudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgcmV0dXJuIHJ2O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5wbUluc3RhbGxBcmdzIHtcbiAgICBwYWNrYWdlSnNvbkNvbnRlbnRzOiBzdHJpbmc7XG4gICAgTGF5ZXJOYW1lOiBzdHJpbmc7XG4gICAgRnVuY3Rpb25OYW1lOiBzdHJpbmc7XG4gICAgcmVnaW9uOiBzdHJpbmc7XG4gICAgcXVpZXQ/OiBib29sZWFuO1xuICAgIHJldGVudGlvbkluRGF5czogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF3c0xheWVySW5mbyB7XG4gICAgVmVyc2lvbjogbnVtYmVyO1xuICAgIExheWVyVmVyc2lvbkFybjogc3RyaW5nO1xuICAgIExheWVyTmFtZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5wbUluc3RhbGxSZXR1cm4ge1xuICAgIGluc3RhbGxMb2c6IHN0cmluZztcbiAgICBsYXllckluZm86IEF3c0xheWVySW5mbztcbiAgICB6aXBTaXplPzogbnVtYmVyO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbnBtSW5zdGFsbCh7XG4gICAgTGF5ZXJOYW1lLFxuICAgIHBhY2thZ2VKc29uQ29udGVudHMsXG4gICAgRnVuY3Rpb25OYW1lLFxuICAgIHJlZ2lvbixcbiAgICBxdWlldCxcbiAgICByZXRlbnRpb25JbkRheXNcbn06IE5wbUluc3RhbGxBcmdzKTogUHJvbWlzZTxOcG1JbnN0YWxsUmV0dXJuPiB7XG4gICAgY29uc3QgbG9nID0gcXVpZXQgPyAoXzogc3RyaW5nKSA9PiB7fSA6IGNvbnNvbGUubG9nO1xuXG4gICAgbG9nKFxuICAgICAgICBgKioqIFRoaXMgZmFhc3QgaW52b2NhdGlvbiBpcyBhbiBpbnRlcm5hbCBsYW1iZGEgY2FsbCB1c2VkIHdoZW4gdGhlIHBhY2thZ2VKc29uIG9wdGlvbiBpcyBzcGVjaWZpZWQgdG8gY3JlYXRlRnVuY3Rpb24oKS4gKioqYFxuICAgICk7XG4gICAgbG9nKFxuICAgICAgICBgKioqIEl0cyBwdXJwb3NlIGlzIHRvIGNyZWF0ZSBhIG5vZGVfbW9kdWxlcyBwYWNrYWdlIGFuZCBjYWNoZSBpdCwgdGhlbiBjb21iaW5lIHdpdGggdXNlciBjb2RlIHRvIGZvcm0gYW4gQVdTIExhbWJkYSBjb2RlIHBhY2thZ2UgYW5kIHVwbG9hZCBpdCB0byBTMyAqKipgXG4gICAgKTtcblxuICAgIGNvbnN0IGJ1aWxkUGFyZW50RGlyID0gcGF0aC5qb2luKHRtcGRpcigpLCBGdW5jdGlvbk5hbWUpO1xuICAgIGNvbnN0IGJ1aWxkRGlyID0gcGF0aC5qb2luKGJ1aWxkUGFyZW50RGlyLCBcIm5vZGVqc1wiKTtcbiAgICBhd2FpdCBlbnN1cmVEaXIoYnVpbGREaXIpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShwYXRoLmpvaW4oYnVpbGREaXIsIFwicGFja2FnZS5qc29uXCIpLCBwYWNrYWdlSnNvbkNvbnRlbnRzKTtcblxuICAgIGNvbnN0IGF3c2NvbmZpZyA9IHsgY29ycmVjdENsb2NrU2tldzogdHJ1ZSwgbWF4UmV0cmllczogNiB9O1xuXG4gICAgbGV0IGluc3RhbGxMb2cgPSBcIlwiO1xuICAgIGxvZyhcIkNoZWNraW5nIGNhY2hlXCIpO1xuICAgIGxvZyhgQ2hlY2tpbmcgZmFhc3QgbGF5ZXJzIGZvciAke0xheWVyTmFtZX1gKTtcbiAgICBjb25zdCBsYW1iZGEgPSBuZXcgTGFtYmRhKHsgYXBpVmVyc2lvbjogXCIyMDE1LTAzLTMxXCIsIHJlZ2lvbiwgLi4uYXdzY29uZmlnIH0pO1xuXG4gICAgY29uc3QgY2FjaGVkID0gYXdhaXQgbGFtYmRhXG4gICAgICAgIC5saXN0TGF5ZXJWZXJzaW9ucyh7IExheWVyTmFtZSwgQ29tcGF0aWJsZVJ1bnRpbWU6IFwibm9kZWpzXCIgfSlcbiAgICAgICAgLnByb21pc2UoKVxuICAgICAgICAuY2F0Y2goXyA9PiB1bmRlZmluZWQpO1xuXG4gICAgY29uc3QgbGF5ZXJWZXJzaW9uID0gY2FjaGVkPy5MYXllclZlcnNpb25zPy5bMF07XG4gICAgaWYgKGxheWVyVmVyc2lvbiAmJiAhaGFzRXhwaXJlZChsYXllclZlcnNpb24uQ3JlYXRlZERhdGUsIHJldGVudGlvbkluRGF5cykpIHtcbiAgICAgICAgY29uc3QgbGF5ZXJJbmZvID0ge1xuICAgICAgICAgICAgTGF5ZXJOYW1lLFxuICAgICAgICAgICAgVmVyc2lvbjogbGF5ZXJWZXJzaW9uLlZlcnNpb24hLFxuICAgICAgICAgICAgTGF5ZXJWZXJzaW9uQXJuOiBsYXllclZlcnNpb24uTGF5ZXJWZXJzaW9uQXJuIVxuICAgICAgICB9O1xuICAgICAgICBsb2coYENBQ0hFRCwgJHtpbnNwZWN0KGxheWVySW5mbyl9YCk7XG4gICAgICAgIHJldHVybiB7IGluc3RhbGxMb2csIGxheWVySW5mbyB9O1xuICAgIH1cblxuICAgIGxvZyhcIk5PVCBDQUNIRUQsIHJ1bm5pbmcgbnBtIGluc3RhbGxcIik7XG4gICAgaW5zdGFsbExvZyArPSBhd2FpdCBleGVjKFtgZWNobyBcImhlbGxvIHdvcmxkXCJgXSk7XG4gICAgaW5zdGFsbExvZyArPSBhd2FpdCBleGVjKFtcbiAgICAgICAgYGV4cG9ydCBIT01FPS90bXA7IG5wbSBpbnN0YWxsIC0tcHJlZml4PSR7YnVpbGREaXJ9IC0tbm8tcGFja2FnZS1sb2NrYFxuICAgIF0pO1xuICAgIGxvZyhgUnVubmluZyBhcmNoaXZlcmApO1xuICAgIGNvbnN0IGNhY2hlQXJjaGl2ZSA9IGFyY2hpdmVyKFwiemlwXCIsIHsgemxpYjogeyBsZXZlbDogOCB9IH0pO1xuICAgIGNhY2hlQXJjaGl2ZS5kaXJlY3RvcnkoYnVpbGRQYXJlbnREaXIsIGZhbHNlKS5maW5hbGl6ZSgpO1xuICAgIGxvZyhgQ29udmVydGluZyBhcmNoaXZlIHRvIGJ1ZmZlcmApO1xuICAgIGNvbnN0IFppcEZpbGUgPSBhd2FpdCBzdHJlYW1Ub0J1ZmZlcihjYWNoZUFyY2hpdmUpO1xuICAgIGxvZyhgQ29kZSBaaXBGaWxlIHNpemU6ICR7WmlwRmlsZS5sZW5ndGh9YCk7XG4gICAgbG9nKGBSZW1vdmluZyAke2J1aWxkUGFyZW50RGlyfWApO1xuICAgIGNvbnN0IHJlbW92ZVByb21pc2UgPSByZW1vdmUoYnVpbGRQYXJlbnREaXIpO1xuICAgIGxldCBDb250ZW50OiBMYW1iZGEuTGF5ZXJWZXJzaW9uQ29udGVudElucHV0IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IEJ1Y2tldCA9IEZ1bmN0aW9uTmFtZTtcbiAgICBjb25zdCBzMyA9IG5ldyBTMyh7IHJlZ2lvbiwgLi4uYXdzY29uZmlnIH0pO1xuICAgIGNvbnN0IHppcFNpemUgPSBaaXBGaWxlLmxlbmd0aDtcbiAgICB0cnkge1xuICAgICAgICBpZiAoWmlwRmlsZS5sZW5ndGggPiA1MCAqIDIgKiogMjApIHtcbiAgICAgICAgICAgIC8vIFRyeSB0byB1c2UgUzMgdG8gYWxsb3cgZm9yIGEgbGFyZ2VyIGxpbWl0XG4gICAgICAgICAgICBsb2coYENyZWF0aW5nIHMzIGJ1Y2tldCAke0J1Y2tldH1gKTtcbiAgICAgICAgICAgIGF3YWl0IHMzXG4gICAgICAgICAgICAgICAgLmNyZWF0ZUJ1Y2tldCh7IEJ1Y2tldCB9KVxuICAgICAgICAgICAgICAgIC5wcm9taXNlKClcbiAgICAgICAgICAgICAgICAuY2F0Y2goXyA9PiB7fSk7XG4gICAgICAgICAgICBsb2coYFVwbG9hZGluZyBidWNrZXQ6ICR7QnVja2V0fSwgb2JqZWN0OiAke0xheWVyTmFtZX1gKTtcbiAgICAgICAgICAgIGF3YWl0IHMzLnVwbG9hZCh7IEJ1Y2tldCwgS2V5OiBMYXllck5hbWUsIEJvZHk6IFppcEZpbGUgfSkucHJvbWlzZSgpO1xuICAgICAgICAgICAgQ29udGVudCA9IHsgUzNCdWNrZXQ6IEJ1Y2tldCwgUzNLZXk6IExheWVyTmFtZSB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgQ29udGVudCA9IHsgWmlwRmlsZSB9O1xuICAgICAgICB9XG4gICAgICAgIGxvZyhgQ3JlYXRpbmcgbGFtYmRhIGxheWVyOiAke0xheWVyTmFtZX0sIHppcCBmaWxlIHNpemU6ICR7WmlwRmlsZS5sZW5ndGh9YCk7XG4gICAgICAgIGNvbnN0IHB1Ymxpc2hSZXNwb25zZSA9IGF3YWl0IGxhbWJkYVxuICAgICAgICAgICAgLnB1Ymxpc2hMYXllclZlcnNpb24oe1xuICAgICAgICAgICAgICAgIExheWVyTmFtZSxcbiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbjogYGZhYXN0IHBhY2thZ2VKc29uIGxheWVyIHdpdGggTGF5ZXJOYW1lICR7TGF5ZXJOYW1lfWAsXG4gICAgICAgICAgICAgICAgQ29udGVudCxcbiAgICAgICAgICAgICAgICBDb21wYXRpYmxlUnVudGltZXM6IFtcIm5vZGVqc1wiXVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5wcm9taXNlKCk7XG4gICAgICAgIGNvbnN0IHsgVmVyc2lvbiB9ID0gcHVibGlzaFJlc3BvbnNlO1xuICAgICAgICBsb2coYENyZWF0ZWQgbGFtYmRhIGxheWVyOiAke0xheWVyTmFtZX06JHtWZXJzaW9ufWApO1xuICAgICAgICBsb2coYERPTkVgKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGluc3RhbGxMb2csXG4gICAgICAgICAgICBsYXllckluZm86IHtcbiAgICAgICAgICAgICAgICBMYXllck5hbWUsXG4gICAgICAgICAgICAgICAgTGF5ZXJWZXJzaW9uQXJuOiBwdWJsaXNoUmVzcG9uc2UuTGF5ZXJWZXJzaW9uQXJuISxcbiAgICAgICAgICAgICAgICBWZXJzaW9uOiBwdWJsaXNoUmVzcG9uc2UuVmVyc2lvbiFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB6aXBTaXplXG4gICAgICAgIH07XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKENvbnRlbnQ/LlMzQnVja2V0KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHMzLmRlbGV0ZU9iamVjdCh7IEJ1Y2tldCwgS2V5OiBMYXllck5hbWUgfSkucHJvbWlzZSgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHMzLmRlbGV0ZUJ1Y2tldCh7IEJ1Y2tldCB9KS5wcm9taXNlKCk7XG4gICAgICAgICAgICB9IGNhdGNoIHt9XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgcmVtb3ZlUHJvbWlzZTtcbiAgICB9XG59XG4iXX0=
\No newline at end of file