shelfio / libreoffice-lambda-layer

MIT License
108 stars 21 forks source link

libreoffice exits - error code 81 #20

Open andrewdoyle19 opened 4 years ago

andrewdoyle19 commented 4 years ago

@shelfio/aws-lambda-libreoffice Version: 3.0.1

Problem: When executing a convert to pdf command, libreoffice will exit with an unexpected error, and exit code 81. It appears to be happening on first startup, sometimes subsequent commands are successful.

Command being run:

await unpack({ inputPath: "/opt/lo.tar.br" })

execSync(`/tmp/instdir/program/soffice.bin --headless --invisible --nodefault --view --nolockcheck --nologo --norestore --nofirststartwizard --convert-to pdf "/tmp/file.txt" --outdir /tmp`)

After looking into this error code, it looks like it could be an issue with using ../soffice.bin as the executable rather than just ../soffice

See this bug report where the same error was reported: https://bugs.documentfoundation.org/show_bug.cgi?id=107912

I was using the previous version of this where i had to use getExecutablePath which would return /tmp/instdir/program/soffice, where as unpack returns /tmp/instdir/program/soffice.bin as libreoffice is now being extracted with the .bin file extension, as documented in the readme diff

Was adding the .bin on intentional and required for this version?

tadasauciunas commented 4 years ago

Did you change the lambda layer version you're using after upgrading the npm package to 3.0.0?

andrewdoyle19 commented 4 years ago

Yes I am using arn:aws:lambda:ap-southeast-2:764866452798:layer:libreoffice-brotli:1

andrewdoyle19 commented 4 years ago

I was able to workaround this issue by essentially pre warming the lambda function with a dummy conversion prior to doing the real pdf conversions. Our application converts lots of files, and runs up to 5 concurrent instances of the conversion function.

The work around creates a dummy text file, and attempts to do a pdf conversion, which fails with exit code 81. It will then attempt to process the real data file and work successfully. The dummy text file will remain on the disk when the AWS lambda container is reused.

The code is essentially:

await unpack({ inputPath: "/opt/lo.tar.br" })

if (!fs.existsSync("/tmp/initfile.txt")) { //no warm container
  await execSync(`echo "Hello World Warming Up" > /tmp/initfile.txt`)
  execSync(`/tmp/instdir/program/soffice.bin --headless --invisible --nodefault --view --nolockcheck --nologo --norestore --nofirststartwizard --convert-to pdf "/tmp/initfile.txt" --outdir /tmp/`) //fails code 81  
}

execSync(`/tmp/instdir/program/soffice.bin --headless --invisible --nodefault --view --nolockcheck --nologo --norestore --nofirststartwizard --convert-to pdf "/tmp/real-file.txt" --outdir /tmp/`) //success
vladholubiev commented 4 years ago

Hey @lurch83

This is a known issue, we end up with the same workaround as well: https://github.com/shelfio/aws-lambda-libreoffice/blob/master/src/convert.ts#L33

Adding .bin was necessary since /program/soffice just doesn't exist. I believe this was some internal change in LibreOffice

andrewdoyle19 commented 4 years ago

Thanks for that. I didn't notice that you were doing it as well as I am not using the convertTo function.

jayeshkulkarni commented 4 years ago

Problem: When executing a convert to pdf command, libreoffice will exit with an unexpected error, and exit code 81. Even after using workaround mentioned by @lurch83 it is still failing with below error for subsequent command : Fontconfig error: Cannot load default config file Error: source file could not be loaded 2020-02-04T15:49:57.395Z 4784afa6-945e-422e-b77b-6c4c082c4292 ERROR Invoke Error
{ "errorType": "Error", "errorMessage": "ENOENT: no such file or directory, open '/tmp/CopySampleDOCFile_1000kb.pdf'", "code": "ENOENT", "errno": -2, "syscall": "open", "path": "/tmp/CopySampleDOCFile_1000kb.pdf", "stack": [ "Error: ENOENT: no such file or directory, open '/tmp/CopySampleDOCFile_1000kb.pdf'", " at Object.openSync (fs.js:440:3)", " at readFileSync (fs.js:342:35)", " at Runtime.module.exports.libre [as handler] (/var/task/handler.js:61:28)" ] }

Code snippet as below :

 await unpack({ inputPath: "/opt/lo.tar.br" }); // default path /tmp/instdir/program/soffice.bin
  if (!fs.existsSync("/tmp/initfile.txt")) { //no warm container
    await execSync(`echo "Hello World Warming Up" > /tmp/initfile.txt`)
    execSync(`/tmp/instdir/program/soffice.bin --headless --invisible --nodefault --view --nolockcheck --nologo --norestore --nofirststartwizard --convert-to pdf "/tmp/initfile.txt" --outdir /tmp/`) //fails code 81  
  }
  execSync(
    `/tmp/instdir/program/soffice.bin ${defaultArgs.join(
      ' '
    )} --convert-to pdf ${filename} --outdir /tmp`
  );

  const outputFilename = `${parse(filename).name}.pdf`;
  const outputFileBuffer = readFileSync(`/tmp/${outputFilename}`);

  await s3
  .upload({
    Bucket: process.env.DESTINATION_BUCKET, Key: outputFilename, Body: outputFileBuffer,
    ACL: 'public-read', ContentType: 'application/pdf'
  })
  .promise();

Any idea ?? @vladgolubev @KnupMan

pavankumar2203 commented 3 years ago

@jayeshkulkarni - I am facing the same issue. were you able to solve this ? Appreciate your help.

mark-hayward commented 3 years ago

I have the same problem. Did anybody solve this?

ladadeedee commented 3 years ago

Node environments don't contain fonts nor a FontConfig anymore. It used to come with a lot more stuff, but now you have to include a lot just to get anything to run. You'll need to put some fonts and a FontConfig in an archive somewhere online (like S3) and then download + extract it in your Lambda. There is more discussion at #23.