Berechtigungen Probleme auf AWS Lambda kann nicht spawn child process

So, ich habe diese nette kleine lambda, die läuft Super lokal, aber nicht so viel, wenn tatsächlich in der wildnis.

Lambda nimmt ein Ereignis, mit html in der Quelle, wandelt html-in eine PDF (mittels der html-und pdf-Knoten-Modul), geht das pdf in einem s3-bucket, und dann die Hände wieder einer signierten url, läuft in 60 Sekunden.

Oder zumindest das ist, was sollte passieren (mal wieder, der lokal arbeitet). Wenn Sie den Test auf Lambda, bekomme ich die folgende Fehlermeldung:

{
   "errorMessage": "spawn EACCES",
   "errorType": "Error",
   "stackTrace": [
       "exports._errnoException (util.js:870:11)",
       "ChildProcess.spawn (internal/child_process.js:298:11)",
       "Object.exports.spawn (child_process.js:362:9)",
       "PDF.PdfExec [as exec] (/var/task/node_modules/html-pdf/lib/pdf.js:87:28)",
       "PDF.PdfToFile [as toFile] (/var/task/node_modules/html-pdf/lib/pdf.js:83:8)",
       "/var/task/index.js:72:43",
       "Promise._execute (/var/task/node_modules/bluebird/js/release/debuggability.js:272:9)",
       "Promise._resolveFromExecutor (/var/task/node_modules/bluebird/js/release/promise.js:473:18)",
       "new Promise   (/var/task/node_modules/bluebird/js/release/promise.js:77:14)",
       "createPDF (/var/task/index.js:71:19)",
       "main (/var/task/index.js:50:5)"
  ]
}

Hier ist der code selbst (nicht kompiliert, gibt es eine praktische Schluck Aufgabe für die)

if(typeof regeneratorRuntime === 'undefined') {
    require("babel/polyfill")
}

import fs from 'fs'
import pdf from 'html-pdf'
import md5 from 'md5'
import AWS from 'aws-sdk'
import Promise from 'bluebird'
import moment from 'moment'

const tempDir = '/tmp'
const config = require('./config')
const s3 = new AWS.S3()

export const main = (event, context) => {
    console.log("Got event: ", event)

    AWS.config.update({
        accessKeyId: config.awsKey,
        secretAccessKey: config.awsSecret,
        region: 'us-east-1'
    })

    const filename = md5(event.html) + ".pdf"

    createPDF(event.html, filename).then(function(result) {
        uploadToS3(filename, result.filename).then(function(result) {
            getOneTimeUrl(filename).then(function(result) {
                return context.succeed(result)
            }, function(err) {
                console.log(err)
                return context.fail(err)
            })
        }, function(err) {
            console.log(err)
            return context.fail(err)
        })
    }, function(err) {
        console.log(err)
        return context.fail(err)
    })
}

const createPDF = (html, filename) => {
    console.log("Creating PDF")
    var promise = new Promise(function(resolve, reject) {
        pdf.create(html).toFile(filename, function(err, res) {
            if (err) {
                reject(err)
            } else {
                resolve(res)
            }
        })
    })
    return promise
}

const uploadToS3 = (filename, filePath) => {
    console.log("Pushing to S3")
    var promise = new Promise(function(resolve, reject) {

        var fileToUpload = fs.createReadStream(filePath)
        var expiryDate = moment().add(1, 'm').toDate()

        var uploadParams = {
            Bucket: config.pdfBucket,
            Key: filename,
            Body: fileToUpload
        }

        s3.upload(uploadParams, function(err, data) {
            if(err) {
                reject(err)
            } else {
                resolve(data)
            }
        })
    })
    return promise
}

const getOneTimeUrl = (filename) => {
    var promise = new Promise(function(resolve, reject) {
        var params = {
            Bucket: config.pdfBucket,
            Key: filename,
            Expires: 60
        }

        s3.getSignedUrl('getObject', params, function(err, url) {
            if (err) {
                reject(err)
            } else {
                resolve(url)
            }
        })
    })
    return promise
}

Scheint, wie ein problem innerhalb von html-pdf-Datei. Ich dachte, es könnte ein problem mit PhantomJS (die html-und pdf-abhängig) aufgrund von einigen Lesen, die ich hier gemacht: https://engineering.fundingcircle.com/blog/2015/04/09/aws-lambda-for-great-victory/ , jedoch, da die Lambda hat, stieß am max-Reißverschluss Größe 50 MB, ich habe nicht ein problem hochladen der binary.

Irgendwelche Gedanken?

InformationsquelleAutor wvm2008 | 2016-05-06



One Reply
  1. 4

    html-und pdf verwendet phantomjs unter der Haube, die benötigt, um zu kompilieren einige Binärdateien, wenn installiert wird. Ich denke, dein problem ist, dass Sie diese bereitstellen, die lokal kompilierten Binärdateien aber die Lambda muss die kompilierte Binärdateien auf dem Amazon Linux.

    Lösen können Sie dieses problem durch den Aufbau Ihrer Bereitstellung-Paket auf einer EC2-Instanz ausgeführt wird Amazon Linux und dann z.B. direkt von dort bereitstellen, wie es erklärt ist,dieses tutorial.

    Schauen Sie sich auch diese Antwort auf ein ähnliches problem.

    • Der Versuch, dieses aus, wird akzeptieren, wenn ich in der klaren, vielen Dank für die Klarheit Freund
    • nun, am Ende, das hat nicht funktioniert…ich konnte meinen code auf ec2 und bereitstellen ok, aber ich am Ende mit der exakt gleichen Fehler…Blick in den node_modules von html-pdf, es ist mit phantomjs_prebuilt, denke das könnte auch etwas damit zu tun?
    • Ist der code arbeiten, die auf EC2? Haben Sie vielleicht anrufen npm rebuild bei der Verwendung von phantomjs-vorgefertigte.
    • Ja, es läuft wie erwartet auf ec2 (wenn ich das dist/ code mit lambda-lokal)
    • Hat den binäre ist es executable-flag gesetzt? Dies ist der Hauptgrund für EACCES Fehler. Wenn Ihr code funktioniert auf dem Amazon Linux und Bereitstellung der exakt gleiche code, sollte es wirklich dasselbe Verhalten auf Lambda.
    • Ja…das executable-flag gesetzt ist gut…*Kopf gegen Wand*
    • Dann ist die Letzte Sache, die ich denken konnte ist, dass PhantomJS ist die Herstellung und Ausgabe, zu schreiben versucht es irgendwo anders als im Ordner /tmp. Sie haben nur Schreibrechte auf diesen Ordner auf Lambda
    • Ich war in der Lage zu führen Sie es nach unten, endlich. Phantomjs-vorgefertigte dynamisch zieht, in welcher phantomjs Bibliothek als ‚ideal‘ bei Laufzeit, anstatt statisch zu kompilieren die binary, wenn ich führen Sie npm install oder npm aufzubauen. So, obwohl ich hatte die executable-flag gesetzt, wird die Binärdatei, schließlich wird geladen, ich habe keinen Zugriff (Lesen: permission). Workaround war statisch kompilieren meiner eigenen phantomjs Bibliothek auf aws, linux, dann hochladen, die zu einem s3-bucket, dann erzählte html-pdf zu verwenden, die statisch kompilierte version von phantom eher als Suche nach Ihrer eigenen…vielen Dank für Ihre Hilfe!
    • Freut mich zu hören das es funktioniert!
    • Ich bin in der gleichen Boot – können Sie genauer beschreiben, wie Sie statisch kompilieren phantomjs und sagen, html-und pdf verwenden Sie diese version statt?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.