Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to load psycopg in an uploaded function #152

Open
butla opened this issue Dec 21, 2017 · 6 comments
Open

Failed to load psycopg in an uploaded function #152

butla opened this issue Dec 21, 2017 · 6 comments

Comments

@butla
Copy link

butla commented Dec 21, 2017

The function I've built and uploaded with lambda-uploader crashed with this error:
Unable to import module 'kinesis_worker': /var/task/psycopg2/_psycopg.so: undefined symbol: PyUnicodeUCS4_DecodeUTF8

My requirements.txt:

credstash==1.14.0
psycopg2==2.7.3.2

My lambda.json:

{
  "name": "kinesis-worker",
  "description": "Takes events off the Kinesis queue and puts them into the DB.",
  "region": "us-east-1",
  "runtime": "python3.6",
  "handler": "kinesis_worker.dump_records_to_db",
  "role": "arn:aws:iam::609235665469:role/test_worker_role",
  "ignore": [
    "asd"
  ],
  "subscription": {
    "kinesis": {
      "stream": "arn:aws:kinesis:us-east-1:609235665469:stream/test_stream",
      "batch_size": 500
    }
  }
}

The function works with AWS when I'm building with my own scripts (created them because of #151):

# build.sh
SCRIPT_LOCATION=$(realpath $(dirname $0))
echo Building a lambda package in $BUILD_DIR

VENV_DIR=${SCRIPT_LOCATION}/lambda_venv
if [ -d $VENV_DIR ]; then
    echo Removing old ${VENV_DIR}
    rm -rf $VENV_DIR
fi
python3.6 -m venv $VENV_DIR
${VENV_DIR}/bin/pip install -r ${SCRIPT_LOCATION}/requirements.txt

cp -r ${VENV_DIR}/lib/python3.6/site-packages ${SCRIPT_LOCATION}
BUILD_DIR=${SCRIPT_LOCATION}/lambda_build
if [ -d $BUILD_DIR ]; then
    echo Removing old ${BUILD_DIR}
    rm -rf $BUILD_DIR
fi
mv ${SCRIPT_LOCATION}/site-packages ${BUILD_DIR}

cp ${SCRIPT_LOCATION}/*.py ${BUILD_DIR}
find ${BUILD_DIR} -name __pycache__ | xargs rm -rf

LAMBDA_PACKAGE=lambda_package.zip
(
    cd $BUILD_DIR
    zip -r ${BUILD_DIR}/${LAMBDA_PACKAGE} .
    mv $LAMBDA_PACKAGE $SCRIPT_LOCATION
)

echo Built $LAMBDA_PACKAGE in $SCRIPT_LOCATION

# upload.sh
SCRIPT_LOCATION=$(realpath $(dirname $0))
LAMBDA_PACKAGE=${SCRIPT_LOCATION}/lambda_package.zip

aws lambda update-function-code \
    --function-name arn:aws:lambda:us-east-1:609235665469:function:kinesis_worker \
    --zip-file fileb://${LAMBDA_PACKAGE}

My OS is Kubuntu 17.10

@Julio-Assis
Copy link

I'm having the same issue here, did you find a fix for it?

@jarosser06
Copy link
Contributor

Looks like an issue with compiled shared libraries trying to run on a different target system. This doesn't appear to be an issue with the lambda-uploader as much as an issue with not building the virtualenv in an Amazon Linux based system.

There are a few workarounds, the easiest is to build the project in a local Amazon Linux container. If I have some time I'll try and write up a little example of how to go about this.

@butla
Copy link
Author

butla commented Mar 10, 2018

@Julio-Assis I've dropped my ideas to use lambda-uploader because of this problem and because it didn't seem to fit our workflow.

We are using our own script that builds the Lambda package as a layer in a docker image extending lambci/lambda:build-python3.6
We then copy that package, from a started container, upload it to S3, and then set it up with Terraform.

We may publish details in a blog post at one point :-)

@butla
Copy link
Author

butla commented Mar 10, 2018

@jarosser06 Oh, I didn't know that you need to use it from Amazon Linux. Guess it'd be good to put it in the readme.

@Julio-Assis
Copy link

One possible workaround that I have in mind is to change my database to mysql and then I would use pymysql rather than psycopg2. Do you think this will work?

@butla
Copy link
Author

butla commented Mar 19, 2018

@Julio-Assis I think that building on Amazon Linux, or in lambci/lambda:build-python3.6 container would be a better idea. I don't think you'll be able to escape using any C extensions for long. Also, I'm a Postgres fan :)

azatoth added a commit to azatoth/lambda-uploader that referenced this issue Apr 25, 2018
azatoth added a commit to azatoth/lambda-uploader that referenced this issue Apr 25, 2018
azatoth added a commit to azatoth/lambda-uploader that referenced this issue Apr 25, 2018
azatoth added a commit to azatoth/lambda-uploader that referenced this issue Apr 25, 2018
A issue has been that even if you specify python3.6 as runtime in lambda.json,
it will use python2 for the virtualenv and thus install possibly incompatible
libraries (psycopg2-binary for example)

This changes the behavour to use the defined "runtime" in lambda.json as
basis for the virtualenv.

Closes: rackerlabs#142
Relates: rackerlabs#152
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants