Problems with custom LIBFFI Heroku buildpack

2020-06-05 01:31发布

问题:

I'm trying to deploy my app to Heroku. It is using pyOpenSSL, which requires cryptography, which requires libffi. I found a custom buildpack that includes libffi here: https://github.com/mfenniak/heroku-buildpack-python-libffi. However, cryptography cannot seem to find libffi even though it's on LD_LIBRARY_PATH:

$ heroku run bash

heroku> echo $LD_LIBRARY_PATH
/app/.heroku/vendor/lib:/app/vendor/libffi-3.0/lib

heroku> ls /app/vendor/libffi-3.0/lib
libffi-3.0.13  libffi.a  libffi.la  libffi.so  libffi.so.6  libffi.so.6.0.1  pkgconfig

However, I'm not sure LD_LIBRARY_PATH is available during install process, but it is part of the compile step of the buildpack: https://github.com/mfenniak/heroku-buildpack-python-libffi/commit/6ce48d4fd6c55fc3dc462cf6300c17854732b6e2

In general, this buildpack works and I used it previously with bcrypt (https://pypi.python.org/pypi/bcrypt).

Here is the heroku deployment process which fails:

$ git push staging master
Fetching repository, done.
Counting objects: 20, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1.71 KiB | 0 bytes/s, done.
Total 11 (delta 9), reused 0 (delta 0)

-----> Fetching custom git buildpack... done
-----> Python app detected
-----> No runtime.txt provided; assuming python-2.7.4.
-----> Using Python runtime (python-2.7.4)
-----> Noticed cffi. Bootstrapping libffi.
PKG_CONFIG_PATH=:/app/vendor/libffi-3.0/lib/pkgconfig/
libffi.pc is in-place at /app/vendor/libffi-3.0/vendor/lib/pkgconfig/libffi.pc, libffi-based builds should work!
-----> Installing dependencies using Pip (1.3.1)
       Obtaining file:///app (from -r requirements.txt (line 1))
         Running setup.py egg_info for package from file:///app

       Downloading/unpacking pyOpenSSL==0.14 (from -r requirements.txt (line 76))
         Running setup.py egg_info for package pyOpenSSL

           no previously-included directories found matching 'doc/_build'
       Downloading/unpacking cryptography==0.2.2 (from -r requirements.txt (line 77))
         Running setup.py egg_info for package cryptography

           Traceback (most recent call last):
             File "<string>", line 16, in <module>
             File "/tmp/pip-build-u45370/cryptography/setup.py", line 113, in <module>
               "build": cffi_build,
             File "/app/.heroku/python/lib/python2.7/distutils/core.py", line 152, in setup
               dist.run_commands()
             File "/app/.heroku/python/lib/python2.7/distutils/dist.py", line 953, in run_commands
               self.run_command(cmd)
             File "/app/.heroku/python/lib/python2.7/distutils/dist.py", line 972, in run_command
               cmd_obj.run()
             File "<string>", line 14, in replacement_run
             File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 259, in find_sources
               mm.run()
             File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 325, in run
               self.add_defaults()
             File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 361, in add_defaults
               sdist.add_defaults(self)
             File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/sdist.py", line 199, in add_defaults
               build_py = self.get_finalized_command('build_py')
             File "/app/.heroku/python/lib/python2.7/distutils/cmd.py", line 312, in get_finalized_command
               cmd_obj.ensure_finalized()
             File "/app/.heroku/python/lib/python2.7/distutils/cmd.py", line 109, in ensure_finalized
               self.finalize_options()
             File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/build_py.py", line 73, in finalize_options
               _build_py.finalize_options(self)
             File "/app/.heroku/python/lib/python2.7/distutils/command/build_py.py", line 46, in finalize_options
               ('force', 'force'))
             File "/app/.heroku/python/lib/python2.7/distutils/cmd.py", line 298, in set_undefined_options
               src_cmd_obj.ensure_finalized()
             File "/app/.heroku/python/lib/python2.7/distutils/cmd.py", line 109, in ensure_finalized
               self.finalize_options()
             File "/tmp/pip-build-u45370/cryptography/setup.py", line 52, in finalize_options
               from cryptography.hazmat.primitives import constant_time, padding
             File "cryptography/hazmat/primitives/constant_time.py", line 21, in <module>
               _ffi = cffi.FFI()
             File "/app/.heroku/python/lib/python2.7/site-packages/cffi/api.py", line 56, in __init__
               import _cffi_backend as backend
           ImportError: libffi.so.6: cannot open shared object file: No such file or directory
           Complete output from command python setup.py egg_info:
           running egg_info

       creating pip-egg-info/cryptography.egg-info

       writing requirements to pip-egg-info/cryptography.egg-info/requires.txt

       writing pip-egg-info/cryptography.egg-info/PKG-INFO

       writing top-level names to pip-egg-info/cryptography.egg-info/top_level.txt

       writing dependency_links to pip-egg-info/cryptography.egg-info/dependency_links.txt

       writing manifest file 'pip-egg-info/cryptography.egg-info/SOURCES.txt'

       warning: manifest_maker: standard file '-c' not found



       Traceback (most recent call last):

         File "<string>", line 16, in <module>

         File "/tmp/pip-build-u45370/cryptography/setup.py", line 113, in <module>

           "build": cffi_build,

         File "/app/.heroku/python/lib/python2.7/distutils/core.py", line 152, in setup

           dist.run_commands()

         File "/app/.heroku/python/lib/python2.7/distutils/dist.py", line 953, in run_commands

           self.run_command(cmd)

         File "/app/.heroku/python/lib/python2.7/distutils/dist.py", line 972, in run_command

           cmd_obj.run()

         File "<string>", line 14, in replacement_run

         File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 259, in find_sources

           mm.run()

         File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 325, in run

           self.add_defaults()

         File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 361, in add_defaults

           sdist.add_defaults(self)

         File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/sdist.py", line 199, in add_defaults

           build_py = self.get_finalized_command('build_py')

         File "/app/.heroku/python/lib/python2.7/distutils/cmd.py", line 312, in get_finalized_command

           cmd_obj.ensure_finalized()

         File "/app/.heroku/python/lib/python2.7/distutils/cmd.py", line 109, in ensure_finalized

           self.finalize_options()

         File "/app/.heroku/python/lib/python2.7/site-packages/setuptools/command/build_py.py", line 73, in finalize_options

           _build_py.finalize_options(self)

         File "/app/.heroku/python/lib/python2.7/distutils/command/build_py.py", line 46, in finalize_options

           ('force', 'force'))

         File "/app/.heroku/python/lib/python2.7/distutils/cmd.py", line 298, in set_undefined_options

           src_cmd_obj.ensure_finalized()

         File "/app/.heroku/python/lib/python2.7/distutils/cmd.py", line 109, in ensure_finalized

           self.finalize_options()

         File "/tmp/pip-build-u45370/cryptography/setup.py", line 52, in finalize_options

           from cryptography.hazmat.primitives import constant_time, padding

         File "cryptography/hazmat/primitives/constant_time.py", line 21, in <module>

           _ffi = cffi.FFI()

         File "/app/.heroku/python/lib/python2.7/site-packages/cffi/api.py", line 56, in __init__

           import _cffi_backend as backend

       ImportError: libffi.so.6: cannot open shared object file: No such file or directory

       ----------------------------------------
       Command python setup.py egg_info failed with error code 1 in /tmp/pip-build-u45370/cryptography
       Storing complete log in /app/.pip/pip.log

 !     Push rejected, failed to compile Python app

To git@heroku.com:my-app-staging.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@heroku.com:my-app-staging.git'

Update

Strangely enough, if I ssh to a dyno heroku run bash and then pip install pyOpenSSL, then it succeeds. But this doesn't seem to help figuring out what's wrong with the deployment process.

回答1:

It appears github user kennethjiang had the same problem and forked the custom libffi buildpack with a fix just four days ago.

Here are the relevant changes:

https://github.com/kennethjiang/heroku-buildpack-python-libffi/compare/3bb5fab8213f41411f515f21a6c83ff36c8aa1f2...8ef02

$ heroku config:add BUILDPACK_URL=git://github.com/kennethjiang/heroku-buildpack-python-libffi.git
$ git push heroku master
Initializing repository, done.
Counting objects: 3, done.
Writing objects: 100% (3/3), 260 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)

-----> Fetching custom git buildpack... done
-----> Python app detected
-----> No runtime.txt provided; assuming python-2.7.4.
-----> Preparing Python runtime (python-2.7.4)
-----> Installing Distribute (0.6.36)
-----> Installing Pip (1.3.1)
-----> Noticed cffi. Bootstrapping libffi.
PKG_CONFIG_PATH=:/app/vendor/libffi-3.0/lib/pkgconfig/
libffi.pc is in-place at /app/vendor/libffi-3.0/vendor/lib/pkgconfig/libffi.pc, libffi-based builds should work!
-----> Installing dependencies using Pip (1.3.1)
       Downloading/unpacking pyOpenSSL==0.14 (from -r requirements.txt (line 1))
         Running setup.py egg_info for package pyOpenSSL

           no previously-included directories found matching 'doc/_build'
       Downloading/unpacking cryptography==0.2.2 (from -r requirements.txt (line 2))
         Running setup.py egg_info for package cryptography
           no previously-included directories found matching 'documentation/_build'
           zip_safe flag not set; analyzing archive contents...
           six: module references __file__
           six: module references __path__

           Installed /tmp/pip-build-u24412/cryptography/six-1.6.1-py2.7.egg
           Searching for cffi>=0.8
           Reading http://pypi.python.org/simple/cffi/
           Best match: cffi 0.8.2
           Downloading https://pypi.python.org/packages/source/c/cffi/cffi-0.8.2.tar.gz#md5=37fc88c62f40d04e8a18192433f951ec
           Processing cffi-0.8.2.tar.gz
           Writing /tmp/easy_install-vYzEMy/cffi-0.8.2/setup.cfg
           Running cffi-0.8.2/setup.py -q bdist_egg --dist-dir /tmp/easy_install-vYzEMy/cffi-0.8.2/egg-dist-tmp-KU0RrQ
           cc -c c/check__thread.c -o c/check__thread.o

           Installed /tmp/pip-build-u24412/cryptography/cffi-0.8.2-py2.7-linux-x86_64.egg
...

       Successfully installed pyOpenSSL cryptography six cffi pycparser
       Cleaning up...

-----> Discovering process types
       Procfile declares types -> (none)

-----> Compressing... done, 27.9MB
-----> Launching... done, v5
       http://quiet-atoll-6802.herokuapp.com/ deployed to Heroku

To git@heroku.com:quiet-atoll-6802.git
 * [new branch]      master -> master