В AWS Lambda Docker Container двоичный файл LibreOffice soffice выполняется из BASH, но не выполняется из Python (подпроцесс)

Следуя этому руководству, я образ Docker (Alpine), работающий на AWS Lambda.

Изображение содержит app.py, который представляет собой простой конвертер документов .docx - ›.pdf. В основе лежит следующий код, который работает в контейнере Docker на моем локальном компьютере разработчика, но вызывает subprocess.CalledProcessError при фактическом развертывании Lambda:

def handler(event, context):
    src_filename = event['filename']

    filename_body, _ = os.path.splitext(src_filename)

    src_filepath = '/tmp/test-template.docx'
    shutil.copyfile('/home/app/test-template.docx', src_filepath)  # for testing
    print( subprocess.check_output(['ls', '-l', '/tmp'] ) )
    # ^ -rw-rw-r--  20974 bytes  test-template.docx

    LIBRE_BINARY = '/usr/bin/soffice'
    print( subprocess.check_output(['ls', '-l', LIBRE_BINARY] ) )
    # ^ lrwxrwxrwx  /usr/bin/soffice -> /usr/lib/libreoffice/program/soffice

    MAX_TRIES = 3
    success = False

    print(f'Processing file: {src_filepath} with LibreOffice')
    for kTry in range(MAX_TRIES):
        print(f'Conversion Attempt #{kTry}')
        try:
            # https://stackoverflow.com/questions/4256107/running-bash-commands-in-python
            result = subprocess.run(
                [
                    LIBRE_BINARY,
                        '--headless',
                        '--invisible',
                        '--nodefault',
                        '--nofirststartwizard',
                        '--nolockcheck',
                        '--nologo',
                        '--norestore',
                        '--convert-to', 'pdf:writer_pdf_Export',
                        '--outdir', TMP_FOLDER,
                        src_filepath
                ],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                shell=False,
                check=True,
                text=True
            )

        except subprocess.CalledProcessError as e:
            raise RuntimeError(f"\tGot exit code {e.returncode}. Msg: {e.output}") from e
            continue

Строка ответа:

[ERROR] RuntimeError:   Got exit code 77. Msg: 
Traceback (most recent call last):
  File "/home/app/app.py", line 82, in handler
    raise RuntimeError(f"\tGot exit code {e.returncode}. Msg: {e.output}") from e

Как это возможно, что это удалось на моем локальном компьютере, но не удалось на AWS?

Выполняется тот же образ контейнера. Он полностью автономен. Проблема определенно исходит из этой subprocess.run команды.

Вот мой aws lambda create-function:

    aws lambda create-function  \
        --function-name $AWS_LAMBDAFUNC_NAME \
        --role $role_arn \
        --code ImageUri=$full_url \
        --package-type Image \
        --memory-size 8192 \
        --timeout 300 \
        --publish

Я использовал большой объем памяти и большой таймаут.

Я читал, что запись в файловую систему вне моей папки / home / app и вне / tmp может быть проблематичной. Поэтому я стараюсь не использовать такие записи.

Так в чем может быть проблема?

Работает от BASH

Если я выполню эту обработку в моем entry.sh, это сработает:

#!/bin/sh

/usr/bin/soffice \
    --headless \
    --invisible \
    --nodefault \
    --nofirststartwizard \
    --nolockcheck \
    --nologo \
    --norestore \
    --convert-to pdf:writer_pdf_Export \
    --outdir /tmp \
    /home/app/test-template.docx \
        &> /home/app/output_and_error_file

ls /tmp >> /home/app/output_and_error_file

exec python -m awslambdaric $1

output_and_error_file:

{"response": "convert /home/app/test-template.docx -> /tmp/test-template.pdf using filter : writer_pdf_Export
hsperfdata_root
test-template.pdf"}

Так что, должно быть, что-то в subprocess противоречит среде выполнения Lambda.

Тест: Использование os.system

os.system( 
    f'export HOME=/home/app && {LIBRE_BINARY}' \
    f'   --headless --invisible --nodefault --nofirststartwizard' \
    f'   --nolockcheck --nologo --norestore' \
    f'   --convert-to pdf:writer_pdf_Export' \
    f'   --outdir {TMP_FOLDER}' \
    f'   {src_filepath}' 
    )

Это приводит к более описательной ошибке:

START RequestId: f2c18863-977e-46e4-a138-c1db80759406 Version: $LATEST
Executing 'app.handler' in function directory '/home/app'
b'total 24\n-rw-rw-r--    1 sbx_user 990          20974 Jan  8 11:01 test-template.docx\n'
/usr/bin/soffice
b'lrwxrwxrwx    1 root     root            36 Jan  8 03:56 /usr/bin/soffice -> /usr/lib/libreoffice/program/soffice\n'
Processing file: /tmp/test-template.docx with LibreOffice
Conversion Attempt #0
javaldx failed!
Warning: failed to read path from javaldx
LibreOffice 6.4 - Fatal Error: The application cannot be started. 
User installation could not be completed. 
Unknown error with saving to S3: <class 'FileNotFoundError'>
END RequestId: f2c18863-977e-46e4-a138-c1db80759406
REPORT RequestId: f2c18863-977e-46e4-a138-c1db80759406  Duration: 2698.32 ms    Billed Duration: 5585 ms    Memory Size: 8192 MB    Max Memory Used: 175 MB Init Duration: 2885.69 ms   

soffice --version работает

            result = subprocess.run( 
                [ LIBRE_BINARY, '--version' ],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                shell=False,
                check=True,
                text=True
            )

Это прекрасно работает!


person P i    schedule 07.01.2021    source источник
comment
Это может быть проблема, связанная с env.   -  person Ravindra    schedule 08.01.2021
comment
У меня была та же проблема, но с помощью этих решений я решил введите описание ссылки здесь   -  person Gian Carlos Figueroa Revelo    schedule 04.06.2021