5

Così ho creato questa piccola lambda, che funziona in modo ottimale localmente, ma non così tanto quando si è fuori in libertà.Problemi relativi alle autorizzazioni su AWS Lambda, non è possibile generare un processo figlio

lambda accetta un evento, con html nell'origine evento, converte l'html in un PDF (utilizzando il modulo nodo html-pdf), passa il pdf a un bucket s3 e restituisce un URL firmato che scade in 60 secondi.

O almeno questo è ciò che dovrebbe accadere (di nuovo, funziona localmente). Durante il test su Lambda, ottengo il seguente errore:

{ 
    "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)" 
    ] 
} 

Ecco il codice stesso (non compilato, c'è un compito sorso a portata di mano per questo)

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 
} 

sembra un problema all'interno di html pdf. Ho pensato che potrebbe essere un problema con PhantomJS (che dipende da html-pdf) a causa di alcune letture che ho fatto qui: https://engineering.fundingcircle.com/blog/2015/04/09/aws-lambda-for-great-victory/, tuttavia, dal momento che Lambda ha superato la dimensione massima di zip a 50 MB, non ho problemi a caricare il file binario .

Qualche idea?

risposta

2

html-pdf utilizza phantomjs sotto il cofano, che deve compilare alcuni file binari durante l'installazione. Immagino che il tuo problema sia che stai distribuendo i binari compilati localmente ma Lambda ha bisogno dei binari compilati su Amazon Linux.

È possibile risolvere questo problema creando il pacchetto di distribuzione su un'istanza EC2 che esegue Amazon Linux e quindi ad es. distribuirlo direttamente da lì come è spiegato in this tutorial.

Controllare anche this answer su un problema simile.

+0

Verificando questo, accetterò una volta che sono in chiaro, grazie per la chiarezza amico – wvm2008

+0

beh, alla fine che non ha funzionato ... Sono stato in grado di costruire il mio codice su ec2 e distribuire ok, ma Finisco con lo stesso errore ... cercando nei node_modules di html-pdf, sta usando phantomjs_prebuilt, penso che potrebbe avere qualcosa a che fare con questo? – wvm2008

+0

Il codice funziona su EC2? Potresti dover chiamare 'npm rebuild' quando usi phantomjs-prebuilt. – birnbaum

Problemi correlati