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

pip creates bad virtualenv #19838

Closed
ns-phennessy opened this Issue Jan 3, 2017 · 7 comments

Comments

Projects
None yet
4 participants
@ns-phennessy

ns-phennessy commented Jan 3, 2017

ISSUE TYPE
  • Bug Report
COMPONENT NAME

virtualenv
pip

ANSIBLE VERSION
ansible 2.0.2.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
CONFIGURATION
[defaults]
error_on_undefined_vars=True
gathering = 'explicit'
callback_whitelist = profile_tasks
OS / ENVIRONMENT

CentOS Linux release 7.2.1511 (Core)

SUMMARY

Installing a flask app that runs behind a uwsgi emperor. This app uses Python 2.7.11 which is the system python and the same python running in the virtualenv

Seeing the following stack trace when running the app:

Traceback (most recent call last):
  File "app/server.py", line 3, in <module>
    import boto
  File "app/venv/lib/python2.7/site-packages/boto/__init__.py", line 35, in <module>
    import logging.config
  File "/usr/lib64/python2.7/logging/config.py", line 27, in <module>
    import sys, logging, logging.handlers, socket, struct, os, traceback, re
  File "/usr/lib64/python2.7/logging/handlers.py", line 26, in <module>
    import errno, logging, socket, os, cPickle, struct, time, re
ImportError: app/venv/lib/python2.7/lib-dynload/cPickle.so: undefined symbol: PyUnicodeUCS4_DecodeUTF8
unable to load app 0 (mountpoint='') (callable not found or import error)

Based on my Google-fu, the consensus is that the virtualenv was built using an outdated python?

Manually installing the virtualenv (via standard steps), works just fine and fixes the issue:

virtualenv app/venv
app/venv/bin/activate
pip install -r app/requirements.txt
deactivate

systemctl start uwsgi

As far as I can tell there is no difference between the manually installed virtualenv and the one using the pip module.

STEPS TO REPRODUCE
    - name: Install virtualenv
      pip:
        name: virtualenv
        state: latest

    - name: Install venv packages
      pip:
        requirements: app/requirements.txt
        virtualenv: app/venv

app/requirements.txt:

Flask==0.10.1
itsdangerous==0.23
simplejson==3.6.3
requests==2.0.1
pymongo==2.4
boto==2.9.7

Edit: Tried running this via the shell module, this seems to fail in the same way:

    - name: Install VirtualEnv Packages
      shell: |
        virtualenv app/venv
        source app/venv/bin/activate
        pip install -r app/requirements.txt
        deactivate
@Lujeni

This comment has been minimized.

Show comment
Hide comment
@Lujeni

Lujeni Jan 4, 2017

Contributor

Hello @ns-phennessy

I am not able to reproduce your bug:

- name: test venv
  hosts: all
  become: true
  tasks:
    - name: Install VirtualEnv Packages
      shell: |
        virtualenv app/venv
        source app/venv/bin/activate
        pip install -r requirements.txt
        deactivate
 ~/works/repos/perso/ansible/issue_19838 
13:54 $ ansible-playbook -i localhost, test.yml -c 'local' 

PLAY [test venv] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [Install VirtualEnv Packages] *********************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

✔ ~/works/repos/perso/ansible/issue_19838 
13:54 $ source app/venv/bin/activate
(venv) ✔ ~/works/repos/perso/ansible/issue_19838 
13:54 $ python
Python 2.7.10 (default, May 31 2016, 23:05:11) 
[GCC 4.9.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask
>>>

Did you launch the ansible setup and your manually test with the same user ?

Contributor

Lujeni commented Jan 4, 2017

Hello @ns-phennessy

I am not able to reproduce your bug:

- name: test venv
  hosts: all
  become: true
  tasks:
    - name: Install VirtualEnv Packages
      shell: |
        virtualenv app/venv
        source app/venv/bin/activate
        pip install -r requirements.txt
        deactivate
 ~/works/repos/perso/ansible/issue_19838 
13:54 $ ansible-playbook -i localhost, test.yml -c 'local' 

PLAY [test venv] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [Install VirtualEnv Packages] *********************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

✔ ~/works/repos/perso/ansible/issue_19838 
13:54 $ source app/venv/bin/activate
(venv) ✔ ~/works/repos/perso/ansible/issue_19838 
13:54 $ python
Python 2.7.10 (default, May 31 2016, 23:05:11) 
[GCC 4.9.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask
>>>

Did you launch the ansible setup and your manually test with the same user ?

@ns-phennessy

This comment has been minimized.

Show comment
Hide comment
@ns-phennessy

ns-phennessy Jan 4, 2017

Yes, both were created and run using the centos user which is the system default.

This only happens when running behind a uwsgi emperor.
https://uwsgi-docs.readthedocs.io/en/latest/

If this is helpful, here is the vassal definition:

[uwsgi]
buffer-size = 32768
chdir = app/
chmod-socket = 660
enable-threads = true
uid = root
gid = root
umask = 002
http-socket = 80
logto = /var/log/vassal.log
master = 1
; Cycle tasks after 50 requests.
max-requests = 50
module = app.server:app
need-app = 1
post-buffering = 8192
processes = 12
pythonpath = app/
show-config = 1
virtualenv = app/venv

ns-phennessy commented Jan 4, 2017

Yes, both were created and run using the centos user which is the system default.

This only happens when running behind a uwsgi emperor.
https://uwsgi-docs.readthedocs.io/en/latest/

If this is helpful, here is the vassal definition:

[uwsgi]
buffer-size = 32768
chdir = app/
chmod-socket = 660
enable-threads = true
uid = root
gid = root
umask = 002
http-socket = 80
logto = /var/log/vassal.log
master = 1
; Cycle tasks after 50 requests.
max-requests = 50
module = app.server:app
need-app = 1
post-buffering = 8192
processes = 12
pythonpath = app/
show-config = 1
virtualenv = app/venv
@Lujeni

This comment has been minimized.

Show comment
Hide comment
@Lujeni

Lujeni Jan 4, 2017

Contributor

The application running with the flask runserver through the venv ?

Contributor

Lujeni commented Jan 4, 2017

The application running with the flask runserver through the venv ?

@ns-phennessy

This comment has been minimized.

Show comment
Hide comment
@ns-phennessy

ns-phennessy Jan 4, 2017

Yes. We install the deps for the Flask app into a venv, which the uwsgi web server will use to run the app.

ns-phennessy commented Jan 4, 2017

Yes. We install the deps for the Flask app into a venv, which the uwsgi web server will use to run the app.

@Lujeni

This comment has been minimized.

Show comment
Hide comment
@Lujeni

Lujeni Jan 4, 2017

Contributor

I use the emperor mode also, i am not sure to see the link between them.

If you can run your flask application, the venv is good i guess.

Which version of pip / virtualenv pls?

Contributor

Lujeni commented Jan 4, 2017

I use the emperor mode also, i am not sure to see the link between them.

If you can run your flask application, the venv is good i guess.

Which version of pip / virtualenv pls?

@ns-phennessy

This comment has been minimized.

Show comment
Hide comment
@ns-phennessy

ns-phennessy Jan 5, 2017

Ah, i have tracked it down.

Turns out, we are building our machine from an image that has a Python 2.7.5 on it; in the midst of running Ansible stuff on it, we are doing a full system update which brings Python to 2.7.11. We compile uwsgi against 2.7.11 while the virtualenv is created using 2.7.5.

I don't much like the idea of hardcoding a version number into Ansible, wondering if there is a way we can have it favor the system's Python?

ns-phennessy commented Jan 5, 2017

Ah, i have tracked it down.

Turns out, we are building our machine from an image that has a Python 2.7.5 on it; in the midst of running Ansible stuff on it, we are doing a full system update which brings Python to 2.7.11. We compile uwsgi against 2.7.11 while the virtualenv is created using 2.7.5.

I don't much like the idea of hardcoding a version number into Ansible, wondering if there is a way we can have it favor the system's Python?

@ns-phennessy

This comment has been minimized.

Show comment
Hide comment
@ns-phennessy

ns-phennessy Jan 5, 2017

Going to close this ticket since this is not an Ansible bug.

it looks like virtualenv_python property can take a version number OR file path. That is a little unclear in the docs fwiw.

This has resolved the issue for us. Thanks for your help @Lujeni

ns-phennessy commented Jan 5, 2017

Going to close this ticket since this is not an Ansible bug.

it looks like virtualenv_python property can take a version number OR file path. That is a little unclear in the docs fwiw.

This has resolved the issue for us. Thanks for your help @Lujeni

@bcoca bcoca removed the needs_triage label Jan 18, 2017

@ansibot ansibot added bug and removed bug_report labels Mar 7, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment