Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import Error from cyptography.hazmat.bindings._constant_time import lib

So I'm trying to create an aws lambda function, to log in to an instance and do some stuff. And the script works fine outside of lambda, but when I package it using the same instructions as this https://aws.amazon.com/blogs/compute/scheduling-ssh-jobs-using-aws-lambda/ it doesn't work. It throws this error.

libffi-72499c49.so.6.0.4: cannot open shared object file: No such file or directory: ImportError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 12, in lambda_handler
    key = paramiko.RSAKey.from_private_key(key)
  File "/var/task/paramiko/pkey.py", line 217, in from_private_key
    key = cls(file_obj=file_obj, password=password)
  File "/var/task/paramiko/rsakey.py", line 42, in __init__
    self._from_private_key(file_obj, password)
  File "/var/task/paramiko/rsakey.py", line 168, in _from_private_key
    self._decode_key(data)
  File "/var/task/paramiko/rsakey.py", line 173, in _decode_key
    data, password=None, backend=default_backend()
  File "/var/task/cryptography/hazmat/backends/__init__.py", line 35, in default_backend
    _default_backend = MultiBackend(_available_backends())
  File "/var/task/cryptography/hazmat/backends/__init__.py", line 22, in _available_backends
    "cryptography.backends"
  File "/var/task/pkg_resources/__init__.py", line 2236, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/var/task/cryptography/hazmat/backends/openssl/__init__.py", line 7, in <module>
    from cryptography.hazmat.backends.openssl.backend import backend
  File "/var/task/cryptography/hazmat/backends/openssl/backend.py", line 15, in <module>
    from cryptography import utils, x509
  File "/var/task/cryptography/x509/__init__.py", line 7, in <module>
    from cryptography.x509.base import (
  File "/var/task/cryptography/x509/base.py", line 15, in <module>
    from cryptography.x509.extensions import Extension, ExtensionType
  File "/var/task/cryptography/x509/extensions.py", line 19, in <module>
    from cryptography.hazmat.primitives import constant_time, serialization
  File "/var/task/cryptography/hazmat/primitives/constant_time.py", line 9, in <module>
    from cryptography.hazmat.bindings._constant_time import lib
ImportError: libffi-72499c49.so.6.0.4: cannot open shared object file: No such file or directory
like image 239
Luis F Hernandez Avatar asked Aug 15 '16 22:08

Luis F Hernandez


2 Answers

The zip commands in that tutorial are missing a parameter. I ran into this exact problem today with pysftp, which is built on paramiko. libffi-72499c49.so.6.0.4 is in a hidden dot directory inside lib64/python2.7/site-packages/.libs_cffi_backend. Depending on how you zipped up the dependencies in your virtualenv, you may have inadvertantly excluded this directory.

  1. First, make sure libffi-devel and openssl-devel are installed on your Amazon Linux instance, otherwise the cryptography module may not be compiling correctly.

    sudo yum install libffi-devel openssl-devel
    

If those packages were not installed before, delete and rebuild your virtualenv.

  1. Make sure that when you are zipping up your site-packages that you use '.' instead of '*', otherwise you will not be including files and directories that are hidden because their names begin with a period.

    cd path/to/my/helloworld-env/lib/python2.7/site-packages
    zip -r9 path/to/zip/worker_function.zip .
    cd path/to/my/helloworld-env/lib64/python2.7/site-packages
    zip -r9 path/to/zip/worker_function.zip .
    
like image 165
Gabriel Totusek Avatar answered Nov 06 '22 06:11

Gabriel Totusek


My 2 cents: if you want to build&test your lambda function in the environment as similar to actual lambda as possible but still under your control, I would suggest using LambCI's Docker images. They are based on dumps of original lambda filesystem. Also they have build-specific variants (tags build-python2.7 and build-python3.6 are most interesting for us). These images are not very small - more than 500mb - but they allow you to avoid any headache when building.

Important benefit over Amazon Linux is that all package versions etc are the same as on the real lambda.

Here is how I did building myself:

cd PROJECT_DIR
docker run --rm -it -v "$PWD":/var/task lambci/lambda:build-python2.7 bash
### now in docker
mkdir deps
pip install -t deps -r requirements.txt
# now all dependencies for our package are installed to deps/ directory,
# without any garbage like wheel or setuptools - unlike when using virtualenv
zip -r archive.zip MYCODE.py MYMODULE MYMODULE2.py
cd deps
# it's important to use . here, not * - or else some dot-starting directories will be omitted
zip -r ../archive.zip .
exit
### now locally
# just upload archive to lambda, with or without s3

For automating it with GitLab CI, just instruct it to use that same docker image and put these commands in deploy script section:

deploy:
    stage: deploy
    image: lambci/lambda:build-python2.7
    script:
        - mkdir deps
        - pip install -t deps -r requirements.txt
        - zip -r archive.zip MYCODE.py MYMODULE MYMODULE2.py
        - cd deps && zip -r ../archive.zip . && cd ..
        - aws s3 cp archive.zip ${bucket}/${key}
        - aws lambda update-function-code --function-name ${func} --s3-bucket ${bucket} --s3-key ${key}
    variables:
        bucket: ...
        key: ...
        func: ...
like image 7
MarSoft Avatar answered Nov 06 '22 07:11

MarSoft