UNPKG

faastjs

Version:

Serverless batch computing made simple.

113 lines 16.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.npmInstall = void 0; const tslib_1 = require("tslib"); const archiver_1 = tslib_1.__importDefault(require("archiver")); const child_process_1 = require("child_process"); const fs_extra_1 = require("fs-extra"); const os_1 = require("os"); const path_1 = tslib_1.__importDefault(require("path")); const util_1 = require("util"); const shared_1 = require("../shared"); const client_lambda_1 = require("@aws-sdk/client-lambda"); const client_s3_1 = require("@aws-sdk/client-s3"); const lib_storage_1 = require("@aws-sdk/lib-storage"); 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_1.default.join((0, os_1.tmpdir)(), FunctionName); const buildDir = path_1.default.join(buildParentDir, "nodejs"); await (0, fs_extra_1.ensureDir)(buildDir); await (0, fs_extra_1.writeFile)(path_1.default.join(buildDir, "package.json"), packageJsonContents); const awsconfig = { maxRetries: 6 }; let installLog = ""; log("Checking cache"); log(`Checking faast layers for ${LayerName}`); const lambda = new client_lambda_1.Lambda({ apiVersion: "2015-03-31", region, ...awsconfig }); const cached = await lambda .listLayerVersions({ LayerName, CompatibleRuntime: "nodejs" }) .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 = (0, archiver_1.default)("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 client_s3_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 }).catch(_ => { }); log(`Uploading bucket: ${Bucket}, object: ${LayerName}`); const upload = new lib_storage_1.Upload({ client: s3, params: { Bucket, Key: LayerName, Body: ZipFile } }); await upload.done(); 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"] }); 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 }); await s3.deleteBucket({ Bucket }); } catch { } } await removePromise; } } exports.npmInstall = npmInstall; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLW5wbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hd3MvYXdzLW5wbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsZ0VBQWdDO0FBQ2hDLGlEQUF5QztBQUN6Qyx1Q0FBd0Q7QUFDeEQsMkJBQTRCO0FBQzVCLHdEQUF3QjtBQUN4QiwrQkFBK0I7QUFDL0Isc0NBQXVEO0FBQ3ZELDBEQUEwRTtBQUMxRSxrREFBd0M7QUFDeEMsc0RBQThDO0FBRTlDLEtBQUssVUFBVSxJQUFJLENBQUMsSUFBYztJQUM5QixJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDWixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3JCLEVBQUUsSUFBSSxJQUFBLHdCQUFRLEVBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUNELE9BQU8sRUFBRSxDQUFDO0FBQ2QsQ0FBQztBQXVCTSxLQUFLLFVBQVUsVUFBVSxDQUFDLEVBQzdCLFNBQVMsRUFDVCxtQkFBbUIsRUFDbkIsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsZUFBZSxFQUNGO0lBQ2IsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQVMsRUFBRSxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO0lBRXBELEdBQUcsQ0FDQyw2SEFBNkgsQ0FDaEksQ0FBQztJQUNGLEdBQUcsQ0FDQywwSkFBMEosQ0FDN0osQ0FBQztJQUVGLE1BQU0sY0FBYyxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBQSxXQUFNLEdBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN6RCxNQUFNLFFBQVEsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNyRCxNQUFNLElBQUEsb0JBQVMsRUFBQyxRQUFRLENBQUMsQ0FB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QUFDO1lBQVMsQ0FBQztRQUNQLElBQUksT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQztnQkFDRCxNQUFNLEVBQUUsQ0FBQyxZQUFZLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7Z0JBQ2xELE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDdEMsQ0FBQztZQUFDLE1BQU0sQ0FBQyxDQUFBLENBQUM7UUFDZCxDQUFDO1FBQ0QsTUFBTSxhQUFhLENBQUM7SUFDeEIsQ0FBQztBQUNMLENBQUM7QUF4R0QsZ0NBd0dDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFyY2hpdmVyIGZyb20gXCJhcmNoaXZlclwiO1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgZW5zdXJlRGlyLCByZW1vdmUsIHdyaXRlRmlsZSB9IGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgaW5zcGVjdCB9IGZyb20gXCJ1dGlsXCI7XG5pbXBvcnQgeyBoYXNFeHBpcmVkLCBzdHJlYW1Ub0J1ZmZlciB9IGZyb20gXCIuLi9zaGFyZWRcIjtcbmltcG9ydCB7IExhbWJkYSwgTGF5ZXJWZXJzaW9uQ29udGVudElucHV0IH0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1sYW1iZGFcIjtcbmltcG9ydCB7IFMzIH0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1zM1wiO1xuaW1wb3J0IHsgVXBsb2FkIH0gZnJvbSBcIkBhd3Mtc2RrL2xpYi1zdG9yYWdlXCI7XG5cbmFzeW5jIGZ1bmN0aW9uIGV4ZWMoY21kczogc3RyaW5nW10pIHtcbiAgICBsZXQgcnYgPSBcIlwiO1xuICAgIGZvciAoY29uc3QgY21kIG9mIGNtZHMpIHtcbiAgICAgICAgcnYgKz0gZXhlY1N5bmMoY21kKS50b1N0cmluZygpO1xuICAgIH1cbiAgICByZXR1cm4gcnY7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTnBtSW5zdGFsbEFyZ3Mge1xuICAgIHBhY2thZ2VKc29uQ29udGVudHM6IHN0cmluZztcbiAgICBMYXllck5hbWU6IHN0cmluZztcbiAgICBGdW5jdGlvbk5hbWU6IHN0cmluZztcbiAgICByZWdpb246IHN0cmluZztcbiAgICBxdWlldD86IGJvb2xlYW47XG4gICAgcmV0ZW50aW9uSW5EYXlzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXdzTGF5ZXJJbmZvIHtcbiAgICBWZXJzaW9uOiBudW1iZXI7XG4gICAgTGF5ZXJWZXJzaW9uQXJuOiBzdHJpbmc7XG4gICAgTGF5ZXJOYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTnBtSW5zdGFsbFJldHVybiB7XG4gICAgaW5zdGFsbExvZzogc3RyaW5nO1xuICAgIGxheWVySW5mbzogQXdzTGF5ZXJJbmZvO1xuICAgIHppcFNpemU/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBucG1JbnN0YWxsKHtcbiAgICBMYXllck5hbWUsXG4gICAgcGFja2FnZUpzb25Db250ZW50cyxcbiAgICBGdW5jdGlvbk5hbWUsXG4gICAgcmVnaW9uLFxuICAgIHF1aWV0LFxuICAgIHJldGVudGlvbkluRGF5c1xufTogTnBtSW5zdGFsbEFyZ3MpOiBQcm9taXNlPE5wbUluc3RhbGxSZXR1cm4+IHtcbiAgICBjb25zdCBsb2cgPSBxdWlldCA/IChfOiBzdHJpbmcpID0+IHt9IDogY29uc29sZS5sb2c7XG5cbiAgICBsb2coXG4gICAgICAgIGAqKiogVGhpcyBmYWFzdCBpbnZvY2F0aW9uIGlzIGFuIGludGVybmFsIGxhbWJkYSBjYWxsIHVzZWQgd2hlbiB0aGUgcGFja2FnZUpzb24gb3B0aW9uIGlzIHNwZWNpZmllZCB0byBjcmVhdGVGdW5jdGlvbigpLiAqKipgXG4gICAgKTtcbiAgICBsb2coXG4gICAgICAgIGAqKiogSXRzIHB1cnBvc2UgaXMgdG8gY3JlYXRlIGEgbm9kZV9tb2R1bGVzIHBhY2thZ2UgYW5kIGNhY2hlIGl0LCB0aGVuIGNvbWJpbmUgd2l0aCB1c2VyIGNvZGUgdG8gZm9ybSBhbiBBV1MgTGFtYmRhIGNvZGUgcGFja2FnZSBhbmQgdXBsb2FkIGl0IHRvIFMzICoqKmBcbiAgICApO1xuXG4gICAgY29uc3QgYnVpbGRQYXJlbnREaXIgPSBwYXRoLmpvaW4odG1wZGlyKCksIEZ1bmN0aW9uTmFtZSk7XG4gICAgY29uc3QgYnVpbGREaXIgPSBwYXRoLmpvaW4oYnVpbGRQYXJlbnREaXIsIFwibm9kZWpzXCIpO1xuICAgIGF3YWl0IGVuc3VyZURpcihidWlsZERpcik7XG4gICAgYXdhaXQgd3JpdGVGaWxlKHBhdGguam9pbihidWlsZERpciwgXCJwYWNrYWdlLmpzb25cIiksIHBhY2thZ2VKc29uQ29udGVudHMpO1xuXG4gICAgY29uc3QgYXdzY29uZmlnID0geyBtYXhSZXRyaWVzOiA2IH07XG5cbiAgICBsZXQgaW5zdGFsbExvZyA9IFwiXCI7XG4gICAgbG9nKFwiQ2hlY2tpbmcgY2FjaGVcIik7XG4gICAgbG9nKGBDaGVja2luZyBmYWFzdCBsYXllcnMgZm9yICR7TGF5ZXJOYW1lfWApO1xuICAgIGNvbnN0IGxhbWJkYSA9IG5ldyBMYW1iZGEoeyBhcGlWZXJzaW9uOiBcIjIwMTUtMDMtMzFcIiwgcmVnaW9uLCAuLi5hd3Njb25maWcgfSk7XG5cbiAgICBjb25zdCBjYWNoZWQgPSBhd2FpdCBsYW1iZGFcbiAgICAgICAgLmxpc3RMYXllclZlcnNpb25zKHsgTGF5ZXJOYW1lLCBDb21wYXRpYmxlUnVudGltZTogXCJub2RlanNcIiB9KVxuICAgICAgICAuY2F0Y2goXyA9PiB1bmRlZmluZWQpO1xuXG4gICAgY29uc3QgbGF5ZXJWZXJzaW9uID0gY2FjaGVkPy5MYXllclZlcnNpb25zPy5bMF07XG4gICAgaWYgKGxheWVyVmVyc2lvbiAmJiAhaGFzRXhwaXJlZChsYXllclZlcnNpb24uQ3JlYXRlZERhdGUsIHJldGVudGlvbkluRGF5cykpIHtcbiAgICAgICAgY29uc3QgbGF5ZXJJbmZvID0ge1xuICAgICAgICAgICAgTGF5ZXJOYW1lLFxuICAgICAgICAgICAgVmVyc2lvbjogbGF5ZXJWZXJzaW9uLlZlcnNpb24hLFxuICAgICAgICAgICAgTGF5ZXJWZXJzaW9uQXJuOiBsYXllclZlcnNpb24uTGF5ZXJWZXJzaW9uQXJuIVxuICAgICAgICB9O1xuICAgICAgICBsb2coYENBQ0hFRCwgJHtpbnNwZWN0KGxheWVySW5mbyl9YCk7XG4gICAgICAgIHJldHVybiB7IGluc3RhbGxMb2csIGxheWVySW5mbyB9O1xuICAgIH1cblxuICAgIGxvZyhcIk5PVCBDQUNIRUQsIHJ1bm5pbmcgbnBtIGluc3RhbGxcIik7XG4gICAgaW5zdGFsbExvZyArPSBhd2FpdCBleGVjKFtgZWNobyBcImhlbGxvIHdvcmxkXCJgXSk7XG4gICAgaW5zdGFsbExvZyArPSBhd2FpdCBleGVjKFtcbiAgICAgICAgYGV4cG9ydCBIT01FPS90bXA7IG5wbSBpbnN0YWxsIC0tcHJlZml4PSR7YnVpbGREaXJ9IC0tbm8tcGFja2FnZS1sb2NrYFxuICAgIF0pO1xuICAgIGxvZyhgUnVubmluZyBhcmNoaXZlcmApO1xuICAgIGNvbnN0IGNhY2hlQXJjaGl2ZSA9IGFyY2hpdmVyKFwiemlwXCIsIHsgemxpYjogeyBsZXZlbDogOCB9IH0pO1xuICAgIGNhY2hlQXJjaGl2ZS5kaXJlY3RvcnkoYnVpbGRQYXJlbnREaXIsIGZhbHNlKS5maW5hbGl6ZSgpO1xuICAgIGxvZyhgQ29udmVydGluZyBhcmNoaXZlIHRvIGJ1ZmZlcmApO1xuICAgIGNvbnN0IFppcEZpbGUgPSBhd2FpdCBzdHJlYW1Ub0J1ZmZlcihjYWNoZUFyY2hpdmUpO1xuICAgIGxvZyhgQ29kZSBaaXBGaWxlIHNpemU6ICR7WmlwRmlsZS5sZW5ndGh9YCk7XG4gICAgbG9nKGBSZW1vdmluZyAke2J1aWxkUGFyZW50RGlyfWApO1xuICAgIGNvbnN0IHJlbW92ZVByb21pc2UgPSByZW1vdmUoYnVpbGRQYXJlbnREaXIpO1xuICAgIGxldCBDb250ZW50OiBMYXllclZlcnNpb25Db250ZW50SW5wdXQgfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgQnVja2V0ID0gRnVuY3Rpb25OYW1lO1xuICAgIGNvbnN0IHMzID0gbmV3IFMzKHsgcmVnaW9uLCAuLi5hd3Njb25maWcgfSk7XG4gICAgY29uc3QgemlwU2l6ZSA9IFppcEZpbGUubGVuZ3RoO1xuICAgIHRyeSB7XG4gICAgICAgIGlmIChaaXBGaWxlLmxlbmd0aCA+IDUwICogMiAqKiAyMCkge1xuICAgICAgICAgICAgLy8gVHJ5IHRvIHVzZSBTMyB0byBhbGxvdyBmb3IgYSBsYXJnZXIgbGltaXRcbiAgICAgICAgICAgIGxvZyhgQ3JlYXRpbmcgczMgYnVja2V0ICR7QnVja2V0fWApO1xuICAgICAgICAgICAgYXdhaXQgczMuY3JlYXRlQnVja2V0KHsgQnVja2V0IH0pLmNhdGNoKF8gPT4ge30pO1xuICAgICAgICAgICAgbG9nKGBVcGxvYWRpbmcgYnVja2V0OiAke0J1Y2tldH0sIG9iamVjdDogJHtMYXllck5hbWV9YCk7XG4gICAgICAgICAgICBjb25zdCB1cGxvYWQgPSBuZXcgVXBsb2FkKHtcbiAgICAgICAgICAgICAgICBjbGllbnQ6IHMzLFxuICAgICAgICAgICAgICAgIHBhcmFtczogeyBCdWNrZXQsIEtleTogTGF5ZXJOYW1lLCBCb2R5OiBaaXBGaWxlIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYXdhaXQgdXBsb2FkLmRvbmUoKTtcbiAgICAgICAgICAgIENvbnRlbnQgPSB7IFMzQnVja2V0OiBCdWNrZXQsIFMzS2V5OiBMYXllck5hbWUgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIENvbnRlbnQgPSB7IFppcEZpbGUgfTtcbiAgICAgICAgfVxuICAgICAgICBsb2coYENyZWF0aW5nIGxhbWJkYSBsYXllcjogJHtMYXllck5hbWV9LCB6aXAgZmlsZSBzaXplOiAke1ppcEZpbGUubGVuZ3RofWApO1xuICAgICAgICBjb25zdCBwdWJsaXNoUmVzcG9uc2UgPSBhd2FpdCBsYW1iZGEucHVibGlzaExheWVyVmVyc2lvbih7XG4gICAgICAgICAgICBMYXllck5hbWUsXG4gICAgICAgICAgICBEZXNjcmlwdGlvbjogYGZhYXN0IHBhY2thZ2VKc29uIGxheWVyIHdpdGggTGF5ZXJOYW1lICR7TGF5ZXJOYW1lfWAsXG4gICAgICAgICAgICBDb250ZW50LFxuICAgICAgICAgICAgQ29tcGF0aWJsZVJ1bnRpbWVzOiBbXCJub2RlanNcIl1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHsgVmVyc2lvbiB9ID0gcHVibGlzaFJlc3BvbnNlO1xuICAgICAgICBsb2coYENyZWF0ZWQgbGFtYmRhIGxheWVyOiAke0xheWVyTmFtZX06JHtWZXJzaW9ufWApO1xuICAgICAgICBsb2coYERPTkVgKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGluc3RhbGxMb2csXG4gICAgICAgICAgICBsYXllckluZm86IHtcbiAgICAgICAgICAgICAgICBMYXllck5hbWUsXG4gICAgICAgICAgICAgICAgTGF5ZXJWZXJzaW9uQXJuOiBwdWJsaXNoUmVzcG9uc2UuTGF5ZXJWZXJzaW9uQXJuISxcbiAgICAgICAgICAgICAgICBWZXJzaW9uOiBwdWJsaXNoUmVzcG9uc2UuVmVyc2lvbiFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB6aXBTaXplXG4gICAgICAgIH07XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKENvbnRlbnQ/LlMzQnVja2V0KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHMzLmRlbGV0ZU9iamVjdCh7IEJ1Y2tldCwgS2V5OiBMYXllck5hbWUgfSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgczMuZGVsZXRlQnVja2V0KHsgQnVja2V0IH0pO1xuICAgICAgICAgICAgfSBjYXRjaCB7fVxuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHJlbW92ZVByb21pc2U7XG4gICAgfVxufVxuIl19