faastjs
Version:
Serverless batch computing made simple.
113 lines • 16.9 kB
JavaScript
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
;