背景
PythonでAWS Lambdaの開発をする際、Serverless Frameworkとserverless-python-requirementsプラグインを使うことがあると思います。
その際に、表題のエラーで少し詰まったので解決のために役に立ったことをまとめます。
動作環境
本記事は以下の環境で確認しています。
- OS : Mac OS Mojave
- Serverless Framework : 1.54.0
- serverless-python-requirements : 5.0.1
エラーが出るまで
本記事では、以下のような構成を考えます。
opencv-python
import cv2
def hello(event, context):
response = {
"statusCode": 200,
"body": cv2.__version__
}
return response
service: test
provider:
name: aws
runtime: python3.7
functions:
hello:
handler: handler.hello
custom:
pythonRequirements:
dockerizePip: true
slim: true
plugins:
- serverless-python-requirements
これは、単にOpenCVのバージョンを返す関数です。
これをデプロイして、sls invoke -f hello
で実行すると以下のようなエラーが出ると思います。
{
"errorMessage": "Unable to import module 'handler': /var/task/cv2/cv2.cpython-37m-x86_64-linux-gnu.so: ELF load command address/offset not properly aligned",
"errorType": "Runtime.ImportModuleError"
}
本記事では、このような場面で試すことをまとめていきます。
プラグインの設定を見直す
このELF load command address/offset not properly aligned
というエラーについてはプラグインのREADME.mdに記載があり、
custom:
pythonRequirements:
slim: true
strip: false
と書けば良いようです。ということで、serverless.ymlを書き換えて再度実行してみます。
ここでエラーが出ない場合は問題ないと思います。本記事では、ここでエラーが出た際の知見を紹介します。
キャッシュを確認する
serverless-python-requirementsは毎回pipをしなくても良いように、キャッシュの機能を持っています。
https://github.com/UnitedIncome/serverless-python-requirements/blob/master/README.md#caching
先ほどのstrip: false
の変更ではキャッシュを利用してしまうらしく、デプロイされるパッケージには変更が反映されません。
例えば、sls remove
などしてもキャッシュは削除されないので、ELF load command address/offset not properly aligned
が出続けてしまいます。
したがって、
$ rm -rf /Users/xxx/Library/Caches/serverless-python-requirements
のようにキャッシュを削除してからデプロイし直すと解決する可能性があります。
(当然、パスは環境によって変わると思います。)
まとめ
ELF load command address/offset not properly alignedが発生したら
- プラグインの設定を確認する
- キャッシュを確認する
と良いかと思います。
他にも知見がある方はぜひ教えて下さい。