faastjs
Version:
Serverless batch computing made simple.
112 lines • 16.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.npmInstall = void 0;
const archiver = require("archiver");
const aws_sdk_1 = require("aws-sdk");
const child_process_1 = require("child_process");
const fs_extra_1 = require("fs-extra");
const os_1 = require("os");
const path = require("path");
const util_1 = require("util");
const shared_1 = require("../shared");
async function exec(cmds) {
let rv = "";
for (const cmd of cmds) {
rv += (0, child_process_1.execSync)(cmd).toString();
}
return rv;
}
async function npmInstall({ LayerName, packageJsonContents, FunctionName, region, quiet, retentionInDays }) {
const log = quiet ? (_) => { } : console.log;
log(`*** This faast invocation is an internal lambda call used when the packageJson option is specified to createFunction(). ***`);
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 ***`);
const buildParentDir = path.join((0, os_1.tmpdir)(), FunctionName);
const buildDir = path.join(buildParentDir, "nodejs");
await (0, fs_extra_1.ensureDir)(buildDir);
await (0, fs_extra_1.writeFile)(path.join(buildDir, "package.json"), packageJsonContents);
const awsconfig = { correctClockSkew: true, maxRetries: 6 };
let installLog = "";
log("Checking cache");
log(`Checking faast layers for ${LayerName}`);
const lambda = new aws_sdk_1.Lambda({ apiVersion: "2015-03-31", region, ...awsconfig });
const cached = await lambda
.listLayerVersions({ LayerName, CompatibleRuntime: "nodejs" })
.promise()
.catch(_ => undefined);
const layerVersion = cached?.LayerVersions?.[0];
if (layerVersion && !(0, shared_1.hasExpired)(layerVersion.CreatedDate, retentionInDays)) {
const layerInfo = {
LayerName,
Version: layerVersion.Version,
LayerVersionArn: layerVersion.LayerVersionArn
};
log(`CACHED, ${(0, util_1.inspect)(layerInfo)}`);
return { installLog, layerInfo };
}
log("NOT CACHED, running npm install");
installLog += await exec([`echo "hello world"`]);
installLog += await exec([
`export HOME=/tmp; npm install --prefix=${buildDir} --no-package-lock`
]);
log(`Running archiver`);
const cacheArchive = archiver("zip", { zlib: { level: 8 } });
cacheArchive.directory(buildParentDir, false).finalize();
log(`Converting archive to buffer`);
const ZipFile = await (0, shared_1.streamToBuffer)(cacheArchive);
log(`Code ZipFile size: ${ZipFile.length}`);
log(`Removing ${buildParentDir}`);
const removePromise = (0, fs_extra_1.remove)(buildParentDir);
let Content;
const Bucket = FunctionName;
const s3 = new aws_sdk_1.S3({ region, ...awsconfig });
const zipSize = ZipFile.length;
try {
if (ZipFile.length > 50 * 2 ** 20) {
// Try to use S3 to allow for a larger limit
log(`Creating s3 bucket ${Bucket}`);
await s3
.createBucket({ Bucket })
.promise()
.catch(_ => { });
log(`Uploading bucket: ${Bucket}, object: ${LayerName}`);
await s3.upload({ Bucket, Key: LayerName, Body: ZipFile }).promise();
Content = { S3Bucket: Bucket, S3Key: LayerName };
}
else {
Content = { ZipFile };
}
log(`Creating lambda layer: ${LayerName}, zip file size: ${ZipFile.length}`);
const publishResponse = await lambda
.publishLayerVersion({
LayerName,
Description: `faast packageJson layer with LayerName ${LayerName}`,
Content,
CompatibleRuntimes: ["nodejs"]
})
.promise();
const { Version } = publishResponse;
log(`Created lambda layer: ${LayerName}:${Version}`);
log(`DONE`);
return {
installLog,
layerInfo: {
LayerName,
LayerVersionArn: publishResponse.LayerVersionArn,
Version: publishResponse.Version
},
zipSize
};
}
finally {
if (Content?.S3Bucket) {
try {
await s3.deleteObject({ Bucket, Key: LayerName }).promise();
await s3.deleteBucket({ Bucket }).promise();
}
catch { }
}
await removePromise;
}
}
exports.npmInstall = npmInstall;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLW5wbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hd3MvYXdzLW5wbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxQ0FBcUM7QUFDckMscUNBQXFDO0FBQ3JDLGlEQUF5QztBQUN6Qyx1Q0FBd0Q7QUFDeEQsMkJBQTRCO0FBQzVCLDZCQUE2QjtBQUM3QiwrQkFBK0I7QUFDL0Isc0NBQXVEO0FBRXZELEtBQUssVUFBVSxJQUFJLENBQUMsSUFBYztJQUM5QixJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDWixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRTtRQUNwQixFQUFFLElBQUksSUFBQSx3QkFBUSxFQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0tBQ2xDO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDZCxDQUFDO0FBdUJNLEtBQUssVUFBVSxVQUFVLENBQUMsRUFDN0IsU0FBUyxFQUNULG1CQUFtQixFQUNuQixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFDTCxlQUFlLEVBQ0Y7SUFDYixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsR0FBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7SUFFcEQsR0FBRyxDQUNDLDZIQUE2SCxDQUNoSSxDQUFDO0lBQ0YsR0FBRyxDQUNDLDBKQUEwSixDQUM3SixDQUFDO0lBRUYsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFBLFdBQU0sR0FBRSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3pELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3JELE1BQU0sSUFBQSxvQkFBUyxFQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzFCLE1BQU0sSUFBQSxvQkFBUyxFQUFDLElBQUksQ0FB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RUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzVELE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDL0M7WUFBQyxNQUFNLEdBQUU7U0FDYjtRQUNELE1BQU0sYUFBYSxDQUFDO0tBQ3ZCO0FBQ0wsQ0FBQztBQTFHRCxnQ0EwR0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhcmNoaXZlciBmcm9tIFwiYXJjaGl2ZXJcIjtcbmltcG9ydCB7IExhbWJkYSwgUzMgfSBmcm9tIFwiYXdzLXNka1wiO1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgZW5zdXJlRGlyLCByZW1vdmUsIHdyaXRlRmlsZSB9IGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSBcIm9zXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSBcInV0aWxcIjtcbmltcG9ydCB7IHN0cmVhbVRvQnVmZmVyLCBoYXNFeHBpcmVkIH0gZnJvbSBcIi4uL3NoYXJlZFwiO1xuXG5hc3luYyBmdW5jdGlvbiBleGVjKGNtZHM6IHN0cmluZ1tdKSB7XG4gICAgbGV0IHJ2ID0gXCJcIjtcbiAgICBmb3IgKGNvbnN0IGNtZCBvZiBjbWRzKSB7XG4gICAgICAgIHJ2ICs9IGV4ZWNTeW5jKGNtZCkudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgcmV0dXJuIHJ2O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5wbUluc3RhbGxBcmdzIHtcbiAgICBwYWNrYWdlSnNvbkNvbnRlbnRzOiBzdHJpbmc7XG4gICAgTGF5ZXJOYW1lOiBzdHJpbmc7XG4gICAgRnVuY3Rpb25OYW1lOiBzdHJpbmc7XG4gICAgcmVnaW9uOiBzdHJpbmc7XG4gICAgcXVpZXQ/OiBib29sZWFuO1xuICAgIHJldGVudGlvbkluRGF5czogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF3c0xheWVySW5mbyB7XG4gICAgVmVyc2lvbjogbnVtYmVyO1xuICAgIExheWVyVmVyc2lvbkFybjogc3RyaW5nO1xuICAgIExheWVyTmFtZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5wbUluc3RhbGxSZXR1cm4ge1xuICAgIGluc3RhbGxMb2c6IHN0cmluZztcbiAgICBsYXllckluZm86IEF3c0xheWVySW5mbztcbiAgICB6aXBTaXplPzogbnVtYmVyO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbnBtSW5zdGFsbCh7XG4gICAgTGF5ZXJOYW1lLFxuICAgIHBhY2thZ2VKc29uQ29udGVudHMsXG4gICAgRnVuY3Rpb25OYW1lLFxuICAgIHJlZ2lvbixcbiAgICBxdWlldCxcbiAgICByZXRlbnRpb25JbkRheXNcbn06IE5wbUluc3RhbGxBcmdzKTogUHJvbWlzZTxOcG1JbnN0YWxsUmV0dXJuPiB7XG4gICAgY29uc3QgbG9nID0gcXVpZXQgPyAoXzogc3RyaW5nKSA9PiB7fSA6IGNvbnNvbGUubG9nO1xuXG4gICAgbG9nKFxuICAgICAgICBgKioqIFRoaXMgZmFhc3QgaW52b2NhdGlvbiBpcyBhbiBpbnRlcm5hbCBsYW1iZGEgY2FsbCB1c2VkIHdoZW4gdGhlIHBhY2thZ2VKc29uIG9wdGlvbiBpcyBzcGVjaWZpZWQgdG8gY3JlYXRlRnVuY3Rpb24oKS4gKioqYFxuICAgICk7XG4gICAgbG9nKFxuICAgICAgICBgKioqIEl0cyBwdXJwb3NlIGlzIHRvIGNyZWF0ZSBhIG5vZGVfbW9kdWxlcyBwYWNrYWdlIGFuZCBjYWNoZSBpdCwgdGhlbiBjb21iaW5lIHdpdGggdXNlciBjb2RlIHRvIGZvcm0gYW4gQVdTIExhbWJkYSBjb2RlIHBhY2thZ2UgYW5kIHVwbG9hZCBpdCB0byBTMyAqKipgXG4gICAgKTtcblxuICAgIGNvbnN0IGJ1aWxkUGFyZW50RGlyID0gcGF0aC5qb2luKHRtcGRpcigpLCBGdW5jdGlvbk5hbWUpO1xuICAgIGNvbnN0IGJ1aWxkRGlyID0gcGF0aC5qb2luKGJ1aWxkUGFyZW50RGlyLCBcIm5vZGVqc1wiKTtcbiAgICBhd2FpdCBlbnN1cmVEaXIoYnVpbGREaXIpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShwYXRoLmpvaW4oYnVpbGREaXIsIFwicGFja2FnZS5qc29uXCIpLCBwYWNrYWdlSnNvbkNvbnRlbnRzKTtcblxuICAgIGNvbnN0IGF3c2NvbmZpZyA9IHsgY29ycmVjdENsb2NrU2tldzogdHJ1ZSwgbWF4UmV0cmllczogNiB9O1xuXG4gICAgbGV0IGluc3RhbGxMb2cgPSBcIlwiO1xuICAgIGxvZyhcIkNoZWNraW5nIGNhY2hlXCIpO1xuICAgIGxvZyhgQ2hlY2tpbmcgZmFhc3QgbGF5ZXJzIGZvciAke0xheWVyTmFtZX1gKTtcbiAgICBjb25zdCBsYW1iZGEgPSBuZXcgTGFtYmRhKHsgYXBpVmVyc2lvbjogXCIyMDE1LTAzLTMxXCIsIHJlZ2lvbiwgLi4uYXdzY29uZmlnIH0pO1xuXG4gICAgY29uc3QgY2FjaGVkID0gYXdhaXQgbGFtYmRhXG4gICAgICAgIC5saXN0TGF5ZXJWZXJzaW9ucyh7IExheWVyTmFtZSwgQ29tcGF0aWJsZVJ1bnRpbWU6IFwibm9kZWpzXCIgfSlcbiAgICAgICAgLnByb21pc2UoKVxuICAgICAgICAuY2F0Y2goXyA9PiB1bmRlZmluZWQpO1xuXG4gICAgY29uc3QgbGF5ZXJWZXJzaW9uID0gY2FjaGVkPy5MYXllclZlcnNpb25zPy5bMF07XG4gICAgaWYgKGxheWVyVmVyc2lvbiAmJiAhaGFzRXhwaXJlZChsYXllclZlcnNpb24uQ3JlYXRlZERhdGUsIHJldGVudGlvbkluRGF5cykpIHtcbiAgICAgICAgY29uc3QgbGF5ZXJJbmZvID0ge1xuICAgICAgICAgICAgTGF5ZXJOYW1lLFxuICAgICAgICAgICAgVmVyc2lvbjogbGF5ZXJWZXJzaW9uLlZlcnNpb24hLFxuICAgICAgICAgICAgTGF5ZXJWZXJzaW9uQXJuOiBsYXllclZlcnNpb24uTGF5ZXJWZXJzaW9uQXJuIVxuICAgICAgICB9O1xuICAgICAgICBsb2coYENBQ0hFRCwgJHtpbnNwZWN0KGxheWVySW5mbyl9YCk7XG4gICAgICAgIHJldHVybiB7IGluc3RhbGxMb2csIGxheWVySW5mbyB9O1xuICAgIH1cblxuICAgIGxvZyhcIk5PVCBDQUNIRUQsIHJ1bm5pbmcgbnBtIGluc3RhbGxcIik7XG4gICAgaW5zdGFsbExvZyArPSBhd2FpdCBleGVjKFtgZWNobyBcImhlbGxvIHdvcmxkXCJgXSk7XG4gICAgaW5zdGFsbExvZyArPSBhd2FpdCBleGVjKFtcbiAgICAgICAgYGV4cG9ydCBIT01FPS90bXA7IG5wbSBpbnN0YWxsIC0tcHJlZml4PSR7YnVpbGREaXJ9IC0tbm8tcGFja2FnZS1sb2NrYFxuICAgIF0pO1xuICAgIGxvZyhgUnVubmluZyBhcmNoaXZlcmApO1xuICAgIGNvbnN0IGNhY2hlQXJjaGl2ZSA9IGFyY2hpdmVyKFwiemlwXCIsIHsgemxpYjogeyBsZXZlbDogOCB9IH0pO1xuICAgIGNhY2hlQXJjaGl2ZS5kaXJlY3RvcnkoYnVpbGRQYXJlbnREaXIsIGZhbHNlKS5maW5hbGl6ZSgpO1xuICAgIGxvZyhgQ29udmVydGluZyBhcmNoaXZlIHRvIGJ1ZmZlcmApO1xuICAgIGNvbnN0IFppcEZpbGUgPSBhd2FpdCBzdHJlYW1Ub0J1ZmZlcihjYWNoZUFyY2hpdmUpO1xuICAgIGxvZyhgQ29kZSBaaXBGaWxlIHNpemU6ICR7WmlwRmlsZS5sZW5ndGh9YCk7XG4gICAgbG9nKGBSZW1vdmluZyAke2J1aWxkUGFyZW50RGlyfWApO1xuICAgIGNvbnN0IHJlbW92ZVByb21pc2UgPSByZW1vdmUoYnVpbGRQYXJlbnREaXIpO1xuICAgIGxldCBDb250ZW50OiBMYW1iZGEuTGF5ZXJWZXJzaW9uQ29udGVudElucHV0IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IEJ1Y2tldCA9IEZ1bmN0aW9uTmFtZTtcbiAgICBjb25zdCBzMyA9IG5ldyBTMyh7IHJlZ2lvbiwgLi4uYXdzY29uZmlnIH0pO1xuICAgIGNvbnN0IHppcFNpemUgPSBaaXBGaWxlLmxlbmd0aDtcbiAgICB0cnkge1xuICAgICAgICBpZiAoWmlwRmlsZS5sZW5ndGggPiA1MCAqIDIgKiogMjApIHtcbiAgICAgICAgICAgIC8vIFRyeSB0byB1c2UgUzMgdG8gYWxsb3cgZm9yIGEgbGFyZ2VyIGxpbWl0XG4gICAgICAgICAgICBsb2coYENyZWF0aW5nIHMzIGJ1Y2tldCAke0J1Y2tldH1gKTtcbiAgICAgICAgICAgIGF3YWl0IHMzXG4gICAgICAgICAgICAgICAgLmNyZWF0ZUJ1Y2tldCh7IEJ1Y2tldCB9KVxuICAgICAgICAgICAgICAgIC5wcm9taXNlKClcbiAgICAgICAgICAgICAgICAuY2F0Y2goXyA9PiB7fSk7XG4gICAgICAgICAgICBsb2coYFVwbG9hZGluZyBidWNrZXQ6ICR7QnVja2V0fSwgb2JqZWN0OiAke0xheWVyTmFtZX1gKTtcbiAgICAgICAgICAgIGF3YWl0IHMzLnVwbG9hZCh7IEJ1Y2tldCwgS2V5OiBMYXllck5hbWUsIEJvZHk6IFppcEZpbGUgfSkucHJvbWlzZSgpO1xuICAgICAgICAgICAgQ29udGVudCA9IHsgUzNCdWNrZXQ6IEJ1Y2tldCwgUzNLZXk6IExheWVyTmFtZSB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgQ29udGVudCA9IHsgWmlwRmlsZSB9O1xuICAgICAgICB9XG4gICAgICAgIGxvZyhgQ3JlYXRpbmcgbGFtYmRhIGxheWVyOiAke0xheWVyTmFtZX0sIHppcCBmaWxlIHNpemU6ICR7WmlwRmlsZS5sZW5ndGh9YCk7XG4gICAgICAgIGNvbnN0IHB1Ymxpc2hSZXNwb25zZSA9IGF3YWl0IGxhbWJkYVxuICAgICAgICAgICAgLnB1Ymxpc2hMYXllclZlcnNpb24oe1xuICAgICAgICAgICAgICAgIExheWVyTmFtZSxcbiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbjogYGZhYXN0IHBhY2thZ2VKc29uIGxheWVyIHdpdGggTGF5ZXJOYW1lICR7TGF5ZXJOYW1lfWAsXG4gICAgICAgICAgICAgICAgQ29udGVudCxcbiAgICAgICAgICAgICAgICBDb21wYXRpYmxlUnVudGltZXM6IFtcIm5vZGVqc1wiXVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5wcm9taXNlKCk7XG4gICAgICAgIGNvbnN0IHsgVmVyc2lvbiB9ID0gcHVibGlzaFJlc3BvbnNlO1xuICAgICAgICBsb2coYENyZWF0ZWQgbGFtYmRhIGxheWVyOiAke0xheWVyTmFtZX06JHtWZXJzaW9ufWApO1xuICAgICAgICBsb2coYERPTkVgKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGluc3RhbGxMb2csXG4gICAgICAgICAgICBsYXllckluZm86IHtcbiAgICAgICAgICAgICAgICBMYXllck5hbWUsXG4gICAgICAgICAgICAgICAgTGF5ZXJWZXJzaW9uQXJuOiBwdWJsaXNoUmVzcG9uc2UuTGF5ZXJWZXJzaW9uQXJuISxcbiAgICAgICAgICAgICAgICBWZXJzaW9uOiBwdWJsaXNoUmVzcG9uc2UuVmVyc2lvbiFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB6aXBTaXplXG4gICAgICAgIH07XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKENvbnRlbnQ/LlMzQnVja2V0KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHMzLmRlbGV0ZU9iamVjdCh7IEJ1Y2tldCwgS2V5OiBMYXllck5hbWUgfSkucHJvbWlzZSgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHMzLmRlbGV0ZUJ1Y2tldCh7IEJ1Y2tldCB9KS5wcm9taXNlKCk7XG4gICAgICAgICAgICB9IGNhdGNoIHt9XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgcmVtb3ZlUHJvbWlzZTtcbiAgICB9XG59XG4iXX0=