Следуя этому руководству, я образ 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
)
Это прекрасно работает!